You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[commonjs] Output contains references to __filename #523
❌ Hardcode references to __filename and __dirname (couldn't they be written to a relative version of the output file, i.e. ./output/bundle.mjs here? since everything will be bundled into that spot by definition?)
✔️ Include ES2015 syntax to export top-level exports in output bundle (this works)
❌ Not include CJS syntax like module.exports (as seen on repl.it)
Actual Behavior
In my real-life code, I get an error because the ESM output references __filename:
file:///home/christian/Projects/gdev/dev/cli.mjs:14587
debug$1('initializing', __filename);
^
ReferenceError: __filename is not defined
And on repl.it, in addition to ESM output containing _filename, the output also includes a module.exports declaration at the top, which throws an error immediately:
output/bundle.mjs
module.exports={test: __filename};vartest=/*#__PURE__*/Object.freeze({__proto__: null});/** * Import a CJS module, log it, export it. */console.log(test);varindex={
test
};/** * `node index.mjs` or `node .` prints (as expected): * * [Module] { * default: { test: '/home/runner/rollup-filename-cjs-esm/importme.cjs' } * } */exportdefaultindex;
Additional Information
Any advice related to working around the __filename error is especially appreciated, I expect the inclusion of module.exports at the top of the repl.it bundle is related to the lower Node version, but I figured I would point that out.
I expect the inclusion of module.exports at the top of the repl.it bundle is related to the lower Node version, but I figured I would point that out.
No, it is because of your use of the .cjs extension which is not included by this plugin by default. If you add it to the extensions option of this plugin, it works correctly. Unfortunately, nobody has done a PR to fix the default for this option yet.
Otherwise, __filename and __dirname are not "fixed" for various reasons:
hardcoding them to the source modules is likely not desired as this would hard-code paths on the file system into the bundle and make the build machine specific.
hardcoding them to the generated modules is rather hard because they are not known at the time when the CommonJS plugin does its work and Rollup core itself never sees any CommonJS.
hardcoding may actually not be desired when the output format is 'cjs'. Only for other formats there is a problem.
hardcoding them to the generated modules would still make the build likely depend on the machine it was done, or it will need to contain some "dreamed up" paths.
You could write a plugin that uses the renderChunk hook to do a post-processing transformation to replace __filename and __dirname with whatever makes the most sense to you.
Alternatively, one could write a plugin that transforms __filename and __dirname using something import.meta.url related. But due to the reasons outlined above, I wonder if this should be a separate plugin.
@lukastaegert Thank you for your insight and fast response Lukas. I would probably agree that it should be a separate plugin. I'd be happy to write it.
No, it is because of your use of the .cjs extension which is not included by this plugin by default. If you add it to the extensions option of this plugin, it works correctly. Unfortunately, nobody has done a PR to fix the default for this option yet.
Thank you for this! I put one in at #524, please let me know if it is insufficient.
For a bit more background, my goal is to take an ES module that relies on Node dependencies, coerce all import logic to ES2015, and spit out a massive bundle whose only import statements are NodeJS builtins. I can compile an ES module that has all the node_modules imports at the top (e.g. import chalk from 'chalk'; import someOtherThirdParty from 'third-party' ...), but rolling those in with node-resolve is quite the challenge.
I can achieve this for a CJS output using Rollup or Webpack, but Webpack can't create an ESM output, so I would sooner invest time into getting Rollup to handle this case than work harder to use both of them.
I would be very interested in getting your specific judgment on how to approach the __filename issue for this specific case: One entry point, one output file, and the only leftover imports are NodeJS builtins, with all third party dependencies are rolled in. I appreciate the information you've offered so far.
Re. __filename logic:
Hardcoding them to the source modules is likely not desired as this would hard-code paths on the file system into the bundle and make the build machine specific.
This was my primary concern when thinking about this, but I'm thinking primarily about this use case. If the output is always going to exist in the same place relative to the module (i.e., at ./dist/output.mjs), we are guaranteed to have only one output, and that output will have rolled in all the possible source codes for any module that is referencing __filename pr __dirname, won't those always be the same at runtime, since the plugins are embedded in the output bundle? __filename = ./dist/output.mjs, __dirname = ./dist? Replace with path.resolve('./dist/output.mjs') if necessary?
Hardcoding them to the generated modules is rather hard because they are not known at the time when the CommonJS plugin does its work and Rollup core itself never sees any CommonJS.
For this case where we are compiling one large output that will have resolved all non-builtin modules, all generated modules will be the same file: One big bundle at dist/output.mjs.
Hardcoding may actually not be desired when the output format is 'cjs'. Only for other formats there is a problem.
Thought the same thing: This would only be for the case when output.format = 'esm' - I guess this would be the only time anyone would want to include this plugin. Maybe include it in the name: esm-filename-dirname or something.
Alternatively, one could write a plugin that transforms __filename and __dirname using something import.meta.url related.
I thought about this as well, but interestingly, for this case, at the end of the build process, any non-builtin module that was required by any dependency will all exist in the same file: The output bundle.
All of this is for an ESM development environment that relies on just Rollup and Closure Compiler - once this issue is solved I will have full ESM-CJS interop, and will be able to ship backwards-compatible packages with no dependencies. Very sorry for talking your ear off (figuratively speaking) and very much appreciate any thoughts you have.
changed the title [-]CommonJS -> ES2015: Output contains references to __filename[/-][+][commonjs] Output contains references to __filename[/+]on Aug 4, 2020
Since the Node-ES interop proposal has not been closed at #539 and this would require an out-of-the-box approach to __filename and __dirname, I am reopening this for now.
Hey folks. This issue hasn't received any traction for 60 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it. ⓘ
I don't think I have the experience on this repo to own such a delicate issue I just think it shouldn't be closed by happy "stale" bot, I didn't mean to be mean if it arrived that way sorry.
Activity
lukastaegert commentedon Aug 2, 2020
No, it is because of your use of the
.cjsextension which is not included by this plugin by default. If you add it to theextensionsoption of this plugin, it works correctly. Unfortunately, nobody has done a PR to fix the default for this option yet.Otherwise,
__filenameand__dirnameare not "fixed" for various reasons:You could write a plugin that uses the
renderChunkhook to do a post-processing transformation to replace__filenameand__dirnamewith whatever makes the most sense to you.Alternatively, one could write a plugin that transforms
__filenameand__dirnameusing somethingimport.meta.urlrelated. But due to the reasons outlined above, I wonder if this should be a separate plugin.ctjlewis commentedon Aug 2, 2020
@lukastaegert Thank you for your insight and fast response Lukas. I would probably agree that it should be a separate plugin. I'd be happy to write it.
Thank you for this! I put one in at #524, please let me know if it is insufficient.
For a bit more background, my goal is to take an ES module that relies on Node dependencies, coerce all import logic to ES2015, and spit out a massive bundle whose only
importstatements are NodeJS builtins. I can compile an ES module that has all thenode_modulesimports at the top (e.g.import chalk from 'chalk'; import someOtherThirdParty from 'third-party' ...), but rolling those in withnode-resolveis quite the challenge.I can achieve this for a CJS output using Rollup or Webpack, but Webpack can't create an ESM output, so I would sooner invest time into getting Rollup to handle this case than work harder to use both of them.
I would be very interested in getting your specific judgment on how to approach the
__filenameissue for this specific case: One entry point, one output file, and the only leftover imports are NodeJS builtins, with all third party dependencies are rolled in. I appreciate the information you've offered so far.Re.
__filenamelogic:This was my primary concern when thinking about this, but I'm thinking primarily about this use case. If the output is always going to exist in the same place relative to the module (i.e., at
./dist/output.mjs), we are guaranteed to have only one output, and that output will have rolled in all the possible source codes for any module that is referencing__filenamepr__dirname, won't those always be the same at runtime, since the plugins are embedded in the output bundle?__filename = ./dist/output.mjs,__dirname = ./dist? Replace withpath.resolve('./dist/output.mjs')if necessary?For this case where we are compiling one large output that will have resolved all non-builtin modules, all generated modules will be the same file: One big bundle at
dist/output.mjs.Thought the same thing: This would only be for the case when
output.format = 'esm'- I guess this would be the only time anyone would want to include this plugin. Maybe include it in the name:esm-filename-dirnameor something.I thought about this as well, but interestingly, for this case, at the end of the build process, any non-builtin module that was required by any dependency will all exist in the same file: The output bundle.
All of this is for an ESM development environment that relies on just Rollup and Closure Compiler - once this issue is solved I will have full ESM-CJS interop, and will be able to ship backwards-compatible packages with no dependencies. Very sorry for talking your ear off (figuratively speaking) and very much appreciate any thoughts you have.
[-]CommonJS -> ES2015: Output contains references to __filename[/-][+][commonjs] Output contains references to __filename[/+]shellscape commentedon Sep 6, 2020
@ctjlewis it looks like there's consensus around a separate plugin to handle the original case. Can we close this?
lukastaegert commentedon Sep 6, 2020
By the way @ctjlewis did you look into https://www.npmjs.com/package/rollup-plugin-node-globals ? It promises a solution for the issue you described.
ctjlewis commentedon Sep 6, 2020
I use a custom workspace environment, gnv, to deal with this now. I did not end up using the
node-globalsplugin.ctjlewis commentedon Nov 13, 2020
Since the Node-ES interop proposal has not been closed at #539 and this would require an out-of-the-box approach to
__filenameand__dirname, I am reopening this for now.stale commentedon Jan 14, 2021
Hey folks. This issue hasn't received any traction for 60 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it. ⓘ
ZeldOcarina commentedon Apr 10, 2024
I don't think this should be closed.
shellscape commentedon Apr 10, 2024
@ZeldOcarina we'd appreciate your contribution and would happily reopen if you'd like to own it.
ZeldOcarina commentedon Apr 10, 2024
I don't think I have the experience on this repo to own such a delicate issue I just think it shouldn't be closed by happy "stale" bot, I didn't mean to be mean if it arrived that way sorry.