使用rollup构建library的一次尝试
Closed this issue · 0 comments
使用rollup构建library的一次尝试
因为在设计博客和CMS的时候,有一个设想就是在CMS里去编辑md,同时实时预览,这个预览和实际提交在博客上展示要求完全一致。所以就想着自己弄一个预览模块,在两个项目之前共享代码。这就涉及到一个Markdown Preview的工具。这个工具其实就是从MD => HTML,使用highlight.js做代码高亮,一些自定义的配置和样式文件,然后打包成一个js包。
这个打包环节其实是想用webpack打一个umd的包就得了,但是一直知道有个rollup的工具存在,非常轻量,同时Vue.js也是通过rollup打包的,所以就想做出一次尝试。以下是阅读文档,结合awesome rollup仓库总结的一些经验。
同时本文只会涉及到一些rollup相关的,关于markdown处理会再开一篇文章记录。
起步
package.json
{
"name": "my-package",
"version": "0.1.0",
"main": "dist/my-package.js"
}
通常,包内的package.json通常用有一个叫main的属性,他说明的是本包的内容是在dist/my-package.js
中。
像Webpack, Browserify之类的bundler会解析这个main, 然后引入main属性对应的js,同时根据dependencies去载入相应依赖。
在第三方打包时一般都会优先选用umd的包,因为这样浏览器也可以使用,所以一般第三方的lib的main属性通常都是umd的包。
而rollup属于ES2015-aware的工具,在rollup内使用CJS或者UMD并不是最理想的情况,因为无法使用ES6 module的特性。
如果对方在使用rollup作为他的bundler, 而也说了rollup属于ES2015-aware的工具,他会优先读取package.json里的module属性,如果没有,才会读main属性,这样既可以保证一般bundler可以正常解析文件,同时在使用rollup的时候会优先读取module里的es包。
所以package.json就会变成:
{
"name": "my-package",
"version": "0.1.0",
"main": "dist/my-package.umd.js",
"module": "dist/my-package.esm.js"
}
这对于打出的包来说属于双赢。
具体可以查看官方对于这种做法的解释
配置文件
rollup的配置文件可以使用es6语法编写
使用-c来指定config文件,默认读取根目录下rollup.config.js
rollup -c
rollup --config
rollup -c build/rollup.config.js
这里也放出我用的配置文件
import resolve from '@rollup/plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'
import pkg from './package.json'
import dev from 'rollup-plugin-dev'
import postcss from 'rollup-plugin-postcss'
import { string } from "rollup-plugin-string"
import { terser } from 'rollup-plugin-terser'
const devServerConfig = {
port: 3000
}
const plugins = function (format) {
const commonPlugins = [
dev(devServerConfig),
postcss({
extract: false
}),
string({
include: "**/*.md",
}),
terser()
]
if (format === 'umd') {
return [
...commonPlugins,
resolve(),
commonjs(),
]
} else {
return commonPlugins
}
}
export default [
// for browser
{
input: 'src/index.js',
output: {
name: 'MarkdownPreview',
file: pkg.browser,
format: 'umd'
},
plugins: plugins('umd')
},
// for cjs and esm
{
input: 'src/index.js',
external: Object.keys(pkg.dependencies),
output: [
{file: pkg.main, format: 'cjs'},
{file: pkg.module, format: 'es'},
],
plugins: plugins()
}
]
常用依赖
- rollup-plugin-commonjs
支持解析commonjs包至es6 module - @rollup/plugin-node-resolve
支持解析node_modules里的包 之前的包rollup-plugin-node-resolve已经archive了且不再维护 - rollup-plugin-vue
- rollup-plugin-jsx
- rollup-plugin-md
- rollup-plugin-terser
- rollup-plugin-string
坑
- rollup-plugin-uglify
因为之前没有用过terser作为minify的工具,所以选择了rollup-plugin-uglify
打包esm的时候竟然不支持es6语法。terser官方也说了这个问题,
Why choose terser?
uglify-es is no longer maintained and uglify-js does not support ES6+.
terser is a fork of uglify-es that mostly retains API and CLI compatibility with uglify-es and uglify-js@3.
所以使用rollup-plugin-terser作为minify工具。