npm包发布记录
下雪了,在家闲着,不如写一个npm 包发布。简单的 npm 包的发布网上有很多教程,我就不记录了。这里记录下,一个复杂的 npm 包发布,复杂指的构建环境复杂。
整个工程使用 rollup 来构建,其中会引进 babel 来转译 ES6,利用 Eslint 来规范代码的书写风格,最后代码的发布会经过 terser 压缩。同时发布 umd、es 格式的版本以供外部调用。
完整目录结构如下:
下面是整个过程的记录
一、初始化工程
yarn init -y
初始化后,修改 package.json 内容,如 name(项目名),description(项目描述)等信息。
二、安装 rollup
yarn add [email protected] --dev
三、创建配置文件 rollup.config.js
export default { input: 'src/index.js', output: { file: 'index.common.js', format: 'umd', name: 'index' } }
四、安装 babel
yarn add [email protected] @babel/[email protected] @babel/[email protected] --dev
五、配置 babel
1、创建配置文件 .babelrc
{ "presets": [ [ "@babel/preset-env", { "modules": false } ] ] }
2、与 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 }) ] }
六、安装 eslint
yarn add [email protected]
七、配置 eslint
1、生成 eslint 配置
.\node_modules\.bin\eslint --init
2、与 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 }) ] }
八、commonjs 兼容
yarn add [email protected] [email protected] --dev
九、与 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 }) ] }
十、安装 terser, 用来压缩代码
yarn add [email protected] --dev
十一、与 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() ] }
十二、引入环境变量,实践差异化打包
1、安装插件
yarn add [email protected] --dev
2、配置 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() ] }
十三、参数化配置,加入版权说明,最终配置如下
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: /^!/ } }) ] }
三、业务代码编写
在 src/index.js 中编写具体业务代码
四、打包
在 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
五、发布
npm publish
发布前记得记得 注册 帐号,记得修改 package.json 中 private 字段为 false
"private": false
后记:[email protected] 在 [email protected] 时有警告,文章中原 rollup-plugin-uglify 被替换成 rollup-plugin-terser