Open gogoend opened 4 years ago
有关Anikyu的相关内容,可参考封装Anikyu时写的文章:尝试通过封装一个库(Anikyu)来学习JavaScript(ES6)相关特性以及相关构建工具,本文操作步骤基于v1.0.1 版本。
首先,打开package.json
看一下旧版本中相关开发依赖:
"@babel/cli": "^7.8.3",
"@babel/core": "^7.8.3",
"@babel/polyfill": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@purtuga/esm-webpack-plugin": "^1.2.1",
"babel-loader": "^8.0.6",
"clean-webpack-plugin": "^3.0.0",
"eslint": "^6.8.0",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
在此,Webpack相关依赖已经不再有用,可以直接删除,仅保留Babel与ESLint,然后再加入Rollup的相关依赖。
"@babel/cli": "^7.8.3",
"@babel/core": "^7.8.3",
"@babel/polyfill": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"eslint": "^6.8.0",
"@rollup/plugin-babel": "^5.1.0",
"@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-node-resolve": "^8.4.0",
"rollup": "^2.22.0",
"rollup-plugin-terser": "^6.1.0"
此处可以了解一下与Rollup相关的依赖的作用:
require
等语法原样保留,而浏览器原生不支持这种语法,因此需要对这种语法进行转换。然后,需要更改package.json
上方scripts
中的build
脚本。由于Webpack已经不再使用,因此把脚本从原先的webpack-cli
替换为rollup -c
。
修改后如果我们迫不及待执行构建命令:
将会提示“找不到入口模块rollup.config.js”。
在这里,rollup.config.js
的角色和webpack.config.js
是一致的,都是打包工具的配置文件。
同时,我们来看一下旧版本中的Webpack配置文件webpack.config.js 。在配置的输出中,包含四个版本的Anikyu。 |
版本 | UMD | ESM |
---|---|---|---|
未压缩 | anikyu.js | anikyu.esm.js | |
已压缩 | anikyu.min.js | anikyu.esm.min.js |
UMD版本用于老旧浏览器,通过script
标签src属性引入;而ESM版本用于支持ES Module的浏览器,通过import
语句引入。
我们迁移的最终目标,就是在保留Anikyu功能,不改动Anikyu库内部原有代码基础上,输出同样的这四种文件。
webpack.config.js
可以先保留,之后可以参考这个文件进行输出配置(当然此时该文件也没用了,如果记下来相关输出配置,可以直接删除)。
接下来在项目根目录下新建rollup.config.js
文件,内容如下:
import babel from '@rollup/plugin-babel';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import { terser } from "rollup-plugin-terser";
export default {
input: './src/anikyu.js',
output: [{
file: `./dist/anikyu.js`,
name: `Anikyu`,
format: 'umd'
},
{
file: `./dist/anikyu.min.js`,
name: `Anikyu`,
format: 'umd',
plugins:[
terser()
]
},
{
file: `./dist/anikyu.esm.js`,
format: 'es'
},
{
file: `./dist/anikyu.esm.min.js`,
format: 'es',
plugins:[
terser()
]
}],
plugins: [
commonjs({
extensions: ['.js'],
ignoreGlobal: false,
sourceMap: false,
}),
resolve({
browser:true
}),
babel({
exclude: 'node_modules/**'
})
]
};
这里的相关配置参考自Three.js的构建配置文件下方有关输出的章节。(其中的某些参数配置笔者暂未仔细了解🌚)
此时若我们再执行npm run build
,即可生成使用Rollup进行打包后的最终文件。这里产生了四个文件,分别对应上文所述的四个版本。
最终产生的diff变化可见:Pull Request。
至此,Anikyu项目由Webpack构建到Rollup的构建便成功完成。 从文件体积上看,Rollup打包出来的版本显然更小一些。
其实将Anikyu的构建工具迁移到Rollup是我一直都在尝试做的事情,今年四月就准备做,但由于当月太忙,就一直忘了,直到最近突然想起,便进行了一波尝试。 之前看了慕课网发布在知乎上的文章,遂一步步跟着做了下来,很完美。但后面发现文章里用到的Babel与Rollup版本其实是很早以前、已被deprecated的版本了;于是便研究如何从老版本升级到新版本,无奈中间总有一步过不去。(见:99fe673ad6a8d06848558a72d6717385a0edbc27) 这一版本的依赖包括:
"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/plugin-external-helpers": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.0.0",
"@rollup/plugin-babel": "^5.1.0",
"@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-node-resolve": "^8.4.0",
"babel-eslint": "^10.0.1",
"babel-preset-env": "^1.7.0",
"eslint": "^6.8.0",
"rollup": "^2.22.0"
}
这一版本Rollup及Babel的配置如下:
import resolve from '@rollup/plugin-node-resolve';
import babel from '@rollup/plugin-babel';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: './src/anikyu.js',
output: [{
file: `./dist/anikyu.js`,
name: `Anikyu`,
format: 'umd'
}, {
file: `./dist/anikyu.esm.js`,
format: 'es'
}],
plugins: [
resolve(),
commonjs({
extensions: ['.js'],
ignoreGlobal: false,
sourceMap: false,
}),
babel({
exclude: 'node_modules/**',
babelHelpers: 'runtime',
"presets": [
[
"env",
{
"modules": false,
"targets": {
// The % refers to the global coverage of users from browserslist
"browsers": [">0.25%", "not ie 11", "not op_mini all"]
}
}
]
],
"plugins": [
"@babel/plugin-external-helpers",
[
"@babel/plugin-transform-runtime",
{
corejs: 3
}
]
]
})
]
};
这一版中打出来的包里不包含polyfill,并且打包时提示了一些错误,之前查各种资料,一无所获:
Trace: The node type RestProperty has been renamed to RestElement
问题产生原因:
babel-preset-env": "^1.7.0
依赖的版本过于古老。此处替换为较新的@babel/preset-env": "^7.0.0
依赖,同时在Babel的配置中,presets下的"env"
应当替换为"@babel/preset-env"
。重新安装依赖后,问题即可解决。
(!) Unresolved dependencies 问题产生的原因:
"useBuiltIns": "usage"
;若没有这条配置,@babel/polyfill也不会被打包。2
。
@rollup/plugin-node-resolve
,并在插件中调用。
若打包后,在低版本浏览器下,某些代码依然报错,则尝试修改Babel将要编译到的目标浏览器。(!) Missing global variable names 当上一个问题解决后,这个错就不会再报了。
今天居然成功解决!真的很意外,值得庆祝一下。
之前封Anikyu库的时候,主要是参考使用vue-cli脚手架构建应用程序的相关配置来进行的,因此之前的构建工具使用的是Webpack。但经过笔者的一些了解,很多库(例如,ECharts、Vue.js、Three.js)的构建工具并非Webpack,而是Rollup。当然也有部分库(例如,Axios)的构建工具使用的是Webpack。事实上,就在早前,Vue.js曾放出了Vue.js 3.0的相关消息,未来的项目将可能会使用一款名为Vite的工具来进行打包,而它基于的打包工具便是Rollup。
经过本人测试,相对使用Webpack打包的库而言,使用Rollup打包的库,冗余代码看起来更少一些。
下方分别是Axios和Vue两个库UMD包未压缩代码。
Axios
Vue
参考资料
10分钟快速入门rollup.js - 知乎 你还没有撸一个包扔到npm上? - 知乎