项目中使用了Nestjs,开发过程总体来说比较顺利,没有遇到大的挫折。
但是在开发完一些功能,想要将其部署到生产环境时,却遇到了不少问题,在此记录一下。
一、背景
先说一下背景,由于一些原因,我们生产环境的主机都无法连接外网,所以一些常用的命令,比如yum\npm install 等命令都无法在生产环境的主机使用。
此外,目前项目使用的是Docker环境,这就要求我们所有的代码都要打包到Docker镜像中才可以运行。
如果每次更新代码都要手动打镜像的话,会比较麻烦,因此我们利用jenkins搭建了一套自动构建的环境。
这样每次代码合并到主分支的时候,系统就会自动构建出一套测试环境的镜像,并且自动发布到测试环境。
以上为背景。
二、要求
在上面的背景条件要求下,其实我最希望的是nestjs能够提供一种类似java 打包的方式,能够自动将所有依赖项打包到一个目录中,而且没有环境依赖、跨平台、可移植。
这样我们就可以很方便的将文件打包成Docker镜像。
但是通过查阅文档,发现nestjs本身并不能提供这样的打包方式。
因此我只能自己探索尝试。
三、尝试
1、webpack方式
我首先想到的是webpack,通过webpack自动处理依赖,从而将整个项目打包到一个或多个文件中。
nestjs 官方也提供了一个类似的例子:https://github.com/ZenSoftware/bundled-nest
但是,这种方式下,webpack无法处理nestjs一些懒加载的包,打包过程中会出现找不到包的错误,因此需要手动将nestjs懒加载的包忽略掉。
此时webpack.config.js如下 :
const path = require('path'); const webpack = require('webpack'); const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); const { NODE_ENV = 'production' } = process.env; console.log(`-- Webpack <${NODE_ENV}> build --`); module.exports = { entry: './src/main.ts', mode: NODE_ENV, target: 'node', plugins: [ new webpack.IgnorePlugin({ /** * There is a small problem with Nest's idea of lazy require() calls, * Webpack tries to load these lazy imports that you may not be using, * so we must explicitly handle the issue. * Refer to: https://github.com/nestjs/nest/issues/1706 */ checkResource(resource) { const lazyImports = [ '@nestjs/microservices', '@nestjs/platform-express', 'cache-manager', 'class-validator', 'class-transformer', ]; if (!lazyImports.includes(resource)) { return false; } try { require.resolve(resource); } catch (err) { return true; } return false; }, }), ], output: { path: path.resolve(__dirname, 'dist'), filename: 'main.js', }, resolve: { extensions: ['.ts', '.js'], plugins: [new TsconfigPathsPlugin({ configFile: './tsconfig.build.json' })], }, module: { rules: [{ test: /\.ts$/, loader: 'ts-loader' }], }, stats: { // This is optional, but it hides noisey warnings warningsFilter: [ 'node_modules/express/lib/view.js', 'node_modules/@nestjs/common/utils/load-package.util.js', 'node_modules/@nestjs/core/helpers/load-adapter.js', 'node_modules/optional/optional.js', warning => false, ], }, };
这种方法确实会将项目所有依赖文件全部打包入一个文件,是我们最希望的一种方式,但我们在实际测试中,却出现了一些无法解析function的错误,而且无法调试,遂放弃。
2、pkg 方式
这种方式也非常符合我们的需求,但在打包的过程中不断出现各种各样的问题,处理的心累,于是也放弃了。
3、nest build 方式打包,然后手动拷贝node_module文件
最终,我们还是选择了最笨的方式,通过nest build的方式编译整个项目,然后手动将node_module目录拷贝到打镜像的主机。
这样虽然麻烦了一些,但好在有jenkins的帮助,这些操作都会自动完成,我们只要关注代码本身就可以了。
但是我个人还是比较倾向于上面两种方式,以后如果有时间的话,我会继续尝试解决一下那些错误,但是目前最重要的还是让服务尽早上线。
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助