简体   繁体   English

webpack 需要动态路径

[英]webpack require with dynamic path

My colleague put something like this in our code:我的同事在我们的代码中放了这样的东西:

const information = require('../relative/path/' + tag + '.json');

The funny thing is that it works, and I don't really see how.有趣的是它有效,我真的不知道如何。

I have created this minimal project:我创建了这个最小的项目:

$ 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]);

when I run the original program, I get this:当我运行原始程序时,我得到了这个:

$ node main.js 1
message #1
$ node main.js 2
message two
$ node main.js 3
message III

so now I compile with webpack所以现在我用 webpack 编译

$ node_modules/.bin/webpack ./main.js

and it creates a dist directory with a single file it in, and that new bundled program works too:它创建了一个包含单个文件的dist目录,并且该新捆绑程序也可以工作:

$ node dist/main.js 1
message #1
$ node dist/main.js 2
message two
$ node dist/main.js 3
message III

and when I look inside the bundle, all the info is bundled:当我查看捆绑包内部时,所有信息都捆绑在一起:

带有 json 内容的捆绑代码

When I remove the require from the program, and just print the arg, the bundled program is a single line.当我从程序中删除 require 并打印 arg 时,捆绑的程序是一行。

So how does it do it?那么它是如何做到的呢?

  • somehow calculate every possible file?以某种方式计算每个可能的文件?
  • just include everything from the current directory down?只包括当前目录下的所有内容?

Funny thing is in my simple example, package.json ended up in there too, but in the real one that gave me the idea, it didn't.有趣的是,在我的简单示例中, package.json也出现在其中,但在真正给我这个想法的例子中,它没有。

Does anybody know how this works?有人知道这是如何工作的吗?

I mean the simple practical answer for me is, never put variables in require... but I am still curious.我的意思是对我来说简单实用的答案是,永远不要将变量放入require中......但我仍然很好奇。

PS the real one is a web project. PS真正的是一个web项目。 just used node and args for the example仅使用 node 和 args 作为示例

Webpack always bundles all require 'd files into the final output file (by default called bundle.js ). Webpack 总是将所有require的文件捆绑到最终的 output 文件中(默认情况下称为bundle.js )。 You cannot require anything that was not bundled.您不能require任何未捆绑的东西。

If you require something that is not a constant, as you pointed out, it might lead to some trouble.正如您所指出的,如果您需要一些不是常数的东西,则可能会导致一些麻烦。 That is why eslint has a no-dynamic-require rule for that.这就是为什么eslint有一个no-dynamic-require规则。 But if you know what you are doing, everything is just fine.但是,如果您知道自己在做什么,那么一切都很好。

Webpack uses some heuristics to support non-build-time-constant values (ie expressions) for require . Webpack 使用一些启发式方法来支持require的非构建时间常数值(即表达式)。 The exact behavior is documented in webpack's documentation on dependency management .确切的行为记录在webpack 的依赖管理文档中。

As explained in that link, your require('../relative/path/' + tag + '.json') will lead webpack to determine:如该链接中所述,您的require('../relative/path/' + tag + '.json')将导致 webpack 确定:

  • Directory: ../relative/path目录: ../relative/path /path
  • Regular expression: /^.*\.json$/正则表达式: /^.*\.json$/ .json$/

And will bundle all files matching that criterion.并将捆绑所有符合该标准的文件

When your require call is executed, it will provide that file that matches it exactly, or throw an error if that file was not bundled.当您的require调用被执行时,它将提供与它完全匹配的文件,或者如果该文件未捆绑,则抛出错误。

Important: This means, of course, that you cannot add files after bundling.重要提示:当然,这意味着您无法在捆绑后添加文件。 You must have files in the right place, before bundling, so they can be found, added and ultimately resolved by webpack.在捆绑之前,您必须将文件放在正确的位置,以便 webpack 可以找到、添加并最终解决它们。

Also note that often times, you don't need to write your own webpack experiments.另请注意,通常情况下,您不需要编写自己的 webpack 实验。 Webpack has plenty of official samples . Webpack有大量官方样品 Eg your case is illustrated exactly by this official webpack sample .例如, 此官方 webpack 示例准确说明了您的案例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM