让你的 Node 项目瘦身
发布于 6 个月前 作者 tmirun 1294 次浏览 来自 分享

很多刚刚入门的同学都被 node 项目体积给吓到,拉几个依赖包包项目立马 上百个 MB。 往往你只需要一个轮子的时候 npm 给你拉了 “一辆马车”(一大坨依赖包)

但这个缺点可以解决!

现在大多数依赖包现在都模块化了 打个比方 lodash:

// Load the full build.
var _ = require('lodash');
// Load the core build.
var _ = require('lodash/core');
// Load the FP build for immutable auto-curried iteratee-first data-last methods.
var fp = require('lodash/fp');
 
// Load method categories.
var array = require('lodash/array');
var object = require('lodash/fp/object');

解决方案1:

用 webpack 打包!具体思路就是 把 lodash 这样可以打包的库加到 devDependency,把不能打包的 mysql2 这样的库添加到 dependency 里。最后在 webpack 打包的时候和他说忽略 dependency 里这些不能的库。

现在把你打包好的 项目(index.js)和 package.json 上传到服务器。服务器只会安装 package.json dependency 的库。体积最少可以减 50%。

webpack config.json

const nodeExternals = require('webpack-node-externals');
commonConfig = {
  ... // 其他代码
  target: 'node', // in order to ignore built-in modules like path, fs, etc.
  externals: [nodeExternals()], // 忽略在 package.json dependency 的模块
};
module.exports = commonConfig;

package.json

{
  "devDependencies": {
    // 可以打包的依赖包
    lodash
  },
  "dependencies": {
    // 不 可以打包的依赖包
    mysql2
  },
}

解决方案2:

用比如 zeit/ncc 这些node 打包📦工具

有更多的方法欢迎留言!

原文: Node-项目瘦身

12 回复

devDependency 和 dependency 弄反了吧

@Ander456 @im-here 我能懂你们的疑问,最初我也是这么认为的,但后面发现 devDependency 添加你要打包的 和 dependency 里面添加你不要打包的是正确的。因为很多时候 devDependency 我们会添加测试用的依赖包。这些包包我们在上传到服务器的时候是不希望 npm install 的。

所以在这里我们会把 我们可以 用 webpack 压缩打包的库都加入到 devDependency 里面。这样上传的时候 npm install 只会拉我们 dependency 里面不能打包的依赖包

@tmirun 赞同,我的理解是devDep放的是构建时或者测试等依赖,而dep放的是运行时的依赖,当然这是前后端同属一个工程并共享package.json的场景。在CI/CD中采用npm install后执行构建,之后docker镜像构建时COPY后采用npm install --production减少镜像大小。

还有个简单的瘦身法就是如果是采用docker方式部署的话,母镜像采用-alpine、-slim或者再次封装,镜像大小会小很多

@CaanDoll 这个方法还没试过,可以研究研究

不过真正用的时候,我也不想把devDependency里的测试库打包进webpack,这就需要配置webpack了

@tmirun 对这块不是很熟悉,只提出我的疑问,有不对的地方还请谅解 1.对于前端项目,不应该都是直接在本地打包好了之后在发布到服务器吗?为什么还要在服务器上npm install? 2.如果是基于node的后端项目,那应该不用打包了吧? 3.假如一个基于vue.js的项目,开发的时候用到了一些实际生产环境不需要的库,那如果你把它们打包进去了,那实际上前端加载的内容不就变大了吗?

@kzfile 你要想,只要你的 main.js 的文件不调用那些测试库,就不会被打包进去 打个比方:

  • main.js 你的主要文件
  • test.js 你的测试文件

打包上传到服务器的时候 webpack 只打包 main.js 和他的依赖包

我没用过webpack,我感觉的楼主说的不太对,难道动态require的就不能打包进去了吗?

[CNodeMD]

@im-here node 服务器正常流程是 上传项目,到服务器后自动启动 npm install 下载依赖包 最后 启动 npm start。

很多时候 npm install 动不动就下载 600mb 的依赖包,而且很多依赖包 我们只需要里面的一个小轮子,所以对这些依赖包 最好方法就是打包。

但node不像前端所有都可以打包,特别是那些里面有驱动文件或者 c++ 代码的依赖包 ,比如 mysql2

webpack 打包上传到服务器的时候只打包📦 main.js 和他的依赖包。如果你没调用到就不会吧不用的依赖包也加进去

希望这能让你对 node 更熟悉一点 = )

@dbit-xia webpack 打包主要看 动态 require 是在 devDependency 里面还是 dependency 里面

回到顶部