preface

A while ago, I worked on a Nest project. When I finished developing a function and planned to deploy it to the server for testing, I found that it did not work. I reported a lot of errors and lacked many dependent packages.

I looked for solutions all over the web, and they all came up with the same answer: Nest does not package dependencies into the package, so it needs to clone the project on the server to install dependencies.

This is not the answer I was looking for, and installing node_modules on the server is nonsense. Fortunately, after some research, I finally solved this problem. In this article, I would like to share with you my implementation ideas and solutions, and welcome interested developers to read this article.

Scenario overview

Continuing with the project we created in the article “Building server-side applications with NestJS” to describe this problem, we open the package.json file and execute the build command inside.

{
    "scripts": {
      "build": "nest build",}}Copy the code

In the blink of an eye, it’s packed, and you’ll have a folder dist in your project root, as shown below.

Then we uploaded dist to the server and used Node to execute the main.js file in the dist directory. After uploading the file to the server, I found that the entire folder was only 18KB. The volume of the server application package developed is incredibly small. The same function is realized in Java, and the JAR package packaged is 50MB.

When I run on the server, I am dumbfounded, the program is reported to run wrong 🌚, this thing does not pass kua.

Location problem

When I opened the dist directory with a bit of trepiness, I found that it simply compiled TS into JS without packing any dependency packages. All of its dependency packages were referenced from node_modules. We do not have these dependencies on our server, so he reported an error.

I looked for a solution on the search engine. It’s ridiculous to clone projects on the server and then install huge node_modules on the server.

After talking to several people, they said that the Node project is all about installing dependencies on the server, which reminded me of a diagram I saw years ago that would be perfect for this.

The solution

I am a pursuit of perfection, such a huge open source library, the designer must not be so stupid, this low-level problem should have been considered, since the online solution can not be found, then I read its source code.

God helps those who help themselves, when I refer to nest – cli source code package module, in @ nestjs/cli/actions/build action. The js file found it has a webpack configuration variables.

Later, I found this configuration item in the Nest-Build section of the Official Nest documentation and found that it could generate a single file main.js by adding the –webpack parameter to the package command.

So, I added this parameter, after running the package command, the single file is generated, but the dependent file is still not packaged. There’s only one possibility: Nest-CLI excludes dependencies from packaging.

Ultimately, I am @ nestjs/cli/lib/compiler/defaults/webpack – defaults. Js discovered the issue, as shown in the figure below:

  • It USESwebpack-node-externalsPlug-ins mask the packaging of dependencies.

The implementation code

After the above analysis, we located the problem. Since it blocks dependent packaging by default, we created a webpack.config.js file by ourselves, ignoring externals and some plug-ins provided by Nest, and the problem was solved perfectly.

  • willexternalsProperty is left blank, ignoring the defaultwebpack-node-externalsThe plug-in
  • Using IgnorePlugin ignores some useless dependency packages in Nest
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
const webpack = require("webpack");
// fork-ts-checker-webpack-plugin needs to be installed separately
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");

module.exports = {
  entry: "./src/main".target: "node".// Ignore the webpack-node-externals plugin if left blank
  externals: {},
  // Ts file processing
  module: {
    rules: [{test: /\.ts? $/,
        use: {
          loader: "ts-loader".options: { transpileOnly: true}},exclude: /node_modules/}},// The name and location of the packaged file
  output: {
    filename: "main.js".path: path.resolve(__dirname, "dist")},resolve: {
    extensions: [".js".".ts".".json"]},plugins: [
    // The plug-in to ignore
    new webpack.IgnorePlugin({
      checkResource(resource) {
        const lazyImports = [
          "@nestjs/microservices"."@nestjs/microservices/microservices-module"."@nestjs/websockets/socket-module"."cache-manager"."class-validator"."class-transformer"
        ];
        if(! lazyImports.includes(resource)) {return false;
        }
        try {
          require.resolve(resource, {
            paths: [process.cwd()]
          });
        } catch (err) {
          return true;
        }
        return false; }}),new ForkTsCheckerWebpackPlugin()
  ]
};

Copy the code

⚠️ Note: the webpack configuration file requires the version number of webpack in package.json to be ^5.11.0″. You also need to install the fork-ts-checker-webpack-plugin dependency package in devDependencies.

Finally, we modify the packaging command to:

{
    "scripts": {
       "build": "nest build --webpack --webpackPath=./webpack.config.js",}}Copy the code

After executing the above command, we see that the dependency package has been loaded into main.js and the file size has increased to 3.6MB.

Finally, we use Node to run the JS file, and there are no errors, running smoothly.

We are using Postman to test whether the interface can be accessed normally. As shown below, it can also be accessed normally.

Tip: When running a Node project on a server, it is usually executed using PM2. Developers interested in this, please find out for yourself.

The sample code

For the complete code listed in this article, go to:

  • webpack.config.js
  • package.json

Write in the last

At this point, the article is shared.

I’m an amazing programmer, a front-end developer.

If you are interested in me, please visit my personal website for further information.

  • If there are any errors in this article, please correct them in the comments section. If this article helped you, please like it and follow 😊
  • This article was first published in the magic programmer public number, without permission to prohibit reprinting 💌