Socrates
Socrates

Reputation: 9574

Webpack bundle imports with an @

I am trying to bundle a Node Express server built with TypeScript using Webpack.

Compiling/Transpiling into one JavaScript file server.js works well, but the file does not seem to have all necessary imports included. If the file is in dist/server.js and there are still Node modules in node_modules/..., then starting the server using node dist/server.js works well. But if I copy the server.js to any other location without also copying the Node modules, and then start it, it does not find classes imported with an @.

Possible error:

mysystem:Desktop myuser$ node server.js 
internal/modules/cjs/loader.js:582
    throw err;
    ^

Error: Cannot find module '@overnightjs/core'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:580:15)
    at Function.Module._load (internal/modules/cjs/loader.js:506:25)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/Users/myuser/Desktop/server.js:1:1422)
    at a (/Users/myuser/Desktop/server.js:1:172)
    at Object.<anonymous> (/Users/myuser/Desktop/server.js:1:6473)
    at a (/Users/myuser/Desktop/server.js:1:172)
    at Object.<anonymous> (/Users/myuser/Desktop/server.js:1:6233)
    at a (/Users/myuser/Desktop/server.js:1:172)

I think that I might have something missing in my Webpack configuration file, which is:

const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: "./src/start.ts",
    output: {
        filename: "server.js",
        path: path.resolve(__dirname, "dist")
    },

    node: {
      // Need this when working with express, otherwise the build fails
      __dirname: false,   // if you don't put this is, __dirname
      __filename: false,  // and __filename return blank or /
      fs: 'empty',
    },

    resolve: {
        alias: {},
        // Add '.ts', and '.tsx' as resolvable exteensions.
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    externals: [nodeExternals()], // Need this to avoid error when working with Express

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    plugins: [
        new CleanWebpackPlugin({
            cleanAfterEveryBuildPatterns: ['dist']
        })
    ]
};

The versions I use:

How can I also add imports starting with an @ into the bundle in Webpack?

Upvotes: 1

Views: 106

Answers (2)

user9157769
user9157769

Reputation:

Don't bundle modules when transpiling TypeScript. Standard practice is two download modules wherever you've deployed you server. Make sure to use the production flag if you're all done developing. npm i --production

Upvotes: 1

felixmosh
felixmosh

Reputation: 35483

It is make sense, Your externals config tells webpack not to bundle node_modules into the bundle but require them at run time.

This means that if you are not copying node_modules to the new location, it will try to require it, and will fail.

Usually it is best practice not to bundle node_modules whenever you are creating a node bundle.

You have 2 choices:

  1. Remove externals config - will increase bundle size cause it will contain all the node_modules that your app is using.
  2. Installing a fresh node_modules on you new location, if this location is a production env, you can use npm install --production which will install only the dependencies without devDependencies.

Upvotes: 1

Related Questions