Search code examples
angularangular-universalserver-side-renderingangular-webpack

Angular seems to build dev dependencies into universal bundle?


I'm using typegoose to unify my interfaces + db schemas shared across ~6 apps. It helps me keep my data structure consistent.

Now that means that most of my types/interfaces in my Angular app are coming from an external project.

Because of this I have:

    "typegoose": "^5.9.0",
    "@types/mongoose": "^5.5.17",
    "mongoose": "^5.6.12",
    "@tlabs/models": "^1.7.13",

added as dev dependencies. All works fine and I can even build but when I try to build using universal, I can see this warning:

WARNING in ./node_modules/mongoose/lib/index.js 11:28-64
Critical dependency: the request of a dependency is an expression

x5 times about mongodb/mongoose

And when I check my lambda function log, I can see:

2019-09-17T14:56:59.691Z undefined ERROR (node:8) DeprecationWarning: This Package got moved, please use `@hasezoey/typegoose` | github:hasezoey/typegoose

which comes from typegoose so that gets me confused.

I'm 100% using only as types, if I attempt to use it by instantiating a class object using one of the types, the whole app won't work at all.

Is there something I'm missing about the configuration of webpack here?


Solution

  • I also got similar errors when dealing with angular universal and other SQL databases. But, there is a solution that at least worked for me.

    And that is the webpack-node-externals package. Which simply makes webpack ignore your node_modules folder.

    Link to the NPM page >> https://www.npmjs.com/package/webpack-node-externals

    assuming everything else in your webpack.server.config.js this should solve those errors and make your bundle size much much smaller. (keep in mind that you will need to include your node_modules folder when deploying to other environments)

    Brief Tutorial

    1. npm i webpack-node-externals
    2. open webpack.server.config.js in a text editor
    3. Format that file to look similar to this:
    module.exports = env => {
      return {
        mode: "production",
        entry: {
          // This is our Express server for Dynamic universal
          server: "./server.ts"
        },
        externals: {
          "./dist/server/main": 'require("./server/main")'
        },
        target: "node",
        node: {
          __dirname: false,
          __filename: false
        },
        externals: [nodeExternals()], // <======LOOK HERE======|
        resolve: { extensions: [".ts", ".js"] },
        optimization: {
          minimize: false
        },
        output: {
          // Puts the output at the root of the dist folder
          path: path.join(__dirname, "dist"),
          filename: "[name].js"
        },
        module: {
          noParse: /polyfills-.*\.js/,
          rules: [
            { test: /\.ts$/, loader: "ts-loader" },
            {
              // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
              // Removing this will cause deprecation warnings to appear.
              test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
              parser: { system: true }
            }
          ]
        },
        plugins: [
          new webpack.ContextReplacementPlugin(
            // fixes WARNING Critical dependency: the request of a dependency is an expression
            /(.+)?angular(\\|\/)core(.+)?/,
            path.join(__dirname, "src"), // location of your src
            {} // a map of your routes
          ),
          new webpack.ContextReplacementPlugin(
            // fixes WARNING Critical dependency: the request of a dependency is an expression
            /(.+)?express(\\|\/)(.+)?/,
            path.join(__dirname, "src"),
            {}
          ),
        ]
      };
    };