Webpack:如何为"webpack"创建一个带有一系列依赖项的加载器?

Vla*_*huk 3 javascript amd commonjs requirejs webpack

例如,我在我的项目中使用AMD定义,并使用"webpack"进行项目构建.有可能创建一些以数组格式依赖的加载器吗?

define(
    [
        'mySuperLoader![./path/dependency-1, ./path/dependency-2, ...]'
    ],
    function() {
        // ... some logic here
    }
)
Run Code Online (Sandbox Code Playgroud)

项目示例:gitHub

Joh*_*ald 5

如果要将load-plugin的行为移植到webpack,则需要执行以下操作:

1.创建自定义解析程序

这是因为mySuperLoader![./path/dependency-1, ./path/dependency-2, ...]没有指向单个文件.当webpack尝试加载文件时,它首先:

  • 解析文件路径
  • 加载文件内容
  • 匹配并解决所有装载机
  • 将文件内容传递给加载器链

由于[./path/dependency-1, ./path/dependency-2, ...]不是一个合适的文件路径,因此有一些工作要做.它甚至不是一个合适的JSON.

所以,我们的第一个目标是把它变成mySuperLoader!some/random/file?["./path/dependency-1", "./path/dependency-2", ...].这通常通过创建自定义解析器来完成:

// webpack.config.js
var customResolverPlugin = {
    apply: function (resolver) {
        resolver.plugin("resolve", function (context, request) {
            const matchLoadRequest = /^\[(.+)]$/.exec(request.path);

            if (matchLoadRequest) {
                request.query = '?' + JSON.stringify(
                    matchLoadRequest[1]
                    .split(", ")
                );
                request.path = __filename;
            }
        });
    }
};

module.exports = {
    ...
    plugins: [
        {
            apply: function (compiler) {
                compiler.resolvers.normal.apply(customResolverPlugin);
            }
        }
    ]
};
Run Code Online (Sandbox Code Playgroud)

注意request.path = __filename;?我们只需要给webpack一个现有文件,这样它就不会抛出错误.无论如何,我们将生成所有内容.可能不是最优雅的解决方案,但它的工作原理.

2.创建我们自己的load-loader(是的!)

// loadLoader.js
const path = require("path");

function loadLoader() {
    return JSON.parse(this.request.match(/\?(.+?)$/)[1])
        .map(module =>
            `exports['${path.basename(module, '.js')}'] = require('${module}');`
        )
        .join('\n');
}

module.exports = loadLoader;
Run Code Online (Sandbox Code Playgroud)

这个加载器解析我们用自定义解析器重写的请求查询,并创建一个看起来像这样的CommonJS模块

exports['dependency-1'] = require('path/to/dependency-1');
exports['dependency-2'] = require('path/to/dependency-2');
Run Code Online (Sandbox Code Playgroud)

3.别名我们自己的load装载机

// webpack.config.js

    ...
    resolveLoader: {
        alias: {
            load: require.resolve('./loadLoader.js')
        }
    },
Run Code Online (Sandbox Code Playgroud)

4.配置 root

由于/path/to/dependency-1是root-relative,我们需要将root添加到webpack配置中

// webpack.config.js
resolve: {
    root: '/absolute/path/to/root' // usually just __dirname
},
Run Code Online (Sandbox Code Playgroud)

这既不是一个漂亮的也不是一个理想的解决方案,但在你移植模块之前应该作为临时工作.