如何发布你自己的React模块至NPM
文章介绍如何创建发布一个npm包,包括项目搭建、发布流程、注意事项等。 演示代码GitHub地址
1. 初始化项目
首先在创建好的项目文件夹下面执行
npm init
根据对应提示完成package.json
文件初始化。
- package name 为你创建的npm包的名称,在发布后被安装使用即该名字,npm规定包名首字母需要为小写。如
import App from 'your-module';
- version 即为包版本,每次发布前都需要更新包版本,否则会失败,包版本应该遵守语义化规范。语义化版本号分为三位
0.0.0
。主版本号:当进行了大都改动或者对api有很多不兼容修改时应该进行版本号升级。次版本号:增加了部分特性或者优化时升级该版本。修订号:当修改了项目bug或者小的改动时升级该版本。 - entry point 项目的入口路径,当用户使用包的时候,会根据该入口也就是
package.json
的main中的路径来进行索引 - git repository 关联的git仓库
- keywords 会在npm中展示你的项目关键字
2. 项目构建
开发环境webpack.config.js配置
const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: path.resolve(__dirname, 'app.js'), output: { path: path.join(__dirname, 'dist'), filename: "main.js", }, module: { rules: [ { test: /(\.jsx|\.js)$/, exclude: /node_modules/, loader: 'babel-loader' }, {test: /\.css$/, loader: 'style-loader!css-loader'}, { test: /\.(png|jpg|gif|svg)$/, //对图片文件,使用 url-loader里的加载器处理 loader: 'url-loader', options: { limit: 8192, //限制图片文件字节,大于8KB则不生成base64 用路径引用替代(相当于file-loader) name: '[name].[ext]?[hash]' //文件名 } } ] }, plugins: [ new HtmlWebpackPlugin({ hash: true, template: './index.html', }), new webpack.HotModuleReplacementPlugin(), // 热更新插件 ], devtool: 'inline-source-map', // map文件追踪错误提示 devServer: { // 启动本地开发的node服务器环境(webpack-dev-server) port: 8080, // 端口 contentBase: './dist', // 开发环境的服务目录 historyApiFallback: true, host: '0.0.0.0', inline: true, hot: true, }, };
在开发环境中就是一些很常见的配置,保证我们可以进行本地的组件模块开发即可。
打包模块webpack.prd.js配置
const path = require('path'); const webpack = require('webpack'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const NODE_ENV = process.env.NODE_ENV; const prdWebpackConfig= { mode: 'production', entry: path.resolve(__dirname, 'src/index.js'), output: { path: path.join(__dirname, 'lib'), filename: "chat-react.js", libraryTarget: 'commonjs2' //模块输出方式 }, externals: { react: 'react' //打包时候排除react }, module: { rules: [ { test: /(\.jsx|\.js)$/, exclude: /node_modules/, loader: 'babel-loader' }, {test: /\.css$/, loader: 'style-loader!css-loader'}, { test: /\.(png|jpg|gif|svg)$/, loader: 'url-loader', options: { limit: 8192, name: '[name].[ext]?[hash]' } } ] }, plugins: [] }; if (NODE_ENV !== 'publish') { prdWebpackConfig.plugins.push(new BundleAnalyzerPlugin()) } module.exports = prdWebpackConfig;
打包模块与我们写应用逻辑代码有些不同,由于大部分用户使用模块都不会去再对模块进行es5转换,所有我们发布的模块也应该是已经被转换之后的代码,而且需要提供模块的引用入口以及排除模块自己以外的代码。
entry
在完成模块打包时,修改了项目的入口路径entry。配置打包的entry路径为该发布模块的文件,而不是开发环境中的项目入口。output
path为生成的目录位置以及目录名,filename 为打包后的模块文件。libraryTarget 为生成模块的引入方式,因为我们写的react组件基本为模块化打包开发方式,选择使用commonjs2配置,最后打包会生成符合commonjs规范的模块,具体配置规则可见output.libraryTargetexternals
因为我们是基于react的组件,但是在完成打包的时候如果将react也打包进去,库的体积就会变大,而且react库通常会在使用组件的时候被外部引入,所以我们要排除react。externals 配置BundleAnalyzerPlugin
在非发布命令下打包时候,我们可以用该插件审查一下打包完成的包体积大小。所以只需判断下在npm scripts中设置的NODE_ENV环境变量,按需使用该插件即可。mode
在webpack4中设置mode为production,会自己启用生产环境的部分配置优化,此时UglifyJsPlugin压缩插件也会启用,帮助完成我们的library的代码压缩。
3. 发布前配置
1.发布前需要正确配置package.json中的main内容,使用时会根据该内容自动索引模块内容
"main": "lib/chat-react.js"
2.在发布前我们需要完成打包,为了确保我们发布的版本为编译完成后的版本,可以利用npm scripts中的prepublishOnly钩子。这个钩子可以保证我们在执行npm publish
的前进行打包操作。
"scripts": { "prepublishOnly": "NODE_ENV='publish' npm run build" }
prepublish钩子也会在执行npm publish
前触发该周期,我使用的是npm v5.5版本,在使用npm install的时候prepublish周期也会被触发,翻到了一篇阮老师的文章,其中提到npm5版本时候会改掉这一状态,prepublish将只在npm publish命令之前运行,不过看起来跟预期不一致。在15年的npm官方讨论issue里说将来可能会废弃prepublish或者prepublishOnly某一个,不过翻看了官方npm script文档对两个钩子的用法都有说明,看起来是都保留了。
3.配置.npmignore
,.npmignore的用法与.gitignore一致。因为我们在执行npm publish发布命令时会将项目下掉所有文件都发布至npm,.npmignore
可以忽略掉我们不需要发布都文件
node_modules example src .babelrc app.js index.html package-lock.json webpack.config.js webpack.prd.js
4.编写使用文档(readme)。为我们的模块组件编写使用文档是必不可少的,README.md
使用的是markdown语法,记不住语法的小伙伴也可以使用我的在线markdown编辑器。
4. 完成发布
发布流程
- 首先注册你的npm帐号
- 命令行执行
npm login
登录你的npm账号 - 进入你项目目录下
npm publish
即可完成发布
回撤版本
如果你意外的发布错了包,使用npm unpublish +包名即可删除该包。如:
npm unpublish chat-react
如果你想撤回指定版本,执行npm unpublish + 包名@版本号。如:
npm unpublish [email protected]
Tips:npm为了保证包不会影响到使用者,发布的版本只能在24小时内进行撤回。
文章代码演示GitHub地址