下雪了,在家闲着,不如写一个npm 包发布。简单的 npm 包的发布网上有不少教程,我就不记录了。这里记录下,一个复杂的 npm 包发布,复杂指的构建环境复杂。javascript
整个工程使用 rollup 来构建,其中会引进 babel 来转译 ES6,利用 Eslint 来规范代码的书写风格,最后代码的发布会通过 terser 压缩。同时发布 umd、es 格式的版本以供外部调用。java
完整目录结构以下:node
下面是整个过程的记录shell
1、初始化工程npm
yarn init -y
初始化后,修改 package.json 内容,如 name(项目名),description(项目描述)等信息。json
2、安装 rollupbabel
yarn add rollup@1.0.0 --dev
3、建立配置文件 rollup.config.jsui
export default { input: 'src/index.js', output: { file: 'index.common.js', format: 'umd', name: 'index' } }
4、安装 babelspa
yarn add rollup-plugin-babel@4.2.0 @babel/core@7.2.2 @babel/preset-env@7.2.3 --dev
5、配置 babel插件
一、建立配置文件 .babelrc
{ "presets": [ [ "@babel/preset-env", { "modules": false } ] ] }
二、与 rollup 集成,在 rollup.config.js 中配置 plugins
import babel from 'rollup-plugin-babel' export default { input: 'src/index.js', output: { file: 'index.common.js', format: 'umd', name: 'index' }, plugins: [ babel({ exclude: 'node_modules/**', runtimeHelpers: true }) ] }
6、安装 eslint
yarn add eslint@5.11.1
7、配置 eslint
一、生成 eslint 配置
.\node_modules\.bin\eslint --init
二、与 rollup 集成,在 rollup.config.js 中配置 plugins
import babel from 'rollup-plugin-babel' import { eslint } from 'rollup-plugin-eslint' export default { input: 'src/index.js', output: { file: 'index.common.js', format: 'umd', name: 'index' }, plugins: [ eslint({ include: ['src/**'], exclude: ['node_modules/**'] }), babel({ exclude: 'node_modules/**', runtimeHelpers: true }) ] }
8、commonjs 兼容
yarn add rollup-plugin-commonjs@9.2.0 rollup-plugin-node-resolve@4.0.0 --dev
9、与 rollup 集成,在 rollup.config.js 中配置 plugins
import babel from 'rollup-plugin-babel' import { eslint } from 'rollup-plugin-eslint' import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' export default { input: 'src/index.js', output: { file: 'index.common.js', format: 'umd', name: 'index' }, plugins: [ resolve({ jsnext: true, main: true, browser: true }), commonjs(), eslint({ include: ['src/**'], exclude: ['node_modules/**'] }), babel({ exclude: 'node_modules/**', runtimeHelpers: true }) ] }
10、安装 terser, 用来压缩代码
yarn add rollup-plugin-terser@4.0.0 --dev
11、与 rollup 集成,在 rollup.config.js 中配置 plugins
import babel from 'rollup-plugin-babel' import { eslint } from 'rollup-plugin-eslint' import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' import { terser } from 'rollup-plugin-terser' export default { input: 'src/index.js', output: { file: 'index.common.js', format: 'umd', name: 'index' }, plugins: [ resolve({ jsnext: true, main: true, browser: true }), commonjs(), eslint({ include: ['src/**'], exclude: ['node_modules/**'] }), babel({ exclude: 'node_modules/**', runtimeHelpers: true }), terser() ] }
12、引入环境变量,实践差别化打包
一、安装插件
yarn add rollup-plugin-replace@2.1.0 --dev
二、配置 plugins
import babel from 'rollup-plugin-babel' import { eslint } from 'rollup-plugin-eslint' import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' import { terser } from 'rollup-plugin-terser' import replace from 'rollup-plugin-replace' export default { input: 'src/index.js', output: { file: 'index.common.js', format: 'umd', name: 'index' }, plugins: [ resolve({ jsnext: true, main: true, browser: true }), commonjs(), eslint({ include: ['src/**'], exclude: ['node_modules/**'] }), babel({ exclude: 'node_modules/**', runtimeHelpers: true }), replace({ exclude: 'node_modules/**', ENVIRONMENT: JSON.stringify(process.env.NODE_ENV) }), terser() ] }
十3、参数化配置,加入版权说明,最终配置以下
import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' import { eslint } from 'rollup-plugin-eslint' import babel from 'rollup-plugin-babel' import replace from 'rollup-plugin-replace' import { terser } from 'rollup-plugin-terser' const pJson = require('./package.json') const version = pJson.version const license = pJson.license const banner = '/*!\n' + ` * ${pJson.name} v${version}\n` + ` * (c) 2018-${new Date().getFullYear()}\n` + ` * Released under the ${license} License.\n` + ' */' const ENV = process.env.NODE_ENV.trim() const paths = { input: { root: 'src/index.js' }, output: { root: 'dist/' } } const fileNames = { development: 'index.common.js', production: 'index.common.js', production6: 'index.esm.js' } const fileName = fileNames[ENV] export default { input: `${paths.input.root}`, output: { file: `${paths.output.root}${fileName}`, format: ENV === 'production6' ? 'es' : 'umd', name: 'index', banner }, plugins: [ resolve({ jsnext: true, main: true, browser: true }), commonjs(), eslint({ include: ['src/**'], exclude: ['node_modules/**'] }), babel({ exclude: 'node_modules/**', runtimeHelpers: true }), replace({ exclude: 'node_modules/**', ENVIRONMENT: JSON.stringify(process.env.NODE_ENV) }), ENV && ENV.includes('production') && terser({ output: { comments: /^!/ } }) ] }
3、业务代码编写
在 src/index.js 中编写具体业务代码
4、打包
在 package.json 中添加
"scripts": { "dev": "set NODE_ENV=development && rollup -c", "build": "yarn run buildcjs && yarn run buildesm", "buildcjs": "set NODE_ENV=production && rollup -c", "buildesm": "set NODE_ENV=production6 && rollup -c" }
运行命令
yarn run build
5、发布
npm publish
发布前记得记得 注册 账号,记得修改 package.json 中 private 字段为 false
"private": false
后记:rollup-plugin-uglify@6.0.0 在 rollup@1.0.0 时有警告,文章中原 rollup-plugin-uglify 被替换成 rollup-plugin-terser