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
$ 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:
$ 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:
When I remove the require from the program, and just print the arg, the bundled program is a single line.
So how does it do it?
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.
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.
PS the real one is a web project. just used node and args for the example
Webpack always bundles all require
'd files into the final output file (by default called bundle.js
). You cannot require
anything that was not bundled.
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. 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
. The exact behavior is documented in webpack's documentation on dependency management .
As explained in that link, your require('../relative/path/' + tag + '.json')
will lead webpack to determine:
../relative/path
/^.*\.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.
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.
Also note that often times, you don't need to write your own webpack experiments. Webpack has plenty of official samples . Eg your case is illustrated exactly by this official webpack sample .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.