Webpack:如何为“webpack”创建一个加载器,它需要一系列依赖项

Webpack: How can I create a loader for "webpack" which takes an array of dependencies?

本文关键字:加载 一个 依赖 一系列 webpack 创建 Webpack      更新时间:2023-09-26

例如,我在项目中使用 AMD 定义,并使用 "webpack" 进行项目构建。是否可以创建一些加载器,它将采用数组格式的依赖项?

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

项目示例:gitHub

如果你想将load插件的行为移植到 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);
            }
        }
    ]
};

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

2. 创建我们自己的load加载器(是的!

// 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;

此加载器解析我们使用自定义解析器重新编写的请求查询,并创建一个如下所示的 CommonJS 模块

exports['dependency-1'] = require('path/to/dependency-1');
exports['dependency-2'] = require('path/to/dependency-2');

3. 别名我们自己的load加载器

// webpack.config.js
    ...
    resolveLoader: {
        alias: {
            load: require.resolve('./loadLoader.js')
        }
    },

4. 配置root

由于/path/to/dependency-1是相对于根的,我们需要将根添加到 webpack 配置中

// webpack.config.js
resolve: {
    root: '/absolute/path/to/root' // usually just __dirname
},

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

我认为您不应该为此使用加载器。你为什么不直接写:

require("./path/dependency-1");
require("./path/dependency-2");
require("./path/dependency-3");

它完成了同样的事情,更具表现力,不需要额外的代码/加载器/黑客/配置。

如果您仍然不满意,您可能会对 webpack 上下文感兴趣,它允许您要求与给定过滤器匹配的大量文件。所以,如果你写

require("./template/" + name + ".jade");

webpack 包含此表达式可以访问的所有模块,而无需访问父目录。基本上和写作一样

require("./table.jade");
require("./table-row.jade");
require("./directory/folder.jade")

您也可以像这样手动创建上下文

var myRequire = require.context(
    "./template",   // search inside this directory
    false,         // false excludes sub-directories
    /'.jade$/      // use this regex to filter files
);
var table = myRequire("./table.jade");