我的同事在我们的代码中加入了这样的内容:
const information = require('../relative/path/' + tag + '.json');
有趣的是它有效,但我真的不知道如何。
我创建了这个最小的项目:
$ head *.json main.js
==> 1.json <==
["message #1"]
==> 2.json <==
["message two"]
==> 3.json <==
["message III"]
==> package.json <==
{
"dependencies": {
"webpack": "^5.38.1"
"webpack-cli": "^4.7.2"
}
}
==> package-lock.json <==
...
==> main.js <==
const arg = process.argv[2] ? process.argv[2] : 1;
console.log(require(`./${arg}.json`)[0]);
当我运行原始程序时,我得到:
$ node main.js 1
message #1
$ node main.js 2
message two
$ node main.js 3
message III
所以现在我用 webpack 编译
$ node_modules/.bin/webpack ./main.js
它会创建一个 dist
目录,里面有一个文件,这个新的捆绑程序也能运行:
$ node dist/main.js 1
message #1
$ node dist/main.js 2
message two
$ node dist/main.js 3
message III
当我查看捆绑包时,所有信息都被捆绑在一起:
当我从程序中删除 require 并只打印 arg 时,捆绑的程序是一行。
那它是怎么做到的?
有趣的是,在我的简单示例中,package.json
也出现在那里,但在真正给我想法的那个例子中,却没有。
有人知道这是如何工作的吗?
我的意思是对我来说简单实用的答案是,永远不要在 require 中放入变量......但我仍然很好奇。
PS 真正的一个是网络项目。示例中仅使用了节点和参数
答案 0 :(得分:0)
Webpack 总是将所有 require
的文件捆绑到最终输出文件中(默认情况下称为 bundle.js
)。您不能require
任何未捆绑的东西。
如果你需要一些不是常数的东西,正如你所指出的,它可能会导致一些麻烦。这就是 eslint
对此有 no-dynamic-require 规则的原因。但如果你知道自己在做什么,一切都会好起来的。
Webpack 使用一些启发式方法来支持 require
的非构建时间常量值(即表达式)。确切的行为记录在 webpack's documentation on dependency management 中。
如该链接中所述,您的 require('../relative/path/' + tag + '.json')
将引导 webpack 确定:
../relative/path
/^.*\.json$/
并且将捆绑所有符合该条件的文件。
当您的 require
调用被执行时,它将提供与其完全匹配的文件,或者如果该文件未捆绑则抛出错误。
重要提示:这当然意味着您不能在捆绑后添加文件。在打包之前,您必须将文件放在正确的位置,以便 webpack 可以找到、添加并最终解决它们。
还要注意,很多时候,你不需要编写自己的 webpack 实验。 Webpack 有 plenty of official samples。例如。 this official webpack sample 正好说明了您的情况。