gpt4 book ai didi

webpack - 使用 webpack 从动态源输出 UMD 模块

转载 作者:行者123 更新时间:2023-12-02 13:50:22 26 4
gpt4 key购买 nike

我有一个项目结构,其中包含一个文件夹,当我构建 webpack 配置时,我希望将其动态导入到 UMD 模块中,并使每个文件成为输出构建中的子模块。

例如,假设我的来源如下:

/src/snippets/red.js
/src/snippets/green.js
/src/snippets/blue.js

我希望 webpack 将这些源构建到一个模块中,这样我就可以将每个源作为子模块进行访问,如下所示;

const red = require('snippets').red

我尝试迭代 snippets 目录并创建一个带有文件名和路径的对象,但我无法弄清楚什么配置属性将指示 webpack 将它们捆绑到单个文件中并导出每个文件。这是我到目前为止所拥有的:

const glob = require('glob')

module.exports = {
entry: glob.sync('./src/snippets/*.js').reduce((files, file) => {
files[path.basename(file,'.js')] = file

return files
}, {}),
output: {
path: __dirname + '/lib',
filename: 'snippets.js',
libraryTarget: 'umd'
}
}

出现错误:冲突:多个资源发送到同一文件名 ./lib/snippets.js

知道如何实现我想要的目标吗?

最佳答案

在生产中使用此解决方案的修改版本已经有一段时间了,我没有遇到任何问题。 (我公司的设置有一个稍微复杂的过滤器,以排除某些模拟模块,但在其他方面是相同的)。

我们使用构建脚本来抓取相关目录(在我们的设置中,它是 src 但在您的设置中是 src/snippets。对于每个以 .在 Node.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 测试之前使用它)。

这个设置感觉相当老套,但效果很好。我遇到的唯一问题是,模块的顺序偶尔会发生变化(大概是由于环境差异),并且文件的枚举会导致 git 出现误报。

我已将整个包放在 GitHub 上:https://github.com/akatechis/webpack-lib-poc

<小时/>

更新:如果您不想通过将构建脚本添加到 package.json scripts 来手动调用构建脚本,您始终可以将其包装为 webpack 插件。您可以阅读详情here

简而言之,插件只是一个具有 apply 方法的对象,该方法将自身注册到 webpack 编译器中。来自文档:

As a clever JavaScript developer you may remember the Function.prototype.apply method. Because of this method you can pass any function as plugin (this will point to the compiler). You can use this style to inline custom plugins in your configuration.

以下是两种设置之间的变化:

更改 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 现在将始终在运行之前调用您的构建脚本。

关于webpack - 使用 webpack 从动态源输出 UMD 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48120264/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com