之前我写了篇文章使用npm发布自己的第一个包,目前存在两个问题,先看一下我们的包上传到 npm 上是怎样的结构:
可以看到上传到 npm 的包和我们的本地目录结构是一样的,这也并不奇怪,因为我使用的就是最简单的npm init -y生成的配置文件,并没有做什么额外的配置项,所以自然是我本地代码是什么样的,上传到 npm 上就是什么样,这样看起来是没有什么问题,但仔细观察就会发现有这么几个问题:
.vscode文件也上传到npm上了,我们其实不希望将vscode的配置文件上传上去,这并没有什么用。此外很多时候我们的代码内可能不是全部内容都上传到npm上的,我们只需要和包有关的代码上传到npm上。- 目前上传的代码是未经压缩的,是源码直出的,可以看到目前包的总体积在 864B, 这在包小的时候没什么问题,但是如果日后代码逐渐增多,包的体积也会递增,这势必会增加实际项目的大小,而这些额外增加的大小,本来是可以通过压缩代码来实现的。而且我们实际上也不需要在
npm上查看它的源码,毕竟 npm 不是源代码管理工具,它注重的是使用。
所以针对上述两个问题,本文将通过增加 npm 的一系列配置以及引入rollup来打包我们的包解决上述问题,下面开始正文:
使用 .npmignore忽略 .vscode 文件夹
- 在项目的根目录下创建一个
.npmignore文件。 - 在文件中添加以下内容以屏蔽
.vscode文件夹
.vscode
然后我们重新发布测试下,查看结果:
此时我们就看到上传到 npm 上的包就不含.vscode了,而且包的体积也减少了近 100B
补充说明
如果使用 git来管理代码,那么npm 默认会使用 .gitignore 文件。在 .gitignore 中添加即可。如果有了.gitignore,.npmignore 文件会覆盖 .gitignore 的行为。
下面解决第二个问题,不过在开始之前,我们需要先知道 rollup是什么?
rollup 是什么
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。
这是官方文档对 rollup 的概括,简单总结一下:
rollup 是使用ES模块(es moudle)语法打包JavaScript模块的工具,所谓的JavaScript模块打包工具,意思就是将使用 ES 模块(使用 exportd 导出和 import 导入)编写的代码编译成其它模块类型的代码(比如UMD 或 CommonJS 格式),以使得你的代码可以在各种不同的 JavaScript 环境运行。
举例来说,就拿我们的fengdu-utils包来说,它是使用 ES 模块写的,很明显它不能直接在浏览器里使用,没有办法通过 script 引入,它只能在工程化的项目内使用。
此外 rollup 还可以在编译的过程中,使用一系列插件来对源代码进一步处理,就比如说压缩代码,而这也是我们主要想使用的,话不多说我们直接开始实践。
rollup 安装
将rollup安装为开发依赖
npm i rollup -D
创建rollup配置文件rollup.config.js,这里我们需要通过input来指定打包的入口文件,以及output指定输出的文件,我希望最后打包的文件放到dist目录下:
export default {
input: 'index.js',
output: {
file: 'dist/index.js'
}
}
我们配置一个 scripts 命令来快速运行 rollup 打包命令
"scripts": {
+ "build": "rollup -c"
}
这样我们就可以直接通过npm run build来执行rollup打包了,运行后发现报错:
> rollup -c
src/index.js → dist/index.js...
(node:5593) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///Users/wanko/project/fengdu-utils/rollup.config.js is not specified and it doesn't parse as CommonJS.
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
To eliminate this warning, add "type": "module" to /Users/wanko/project/fengdu-utils/package.json.
(Use `node --trace-warnings ...` to show where the warning was created)
[!] RollupError: Could not resolve entry module "src/index.js".
这是因为 Rollup 的配置文件被检测为 ESM 模块(通过 export default 或 import 语法),而Node.js 默认将文件解析为 CommonJS 模块,所以我们需要在package.json中添加 "type": "module",明确声明项目使用 ESM 模块格式:
{
"type": "module"
}
如果不想使用 ESM,可以将 Rollup 配置文件改为 CommonJS 格式,使用 module.exports 和 require:
module.exports = {
input: 'index.js',
output: {
file: 'dist/index.js'
}
}
此时再打包可以看到打包后dist目录输出的index.js文件:
我们可以看到打包后的代码,其实就是将 ES6 转为了 ES5,然后将原来不同模块的代码组合到了一个文件中,代码都是原样不变,连注释都在。
很明显这样还是不能减少包的体积,想要减少包体积,我们还需要使用rollup的压缩插件terser,它可以对打包后的文件进行压缩,包括移除 console,移除注释, 从而减少文件体积。专于生产环境的代码优化。
安装压缩插件
npm install rollup-plugin-terser -D
我们再执行 rollup 打包命令,查看 dist
可以看到压缩后就只剩下几行代码,那么我们只需要上传这个文件到 npm 上就可以极大的减少我们的包体积,具体怎么做,请继续往下看。
指定 npm 要上传的文件
我们需要在package.json中做两件事情:
- 增加
files字段,files 字段为一个数组,设置后 npm 将只会上传指定目录或文件夹下的文件到 npm。 - 修改
main字段,因为我们只上传了dist目录到 npm,原来的设置的根目录下index.js为入口文件就不再对了,需要改为dist/index.js
完整 package.json配置
{
"name": "fengdu-utils",
"version": "1.0.3",
"main": "dist/index.js",
"files": [
"dist"
],
"scripts": {
"build": "rollup -c"
},
"type": "module",
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@rollup/plugin-terser": "^0.4.4",
"rollup": "^4.29.1"
}
}
发布到 npm 上后我们查看 npm 的包结构:
可以看到只有dist目录被上传了,最后打包后的文件体积只有327B,比之前小了一半还多。
总结
通过使用rollup来打包 npm 包,不仅使得 npm 的包结构精简,减少了冗余代码的上传,还减少了包的体积。
如果学会了就赶快去行动吧。