2022 年 06 月 23 日
缘起
需要提供一个JavaScript的 SDK, 当然我们使用
webpack
可也以构建; ps(对于现代浏览器来说 webpack 打包体积 其实都不算事) 主要是Rollup
配置文件全面 ESM,配置简介,对于爱干净的我来说比较喜爱
Rollup
Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。Rollup 对代码模块使用新的标准化格式,这些标准都包含在 JavaScript 的 ES6 版本中,而不是以前的特殊解决方案,如 CommonJS 和 AMD。ES6 模块可以使你自由、无缝地使用你最喜爱的 library 中那些最有用独立函数,而你的项目不必携带其他未使用的代码。ES6 模块最终还是要由浏览器原生实现,但当前 Rollup 可以使你提前体验。
Flow 👇🏻
- 打包构建
- 加载 额外资源 ( resolve )
- 转译 ES module
- Babel
- 输出 压缩、移除 console 等
- 发布脚本
本文旨在 Rollup 的构建过程介绍,和业务无关
install 化环境依赖
yarn add -D rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve
-
rollup
-
@rollup/plugin-commonjs // 转译
-
@rollup/plugin-node-resolve // 加载依赖
rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel'; // 转换babel
import { terser } from 'rollup-plugin-terser' // 压缩代码
import pkg from './package.json';
export default [
{
input: 'src/index.js',
external: ['ms'],
output: [
{ file: `${process.cwd()}/dist/cjs/index.js`, format: 'cjs' },
{ file: `${process.cwd()}/dist/esm/index.js`, format: 'esm' },
{ file: `${process.cwd()}/dist/index.js`, format: 'umd', name: pkg.name },
],
plugins: [
resolve(), // so Rollup can find `ms`
commonjs(), // so Rollup can convert `ms` to an ES module
babel({
babelHelpers: 'runtime', //
exclude: 'node_modules/**' // 排除 node_modules
}),
terser({
output: {
ascii_only: true // 仅输出ascii字符
},
compress: {
pure_funcs: ['console.log'] // 去掉console.log函数
}
}),
]
}
];
external & resolve
我们开发SDK的不可能全然自己 造轮子,也会使用其他一些依赖
external : 申明外部依赖
例如:🌰
{
external: ['lodash']
resolve()
}
output
输出 目录和文件名
输出了 三个文件 分别是:
- cjs:Commonjs 规范
- esm: ESmodule 规范
- umd: 集 CommonJs、CMD、AMD 的规范于一身
terser
压缩代码、移除console
TypeScript
-
更改
src/index.js
=>index.ts
-
安装依赖
yarn add -D @rollup/plugin-typescript typescript
- 增加配置文件
tsconfig.json
{
"compilerOptions": {
"jsx": "preserve",
"jsxFactory": "VueTsxSupport",
"target": "esnext",
"module": "esnext",
"strict": true,
"importHelpers": true,
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"experimentalDecorators": true
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.d.ts",
],
"exclude": ["node_modules", "dist", "scripts"],
}
rollup.config.js
...
import ts from '@rollup/plugin-typescript';
// ts
const tsPlugin = ts({
tsconfig: getPath('./tsconfig.json'), // 导入本地ts配置
exclude: 'node_modules/**',
});
export default [
{
input: 'src/index.ts',
external: ['ms'],
output: [
{ file: `${process.cwd()}/dist/cjs/index.js`, format: 'cjs' },
{ file: `${process.cwd()}/dist/esm/index.js`, format: 'esm' },
{ file: `${process.cwd()}/dist/index.js`, format: 'umd', name: pkg.name },
],
plugins: [
...
tsPlugin,
],
},
];
...
package.json
"types": "src/index.d.ts",
ESLint
ESlint 还要安装 支持 TS 的插件
- 安装依赖
yarn add -D @rollup/plugin-eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-prettier eslint-plugin-prettier
rollup.config.js
...
import eslint from '@rollup/plugin-eslint'; // eslint
// eslint
const esPlugin = eslint({
throwOnError: true,
include: ['src/**/*.ts'],
exclude: ['node_modules/**'],
});
export default [
{
...
plugins: [
...
tsPlugin,
],
},
];
.eslintrc.js
module.exports = {
env: {
browser: true,
node: true,
amd: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
parserOptions: {
ecmaVersion: 2015,
sourceType: 'module',
},
plugins: ['@typescript-eslint', 'prettier'],
rules: {
'prettier/prettier': 'warn',
},
};
.eslintignore
dist/*.js
config/*.js
scripts/*.js
test/*.js
.prettierrc
{
"singleQuote": true,
"trailingComma": "all",
"endOfLine": "auto",
"printWidth": 100,
"proseWrap": "never",
"arrowParens": "avoid",
"htmlWhitespaceSensitivity": "ignore",
"overrides": [
{
"files": ".prettierrc.js",
"options": {
"parser": "json"
}
}
]
}
package.json
添加脚本
"lint": "eslint --ext .js,.ts src",
"format": "eslint --ext .js,.ts src --fix",
Publish Script
SDK 发布到 NPM 、 PNPM 或者 私有 npm 等
直接上代码 简单版
- 把
package.json
andREADME
copy 到dist
下面 - 修改版本
- 发布
我这里省略了 版本修改,因为 每次通过 process.argv 来指定版本 不如直接修改 package.json
const path = require('path');
const shelljs = require('shelljs');
const program = require('commander');
const { copyFile } = require('fs');
const colors = require('colors');
const copyFunc = () => {
copyFile(`${process.cwd()}/package.json`, `${process.cwd()}/dist/package.json`, (err) => {
if (err) {
console.log(`copy package 失败 \n ${err}`)
}
})
copyFile(`${process.cwd()}/README.md`, `${process.cwd()}/dist/README.md`, (err) => {
if (err) {
console.log(`copy README 失败 \n ${err}`)
}
})
}
const pubFunc = () => {
copyFunc()
shelljs.cd('dist');
shelljs.exec('npm publish'); // 发布
}
pubFunc()
发布
-
yarn adduser --registry http://xxx
or
-
yarn login login
-
yarn publish