Parcel: (nodejs) Nested Code splitting: __dirname is not defined

Created on 5 Feb 2019  路  6Comments  路  Source: parcel-bundler/parcel

馃悰 bug report

UnhandledPromiseRejectionWarning: ReferenceError: __dirname is not defined

In case if you are using code splitting inside a code spitted block the function loadJSBundle would be added to the parent block.
The function is simple

module.exports = function loadJSBundle(bundle) {
return new Promise(function (resolve, reject) {
    fs.readFile(__dirname + bundle, 'utf8', function (err, data) {
    // ...
   }).then(function (code) {
    new Function('', code)();
  });

The problem - it could not execute _itself_, ie own duplicate in a chunk, as long as it __eval__ module code, and __dirname is __not defined__ for eval.

馃帥 Configuration (.babelrc, package.json, cli command)

parcel build server/index.js -d dist/server --public-url /dist --target=node --no-minify --no-cache

馃 Expected Behavior

Should work. Ideally without eval.

馃槸 Current Behavior

Runtime error. Dynamic import returns rejected promise.

馃拋 Possible Solution

The simple solution is to restore global variable.

new Function('', `var __dirname="${__dirname}";${code}`)();

馃敠 Context

I know Code-splitting and SSR is a pain point for Parcel, and so far there is only one working (React)SSR-enabled library - https://github.com/theKashey/react-imported-component
I am working on bringing a better CSS experience, and it's almost done.
I just need to create a few examples. But they don't work :(

馃捇 Code Sample

https://github.com/theKashey/react-imported-component/tree/master/examples/SSR/parcel-react-ssr

馃實 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.11.0
| Node | 10.9
| npm/Yarn | yarn 1.10
| Operating System | MacOS

Bug Stale

Most helpful comment

Just run it

console.log(1, __dirname);  // works
console.log(2, eval('__dirname')); // works
console.log(3, new Function('', 'return __dirname')()); // not working, and this is the way Parcel evals module

All 6 comments

__dirname is a global variable that is always defined in the node runtime. If you鈥檙e using 鈥攖arget=node it is expected your target is actually node

Sent with GitHawk

Just run it

console.log(1, __dirname);  // works
console.log(2, eval('__dirname')); // works
console.log(3, new Function('', 'return __dirname')()); // not working, and this is the way Parcel evals module

same thing happened to me on a module that uses the following
module.exports = protobuf(fs.readFileSync(path.join(__dirname, '..', 'schema.proto'), 'utf-8'))

We have this .babelrc config working. Hope it helps

{
  "presets": [["@babel/env"], ["@babel/react"]],
  "plugins": [
    ["@babel/plugin-transform-react-jsx", { "pragmaFrag": "React.Fragment" }],
    ["@babel/plugin-syntax-dynamic-import"],
    ["react-imported-component/babel"]
  ],
  "env": {
    "server": {
      "presets": [
        ["@babel/react"],
        ["@babel/preset-env", { "targets": { "node": "current" } }]
      ],
      "plugins": [
        [
          "@babel/plugin-transform-react-jsx",
          { "pragmaFrag": "React.Fragment" }
        ],
        ["@babel/plugin-syntax-dynamic-import"],
        ["react-imported-component/babel"],
        ["babel-plugin-dynamic-import-node"]
      ]
    }
  }
}

I run into this issue. In my case the __dirname error was thrown after a module not found error.
The solution from @nemish also solved it for me. I added the newly released official babel plugins instead of babel-plugin-dynamic-import-node:

 '@babel/plugin-proposal-dynamic-import',
 '@babel/plugin-transform-modules-commonjs',

@DeMoorJasper Do you think it makes sense to add something like this by default to parcel or do you have other plans to solve this in v2 already?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 30 days if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings