Nest项目部署的最佳方式

简介: Nest项目部署的最佳方式

前言


前一阵子搞了个nest项目,当我开发完一个功能,打算部署到服务器进行测试时,发现它跑不起来,报了一大堆错缺少了很多依赖包。


我几乎找遍了全网的解决方案,他们的答案齐刷刷只有一个:nest在打包时,不会将依赖打包进去,需要在服务器上clone项目,安装依赖。


这个答案不是我想要的,在服务器上安装node_modules纯属胡闹。幸运的是,经过一番研究后,我终于解决了这个问题,本文就跟大家分享下我的实现思路与方案,欢迎各位感兴趣的开发者阅读本文。


场景概述


我们继续用文章“使用NestJS搭建服务端应用[1]”所创建的项目,以此为基础来描述这个问题,我们打开package.json文件,执行里面的build命令。


{
    "scripts": {
      "build": "nest build",
    }
}


一眨眼的功夫,它就打包好了,在你的项目根目录下会多出一个dist文件夹,如下如所示,这就是它所打包出来的文件。


640.png

                                image-20220217225521052


紧接着,我们把dist目录上传到服务器,用node来执行其目录下的main.js文件,上传文件至服务器后,我发现整个文件夹竟然只有18KB,我当时惊呆了,心想js这么牛的吗!开发出来的服务端应用包体积居然这么小,同样的功能使用Java实现,打包出来的jar包都50MB起步了!


640.png

                              image-20220217230347949


当我在服务器上运行时,我傻眼了,程序报错跑不起来🌚,这玩意儿不经夸啊。


640.png

定位问题


我怀着忐忑的心情打开dist的目录下的文件后,发现它只是简单的把ts编译成了js,并没有打包任何依赖包进去,他所有的依赖包都是从node_modules中引的。我们的服务器上是没有这些依赖包的,所以他就报错了。


640.png

                          image-20220217231732899


在搜索引擎上找了下解决方案,千篇一律的要在服务器上clone项目,然后在服务器上安装庞大的node_modules,简直是无稽之谈。


跟几个人交流后,他们说node项目本来就是这样啊,都是在服务器上安装依赖包的,这让我想起了好多年前看到的一个图,用在此处极为合适。


640.png

                                image-20220217232141650


解决方案


我是一个追求完美的人,这么庞大的一个开源库,设计者一定不会这么傻吧,这种低级问题应该早就考虑到了才对,既然网上找不到方案,那我就读一下它的源码吧。


皇天不负有心人,当我在查阅nest-cli源码的打包模块时,在@nestjs/cli/actions/build.action.js文件中发现了它有个配置变量webpack


640.png

                                image-20220218000128632


随后,我在nest的官方文档中,在nest-build[2]章节找到了这个配置项的相关内容,发现他可以在打包命令后面添加--webpack参数来生成单文件main.js。


640.png

                               image-20220218000919121


于是,我添加了这个参数,运行打包命令后,单文件是生成了,但是依赖文件依然没打包进去。出现这种情况那就只有一种可能了:nest-cli在打包时排除屏蔽了依赖包。


顺藤摸瓜,我在@nestjs/cli/lib/compiler/defaults/webpack-defaults.js发现了猫腻,如下图所示:


  • 它使用webpack-node-externals插件屏蔽了依赖的打包。


640.png

                             image-20220218001802693  


实现代码


经过上面的分析,我们定位到了问题所在,既然它默认屏蔽了依赖的打包,那我们就自己创建一个webpack.config.js文件,忽略掉externals以及一些nest提供的插件,这个问题就完美解决了,实现代码如下所示:


  • externals属性置为空,就忽略掉了默认的webpack-node-externals插件
  • 使用IgnorePlugin忽略掉了nest中的一些无用依赖包


/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
const webpack = require("webpack");
// fork-ts-checker-webpack-plugin需要单独安装
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
module.exports = {
  entry: "./src/main",
  target: "node",
  // 置为空即可忽略webpack-node-externals插件
  externals: {},
  // ts文件的处理
  module: {
    rules: [
      {
        test: /\.ts?$/,
        use: {
          loader: "ts-loader",
          options: { transpileOnly: true }
        },
        exclude: /node_modules/
      }
    ]
  },
  // 打包后的文件名称以及位置
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "dist")
  },
  resolve: {
    extensions: [".js", ".ts", ".json"]
  },
  plugins: [
    // 需要进行忽略的插件
    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()
  ]
};


⚠️注意:上述webpack配置文件要求package.json中webpack的版本号为^5.11.0",还需要安装fork-ts-checker-webpack-plugin依赖包到devDependencies中。


最后,我们修改打包命令为:


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


执行上述命令后,我们发现依赖包已经打入main.js了,文件体积也上升到了3.6mb


640.png

                                  image-20220218004017593


最后,我们用node来运行这个js文件,也没有了报错,顺利的跑起来了。


640.png

                            image-20220218004215022


我们再拿postman来测试下接口能否正常访问,如下所示,也都可以正常访问。


640.png

                                  image-20220218004354633


小tips:在服务器上运行node项目时,通常会使用pm2来执行。对此感兴趣的开发者,请自行了解。


示例代码


本文中所列举的完整代码请移步:


  • webpack.config.js[3]
  • package.json[4]


写在最后


至此,文章就分享完毕了。


我是神奇的程序员,一位前端开发工程师。


如果你对我感兴趣,请移步我的个人网站[5],进一步了解。

  • 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊
相关文章
|
移动开发 安全 JavaScript
uniapp打包成H5部署到服务器教程
uniapp打包成H5部署到服务器教程
1192 0
|
存储 资源调度 数据库
Vercel 部署 NestJS应用
Vercel 部署 NestJS应用
942 0
|
3月前
|
JavaScript
Nest.js 实战 (十一):配置热重载 HMR 给服务提提速
这篇文章介绍了Nest.js服务在应用程序引导过程中,TypeScript编译对效率的影响,以及如何通过使用webpackHMR来降低应用实例化的时间。文章包含具体教程,指导读者如何在项目中安装依赖包,并在根目录下新增webpack配置文件webpack-hmr.config.js来调整HMR相关的配置。最后,文章总结了如何通过自定义webpack配置来更好地控制HMR行为。
|
2月前
|
SQL 前端开发 JavaScript
Nest.js 实战 (十五):前后端分离项目部署的最佳实践
这篇文章介绍了如何使用现代前端框架Vue3和后端Node.js框架Nest.js实现的前后端分离架构的应用,并将其部署到生产环境。文章涵盖了准备阶段,包括云服务器的设置、1Panel面板的安装、数据库的安装、域名的实名认证和备案、SSL证书的申请。在部署Node服务环节,包括了Node.js环境的创建、数据库的配置、用户名和密码的设置、网站信息的填写、静态网站的部署、反向代理的配置以及可能遇到的常见问题。最后,作者总结了部署经验,并希望对读者有所帮助。
145 11
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的网络游戏公司官方平台附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的网络游戏公司官方平台附带文章和源代码部署视频讲解等
46 2
|
2月前
|
前端开发 JavaScript
轻松上手:基于single-spa构建qiankun微前端项目完整教程
轻松上手:基于single-spa构建qiankun微前端项目完整教程
44 0
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的创新型产品提前购平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的创新型产品提前购平台附带文章源码部署视频讲解等
27 2
|
6月前
|
前端开发 开发工具 git
[巨详细]使用HBuilder-X启动uniapp项目教程
【6月更文挑战第6天】使用HBuilder-X启动uniapp项目教程 先用HBuilder-X打开本地的uniapp项目
654 0
|
Web App开发 前端开发 JavaScript
用electron打包前端应用初体验
用electron打包开发桌面应用遇到的各种问题和解决办法
207 1
|
JSON 前端开发 JavaScript
前端常用插件(自用)
前端常用插件(自用)
175 0
下一篇
无影云桌面