Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic require of "path" is not supported #3324

Open
jdion84 opened this issue Aug 20, 2023 · 3 comments
Open

Dynamic require of "path" is not supported #3324

jdion84 opened this issue Aug 20, 2023 · 3 comments

Comments

@jdion84
Copy link

jdion84 commented Aug 20, 2023

im trying to build and run express server code

entry/server.js:

import express from 'express'

const app = express()

app.get('/', (req, res) => {
    res.send('Hello World!')
})

app.listen(3000, () => {
    console.log(`Example app listening on http://localhost:3000`)
})

entry/build.js:

import * as esbuild from 'esbuild'

await esbuild.build({
    entryPoints: [
        'entry/server.js',
    ],
    bundle: true,
    outdir: 'private',
    platform: 'node',
    format: 'esm',
})

package.json:

{
    "name": "bas-framework-2",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "node entry/build.js",
        "serve": "node private/server.js",
        "dev": "npm run build && npm run serve"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "type": "module",
    "devDependencies": {
        "esbuild": "^0.19.2",
        "express": "^4.18.2"
    }
}

when i do npm run dev i get this error:

file:///Users/jdion84/Sites/bas-framework-2/private/server.js:12
  throw Error('Dynamic require of "' + x + '" is not supported');
        ^

Error: Dynamic require of "path" is not supported
    at file:///Users/jdion84/Sites/bas-framework-2/private/server.js:12:9
    at node_modules/depd/index.js (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:37:20)
    at __require2 (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:15:50)
    at node_modules/body-parser/index.js (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:16528:21)
    at __require2 (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:15:50)
    at node_modules/express/lib/express.js (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:21855:22)
    at __require2 (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:15:50)
    at node_modules/express/index.js (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:21924:22)
    at __require2 (file:///Users/jdion84/Sites/bas-framework-2/private/server.js:15:50)
    at file:///Users/jdion84/Sites/bas-framework-2/private/server.js:21929:30

Node.js v20.4.0
@hyrious
Copy link

hyrious commented Aug 20, 2023

This issue is already tracked here: #1921

In summary, this runtime error is caused by bundling CJS libraries into ESM context (i.e. bundle express in format: 'esm'). esbuild uses closures to wrap these CJS liraries, and Node.js forbids dynamic (i.e. not at the top level) require on builtin modules.

I would still suggest you to exclude these dependencies from your bundle with --packages=external or --external:express since your runtime supports loading them from the file system, and it also bundles less code.

@ghost
Copy link

ghost commented Oct 13, 2023

@hyrious will work if i deploy the code?

unphased added a commit to unphased/tst that referenced this issue Mar 14, 2024
awong-dev added a commit to SPS-By-The-Numbers/transcripts that referenced this issue Jun 24, 2024
Making this work with

  * firebase functions
  * esm modules, esp with "type":"modules" in package.json
  * typescript

is hilariously hard.  Firebase functions do not understand esm modules. This
causes their preprocessor to blow up if you use them. There is a workaround
here:

  firebase/firebase-tools#2994 (comment)

that uses esbuild to bundle all of the code into one huge index.js that
papers over all the preprocessing issues. It also does some magic with
package.json and the npm-run-all package to ensure all of esbuild, tsc,
and firebase run in parallel so that changing a typescript source file
results in an actual behavior change to a running function emulator.

However, this is still not sufficient because esbuild has decided to
bundle everything in devDependencies and dependencies into the index.js.
This will pull in old commonJS packages but attempt to run that
syntax in an ESM environment which causes a cryptic

  "Dynamic require of 'something' is not supported"

This will send you down rabbit holes of trying to fix tsc config because
it looks like you are exporting the wrong module loading type..which
will lead you to try setting tsconfig's module to "nodenext"...which
confusing *requires* you to put .js after all your relative path imports
even if the source file is .ts.  This is confusing as heck.

But the real problem is you need to exclude packages from esbuild:

  evanw/esbuild#3324 (comment)

And now everything will run. Howeever, it means you have to ensure the
deploy picks up your node_modules.... ugh.
awong-dev added a commit to SPS-By-The-Numbers/transcripts that referenced this issue Jun 24, 2024
Making this work with

  * firebase functions
  * esm modules, esp with "type":"modules" in package.json
  * typescript

is hilariously hard.  Firebase functions do not understand esm modules. This
causes their preprocessor to blow up if you use them. There is a workaround
here:

  firebase/firebase-tools#2994 (comment)

that uses esbuild to bundle all of the code into one huge index.js that
papers over all the preprocessing issues. It also does some magic with
package.json and the npm-run-all package to ensure all of esbuild, tsc,
and firebase run in parallel so that changing a typescript source file
results in an actual behavior change to a running function emulator.

However, this is still not sufficient because esbuild has decided to
bundle everything in devDependencies and dependencies into the index.js.
This will pull in old commonJS packages but attempt to run that
syntax in an ESM environment which causes a cryptic

  "Dynamic require of 'something' is not supported"

This will send you down rabbit holes of trying to fix tsc config because
it looks like you are exporting the wrong module loading type..which
will lead you to try setting tsconfig's module to "nodenext"...which
confusing *requires* you to put .js after all your relative path imports
even if the source file is .ts.  This is confusing as heck.

But the real problem is you need to exclude packages from esbuild:

  evanw/esbuild#3324 (comment)

And now everything will run. Howeever, it means you have to ensure the
deploy picks up your node_modules.... ugh.

Oh...and jest's setup requires you to NOT use verbatimModuleSyntax otherwise
you cannot import typescript types since its config file is a CommonJs
setup and the import syntax is ESM.
awong-dev added a commit to SPS-By-The-Numbers/transcripts that referenced this issue Jun 26, 2024
Making this work with

  * firebase functions
  * esm modules, esp with "type":"modules" in package.json
  * typescript

is hilariously hard.  Firebase functions do not understand esm modules. This
causes their preprocessor to blow up if you use them. There is a workaround
here:

  firebase/firebase-tools#2994 (comment)

that uses esbuild to bundle all of the code into one huge index.js that
papers over all the preprocessing issues. It also does some magic with
package.json and the npm-run-all package to ensure all of esbuild, tsc,
and firebase run in parallel so that changing a typescript source file
results in an actual behavior change to a running function emulator.

However, this is still not sufficient because esbuild has decided to
bundle everything in devDependencies and dependencies into the index.js.
This will pull in old commonJS packages but attempt to run that
syntax in an ESM environment which causes a cryptic

  "Dynamic require of 'something' is not supported"

This will send you down rabbit holes of trying to fix tsc config because
it looks like you are exporting the wrong module loading type..which
will lead you to try setting tsconfig's module to "nodenext"...which
confusing *requires* you to put .js after all your relative path imports
even if the source file is .ts.  This is confusing as heck.

But the real problem is you need to exclude packages from esbuild:

  evanw/esbuild#3324 (comment)

And now everything will run. Howeever, it means you have to ensure the
deploy picks up your node_modules.... ugh.

Oh...and jest's setup requires you to NOT use verbatimModuleSyntax otherwise
you cannot import typescript types since its config file is a CommonJs
setup and the import syntax is ESM.
@ford-jones
Copy link

@hyrious will work if i deploy the code?

It depends on your deployment environment, if you are only sending the build output upstream then no - it won't.
If you are sending the whole application root up, including any modules and all the other files needed to produce the build; then it should work fine :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants