我已经在生产环境中使用这个修改版解决方案一段时间了,没有遇到任何问题。(我们公司的设置有一个稍微复杂一些的过滤器,用于排除某些虚拟模块,但基本相同)。
我们使用构建脚本来爬取相关目录(在我们的设置中,它是src
,但在你的设置中是src/snippets
)。对于每个以.js结尾的文件,我们导入并重新导出到src/index.js
。如果你需要更强大的功能,比如多级目录遍历,你需要修改它以递归遍历目录结构。
完成后,我们将其输出到index.js,同时提醒该文件是自动生成的,以防止手动添加条目到文件中。
const fs = require("fs");
const { EOL } = require("os");
const path = require("path");
let modules = 0;
const buffer = [
"// auto-generated file", "",
];
const emitModule = file => {
const moduleName = file.replace(".js", "");
modules += 1;
buffer.push(`exports.${moduleName} = require("./snippets/${moduleName}");`);
};
const files = fs.readdirSync(__dirname + "/snippets");
files
.filter(fname => fname !== "index.js" && !fname.startsWith("."))
.forEach(f => {
const stats = fs.statSync(path.join(__dirname, "snippets", f));
if (stats.isFile()) {
emitModule(f);
}
});
fs.writeFileSync(path.join(__dirname, "index.js"), buffer.join(EOL)+EOL);
console.info(`Built 'src/index.js' with ${modules} modules`);
然后,在 webpack.config.js 文件中,我们将 libraryTarget 设置为 umd
,如下所示:
module.exports = {
entry: path.resolve(__dirname, "src/index.js"),
output: {
path: path.resolve(__dirname, "build/"),
filename: "mylib.js",
libraryTarget: "umd"
}
};
最后,在 package.json 中为方便起见,我们使用以下内容在构建之前自动运行构建脚本(你也可以在启动 webpack-dev-server 或运行 mocha 测试之前使用它)。
这个设置感觉有点 hacky,但它运行得相当好。我遇到的唯一问题是偶尔模块的顺序会改变(可能是因为环境差异),而文件的枚举会导致 git 出现误报。
我已经将整个包上传到 GitHub 上,链接为:https://github.com/akatechis/webpack-lib-poc
更新:
如果你不想手动将构建脚本添加到 package.json 的 scripts
中调用,你可以将其作为 webpack 插件进行包装。你可以在这里阅读详细信息:https://webpack.js.org/concepts/plugins/
简而言之,插件只是一个具有 apply
方法的对象,它向 webpack 编译器注册自己。从文档中可以看出:
作为聪明的 JavaScript 开发者,你可能记得 Function.prototype.apply
方法。由于这个方法,你可以将任何函数作为插件传递(this
将指向编译器)。你可以使用这种风格来内联自定义插件到你的配置中。
以下是两个设置之间的更改:
将 webpack 配置更改为导入构建脚本并将其添加到 plugins
数组中:
const path = require("path");
const buildPlugin = require("./src/index.build");
module.exports = {
entry: path.resolve(__dirname, "src/index.js"),
output: {
path: path.resolve(__dirname, "build/"),
filename: "mylib.js",
libraryTarget: "umd"
},
plugins: [buildPlugin]
};
接下来,将 index.build.js
改为导出一个函数,在编译器上注册一个回调(它作为 this
接收)。将之前的构建脚本内容放入一个名为 build()
的函数中,然后按如下方式导出插件函数:
module.exports = function () {
this.plugin('run', function(compiler, callback) {
console.log("Build script starting");
build();
callback();
});
};
从package.json
中的任何脚本中删除build-index
目标。Webpack现在将在运行之前始终调用您的构建脚本。