本文已参与「新人创作礼」活动,一起开启掘金创作之路。
——Bug修复员-鲁宽宽
前言
阅读过上篇(手把手教你设计npm包-系列一 )的伙伴应该可以想到此篇主要内容是什么,那就是如何使用Rollup来构建源码。
此篇会详细(有点长)介绍每一步的配置及相关依赖,若只想看整体效果,可以访问源码地址。
实现能力主要有:
- 输出多端运行源码
- 支持ts
- 支持按需加载
构建工具配置
初始化项目
npm init
// 项目目录
|- src
|- index.js
|- package.json
// package
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
// index.js
const test = () => {
return true
}
export default test
安装rollup
npm install rollup -D
// 项目目录
|- build
|- rollup
|-rollup.config.prod.js
|- src
|- index.js
|- package.json
// pageage 修改
{
"scripts": {
"build": "rollup -c build/rollup/rollup.config.prod.js",
}
}
配置rollup,支持导出esm、umd、cjs类型。
export default {
input: 'src/index.js',
output: [
{
file: `lib/index.esm.js`,
format: 'esm'
},
{
file: `lib/index.umd.js`,
format: 'umd',
name: 'JSUTILS'
},
{
file: 'lib/index.cjs.js',
format: 'cjs'
}
],
external: ['fs']
}
初次尝试npm run build,提示构建成功,还挺简单。不过检查构建后代码,会发现ES6的属性没有被转换为ES5,接下来就使用babel重新构建下。
安装babel
npm install @babel/core @babel/preset-env -D
npm install core-js
运行会报错,提示需要安装rollup的babel插件。安装rollup插件:
npm install @rollup/plugin-babel -D
此时的配置如下:
// 项目目录
|- build
|- rollup
|-rollup.config.prod.js // 修改
|- src
|- index.js
|- package.json
|- .babelrc // 修改
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"useBuiltIns": "usage",
"corejs": "3.8"
}
]
]
}
// rollup.config.prod.js
import { babel } from '@rollup/plugin-babel'
export default {
input: 'src/index.js',
output: [...],
external: ['fs'],
plugins: [
babel(
{
babelHelpers: 'bundled',
extensions: ['.js', '.ts'],
exclude: 'node_modules/**'
}
)
]
}
再次运行发现是ok的,不过我们尝试使用Promise功能,发现构建后的文件含有以下代码:
// index.esm.js
import 'core-js/modules/es.object.to-string.js';
import 'core-js/modules/es.promise.js';
造成这个原因是因为rollup本身不会对依赖包进行额外的解析,但若要输出一个独立的包,是需要解决这个问题的,很简单,只需要添加rollup相应插件就可以了。
配置rollup插件
npm install @rollup/plugin-node-resolve @rollup/plugin-commonjs -D
这两个包可以对node_modules依赖及commonjs语法进行解析。详细配置:
// rollup.config.prod.js
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
export default {
input: 'src/index.js',
output: [...],
external: ['fs'],
plugins: [
babel(...),
nodeResolve({
preferBuiltins: false
}),
commonjs(
{
sourceMap: false
}
)
]
}
配置完成并运行后,查看源码发现多了许多并不熟悉的代码,这些就是支持新属性(promise)的代码。
到了这里基本已经结束,下面再讲讲如何配置ts。
配置Ts
npm install typescript rollup-plugin-typescript2 @babel/preset-typescript -D
修改相关配置
// 项目目录
|- build
|- rollup
|-rollup.config.prod.js // 修改
|- src
|- index.js
|- package.json
|- .babelrc // 修改
|- tsconfig.json // 新增
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"isolatedModules": true,
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": false,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"removeComments": true,
"declaration": true,
"noImplicitAny": false,
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "lib/**/*.ts", "lib/**/*.d.ts"],
"references": []
}
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"useBuiltIns": "usage",
"corejs": "3.8"
}
],
"@babel/preset-typescript" // 新增
]
}
// rollup.config.prod.js
...
import typescript from 'rollup-plugin-typescript2'
const getPath = _path => path.resolve(__dirname, _path)
export default {
input: 'src/index.js',
output: [...],
external: ['fs'],
plugins: [
...,
typescript({
tsconfig: getPath('../../tsconfig.json'), // 导入本地ts配置
extensions: ['.js', '.ts']
}),
]
}
配置完成后,可以支持Ts的编写,并在构建时,输出相应的ts声明文件。这样在使用此包方法时可以给出友好提示(记得改package)。如下:
{
"main": "lib/index.cjs.js",
"module": "lib/index.esm.js",
"typings": "lib/index.d.ts", // 配置相应的输出路径
}
结语
详细代码参考:源码地址
这份配置建议作为学习的参考或者内部使用。因为它不是最优的实现,比如并未接入eslint、单元测试等,故不适合一些复杂(开源、严谨)的项目。
若是大家有较优的方案,也可以将地址留在评论区,让我们一同学习参考~
获取知识、沉淀总结、分享经验,很美妙的过程。