I've read the docs of import.meta.url
saying :
The full URL to the module, includes query parameters and/or hash (following the ? or #). In browsers, this is either the URL from which the script was obtained (for external scripts), or the URL of the containing document (for inline scripts). In Node.js, this is the file path (including the file:// protocol).
I created a simple React app with this code:
console.log(import.meta.url); //here
export function App() {
...
...
console.log(import.meta.url); //also here
...
Then I created assets (js, css, html) via npm run build (webpack etc.) and deployed them in an Nginx Docker container.
However, when I run the code, I get this:
Question:
Why do I see file://
instead of http://
? It's not in node mode, and it is a module (App.tsx) is a module .
file:///
when they are lazy fetched ?By default Webpack will replace the value of import.meta.url
with the module's file:
URL at build time. You haven't stated what version of Webpack you are using, but support for allowing dynamic import.meta.url
values was added in versions >= 5.68.0 via PR 15246 as a result of issue 14445.
To disable Webpack replacing import.meta.url
at build time with the module's associated file:
URL update your configuration:
module: {
parser: {
javascript: {
importMeta: false,
},
},
},
Here is the documentation for enabling or disabling evaluation of import.meta
at build time.
You can see an example of a build configuration that uses this and returns the value of import.meta.url
you want: https://github.com/morganney/import-meta. This is also hosted on GitHub pages at https://morganney.github.io/import-meta/
Why?
This is a design question, and as such you're better off asking the designers, however, I'll offer a possible reason.
Webpack supports different targets. One of those is node
and Node.js supports CommonJS and ES Modules. There is no equivalent of import.meta.url
in CommonJS which was supported before ES modules and that may be why it is rewritten during the build by default, because you may be targeting a CJS environment. Moreover, you may be targeting web
where some browsers do not support native ES modules.
Other bundlers like rollup and swc have had to go through a similar process of how to deal with import.meta.url
in various contexts. Thus, there are configuration options to tell Webpack how to handle import.meta.url
during a build. Having an explicit option for this, rather than trying to infer it all from your target
and/or browserslist
file was probably a more reliable way to proceed with easier to maintain code, but you should ask the maintainers for a more definitive reason "why" they chose this design.
What does webpack do that it still fetches chunks of js and still those chunks show file:/// when they are lazy fetched?
It is the Webpack source code on GitHub. Referenced from the issue I mentioned above. Within lib/dependencies/importMetaPlugin.js
: https://github.com/webpack/webpack/blob/main/lib/dependencies/ImportMetaPlugin.js#L99