question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[NOT RESOLVED] Built 'module' bundle errors with "require is not defined", but 'commonjs' bundle errors with "Cannot use import"

See original GitHub issue

Bug report

https://stackoverflow.com/questions/72892145/is-it-possible-to-create-single-file-bundle-with-webpack-target-node-type-module

Done.

What is the current behavior?

I’m trying to bundle an ES module node app into a single file, with the exception of the sharp library which has problems with Webpack. This is a node server app, not browser.

All of my code are modules, and I don’t use require(). Only third=party dependencies might.

In webpack.config.js, ff I set the target to node, node18.3 or async-node18.3, I get the following error:

(output config):

        filename: '[name].bundle.mjs',
        path: path.resolve(__dirname, 'dist'),
        sourceMapFilename: '[name].bundle.map',
        chunkFormat: 'module',
$ node ./dist/index.bundle.mjs

<remove source outout for brevity>

ReferenceError: require is not defined
    at 67361 (file:///Path/to/app/dist/index.bundle.mjs:2:4368640)
    at __webpack_require__ (file:///Path/to/app/dist/index.bundle.mjs:2:5256005)
    at file:///Path/to/app/dist/index.bundle.mjs:2:4313644
    at __webpack_require__.a (file:///Path/to/app/dist/index.bundle.mjs:2:5256751)
    at 63607 (file:///Path/to/app/dist/index.bundle.mjs:2:4313499)
    at __webpack_require__ (file:///Path/to/app/dist/index.bundle.mjs:2:5256005)
    at file:///Path/to/app/dist/index.bundle.mjs:2:5258585
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:409:24)

Node.js v18.3.0

If I change target to es2020 and keep output as-is, webpack fails with (290 errors reduced for brevity):

ERROR in /Path/to/app/node_modules/mongoose/lib/browserDocument.js 8:21-51
Module not found: Error: Can't resolve 'events' in '/Path/to/app/node_modules/mongoose/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "events": require.resolve("events/") }'
	- install 'events'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "events": false }
 @ Path/to/app/node_modules/mongoose/lib/document_provider.js 9:24-55
 @ Path/to/app/node_modules/mongoose/lib/index.js 927:38-68
 @ Path/to/app/node_modules/mongoose/index.js 9:17-34
 @ ./node_modules/hapi-mongoose-connect-next/lib/index.js 3:15-34
 @ ./src/index.ts 6:0-61 31:14-33

Module not found: Error: Can't resolve 'util' in '/Path/to/app/node_modules/mongoose/lib'
Module not found: Error: Can't resolve 'assert' in '/Path/to/app/node_modules/mongoose/lib/cast'
Module not found: Error: Can't resolve 'util' in '/Path/to/app/node_modules/mongoose/lib/cursor'
Module not found: Error: Can't resolve 'stream' in '/Path/to/app/node_modules/mongoose/lib/cursor'
Module not found: Error: Can't resolve 'tty' in '/Path/to/app/node_modules/mongoose/node_modules/debug/src'
Module not found: Error: Can't resolve 'os' in '/Path/to/app/node_modules/mongoose/node_modules/ip/lib'
Module not found: Error: Can't resolve 'dns' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/auth'
Module not found: Error: Can't resolve 'crypto' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/auth'
Module not found: Error: Can't resolve 'http' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/auth'
Module not found: Error: Can't resolve 'url' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/auth'
Module not found: Error: Can't resolve 'net' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib/cmap'
Module not found: Error: Can't resolve 'tls' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib/cmap'
Module not found: Error: Can't resolve 'zlib' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/wire_protocol'
Module not found: Error: Can't resolve 'dns' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib'
Module not found: Error: Can't resolve 'fs' in '/Path/to/app/node_modules/mongoose/node_modules/mongodb/lib'
Module not found: Error: Can't resolve 'path' in '/Path/to/app/node_modules/mongoose/node_modules/saslprep/lib'
Module not found: Error: Can't resolve 'https' in '/Path/to/app/node_modules/@hapi/hapi/lib'
Module not found: Error: Can't resolve 'vm' in '/Path/to/app/node_modules/fast-redact/lib'
Module not found: Error: Can't resolve 'net' in '/Path/to/app/node_modules/http-proxy-agent/dist'
Module not found: Error: Can't resolve 'child_process' in '/Path/to/app/node_modules/jsdom/lib/jsdom/living/xhr'

290 errors have detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

webpack 5.65.0 compiled with 290 errors and 21 warnings in 32411 ms

If I change target back to node but change output to commonjs, I get:

        filename: '[name].bundle.cjs',
        path: path.resolve(__dirname, 'dist'),
        sourceMapFilename: '[name].bundle.map',
        chunkFormat: 'commonjs',
$ node ./dist/index.bundle.cjs

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Module._load (node:internal/modules/cjs/loader:827:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

Node.js v18.3.0

I seem to be stuck in a catch-22 here. I can’t compile to commonjs because I use the following in one of my modules:

import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

And I can’t remove import.meta.url because I’m using modules and I need to polyfill __filename and __dirname. I’ve gone though the documentation, and I don’t see what I’m missing. So, I can only assume this is a webpack bug.

Contents of ./dist with target: 'node':

$ ls -al ./dist
total 44512
drwxr-xr-x   6 me  me       192 Jul  6 23:57 .
drwxr-xr-x  22 me  me       704 Jul  6 21:57 ..
-rw-r--r--   1 me  me  17330789 Jul  6 23:57 index.bundle.map
-rw-r--r--   1 me  me   5417703 Jul  6 23:57 index.bundle.mjs
-rw-r--r--   1 me  me     34784 Jul  6 23:57 index.bundle.mjs.LICENSE.txt
drwxr-xr-x   4 me  me       128 Jul  6 23:57 resources

If the current behavior is a bug, please provide the steps to reproduce.

package.json:

  "type": "module",
  "main": "./dist/index.bundle.mjs",
  "module": "./dist/index.bundle.mjs",
  "sideEffects": false,
  "overrides": {
    "@mapbox/node-pre-gyp": "1.0.9"
  },

tsconfig.json:

{
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "src",
    "allowJs": true,
    "target": "es2021",
    "module": "es2022",
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",  
    "types": ["node", "jest"], 
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "lib": ["es2021"],
  },
  "include": [
    "src/index.ts",
    "src/**/*",
    "src/resources"
  ],
  "exclude": ["node_modules"]
}

Complete webpack.config.js:

import path from 'path';
import webpack from 'webpack';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
    target: 'async-node18.3',
    entry: {
        index: './src/index.ts'
    },
    devtool: 'source-map',
    node: {
        global: true,
        __filename: true,
        __dirname: true,
    },
    module: {
        rules: [
            {
                test: /\.html$/i,
                loader: "html-loader",
            },
            {
                test: /\.[jt]sx?$/,
                resolve: {
                    fullySpecified: false,
                },
            },
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },
            { test: /\.node$/, use: "node-loader" }
        ],
    },
    experiments: {
        topLevelAwait: true,
        outputModule: true,
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
    output: {
        filename: '[name].bundle.mjs',
        path: path.resolve(__dirname, 'dist'),
        sourceMapFilename: '[name].bundle.map',
        chunkFormat: 'module',
        environment: {
            arrowFunction: true,
            bigIntLiteral: false,
            const: true,
            destructuring: true,
            dynamicImport: true,
            forOf: true,
            module: true,
            optionalChaining: true,
            templateLiteral: true,
        }
    },
    plugins: [
        new webpack.IgnorePlugin({
            resourceRegExp: /canvas/,
            contextRegExp: /jsdom$/
        }),
        new webpack.ContextReplacementPlugin(/require_optional/)
    ],
    externals: {
        'sharp': 'commonjs sharp'
    }
};

What is the expected behavior?

The expect behavior is that javascript modules bundled as a single file module should have all require references replaced, or modules compiled as commonjs should do something to convert import.meta.*.

Other relevant information: webpack version: 5.73.0 Node.js version: 18.3.0 Operating System: macOS 12.4 Additional tools: typescript: 4.6.4, ts-loader: 9.3.0, webpack-cli: 4.10.0

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:16 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
vankopcommented, Jul 8, 2022

webpack can output only commojs for Node.js right now, please use

output: {
        filename: '[name].bundle.js',
}
0reactions
andrewRichardsoncommented, Sep 21, 2022

Bump @vankop

Read more comments on GitHub >

github_iconTop Results From Across the Web

Client on Node.js: Uncaught ReferenceError: require is not ...
As the project doesn't require CommonJS and it must have ES3 compatibility (modules not supported) all you need is just remove all export...
Read more >
How To Fix ReferenceError require is not defined in JavaScript
In this case, check your package.json file for an property called type . If that is set to module , ES6 modules will...
Read more >
CommonJS modules | Node.js v19.3.0 Documentation
Attempting to do so will throw a ERR_REQUIRE_ESM error. Use import() instead. The .mjs extension is reserved for ECMAScript Modules which cannot be...
Read more >
RequireJS API
If the module does not have dependencies, but needs to use a function to do some setup work, then define itself, pass a...
Read more >
ts-node - npm
This error is thrown by node when a module is require() d, but node believes it should execute as native ESM. This can...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found