一直想构建一个npm包并发布到社区。这次趁着百日计划把这项工作好好落实了。以下是整个流程的记录。
参考1: 从零开始发布一个React组件到npm
参考2: 基于webpack和ES6构建npm包
参考3: 怎么写一个React组件库
构建流程
1. 初始化工作
1.1 创建git仓库
为了方便版本控制,最好创建一个git仓库来管理我们的代码。这里略。
1.2 添加npm用户
在npm官网注册好用户之后,就可以使用这个账号来登陆:
$ npm set init.author.name "Your Name"
$ npm set init.author.email "you@example.com"
$ npm set init.author.url "http://yourblog.com"
$ npm adduser
1.3 npm项目初始化
$ npm init
填写好项目的基本信息之后初始化工作就结束了。
2. 脚手架搭建
2.1 安装必要构建包
这里可以参考我之前的一篇博文: Yarn + webpack 构建项目。
- 安装React相关组件
npm i react react-dom -D
- 安装webpack相关
npm i webpack webpack-cli webpack-dev-server html-webpack-plugin style-loader css-loader babel-core babel-loader babel-preset-env babel-preset-react babel-loader@7 -D
- 相关配置
-
webpack.config.js
幸运的是,webpack到4.0以后就实现了几乎“零配置”的开箱即用,这里对webpack不需要做太多配置工作,在项目根目录下创建这个文件即可。如果你的组件构建需要用到一些基于webpack的工具,那需要自行解决。
/*** webpack.config.js ***/
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
template: path.join(__dirname, "examples/src/index.html"),
filename: "./index.html"
});
module.exports = {
entry: path.join(__dirname, "examples/src/index.js"),
module: {
rules: [{
test: /\.(js|jsx)$/,
use: "babel-loader",
exclude: /node_modules/
},{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}]
},
plugins: [htmlWebpackPlugin],
resolve: {
extensions: [".js", ".jsx"]
},
devServer: {
port: 3001
}};
-
package.json
配置一下启动命令脚本
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --mode development"
},
2.2 配置开发环境
1. eslint配置(不是必要)
自动生成.eslintrc.js文件并安装相关依赖(可根据自己喜好选择代码规范)
$ npm install eslint -D
$ npm install eslint -g # 全局安装ESLint
// 安装eslint相关
$ npm i eslint-plugin-html babel-eslint -D
$ eslint --init
? How would you like to configure ESLint? Use a popular style guide
? Which style guide do you want to follow? Standard
? What format do you want your config file to be in? JavaScript
添加.eslintignore
文件忽略对输出目录的代码检测
dist/
2. babel 配置
创建..babelrc
文件:
{
"presets": ["env", "react"]
}
2.3 整理项目目录结构
├── examples // 示例代码存放目录
│ └── src
├── node_modules
├── package.json
└── src // 组件源代码和样式存放目录
3. 简单组件示例
下面我将创建一个非常简单的组件以作为示例
- src/index.js
/*** src/index.js ***/
import React from 'react';
import './styles.css';
const MyComponent = () => (
<h1>Hello from My Component</h1>
);
export default MyComponent;
- src/styles.css
/*** src/styles.css ***/
h1 {
color: red;
}
- examples/src/index.html
<!-- examples/src/index.html -->
<html>
<head>
<title>My Component Demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
- examples/src/index.js
/*** examples/src/index.js ***/
import React from 'react';
import { render} from 'react-dom';
import MyComponent from '../../src';
const App = () => (
<MyComponent />
);
render(<App />, document.getElementById("root"));
4. 测试和打包(未完成)
接下来运行 demo
npm start
启动完成后打开浏览器输入 http://localhost:3001,你将会在页面上看到你写的组件,你可以修改你的代码并保存,页面将会自动刷新,我们的开发环境已经处于监控模式。
确认无误之后,进入下一步工作。
1. 首先需要安装 babel cli
npm i babel-cli -D
现在我们添加 transpile 脚本,以便使用 Babel 编译我们的源代码,同时拷贝一些静态文件 (如:css 文件) 到目标打包目录 dist 下。
# package.json
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --mode development",
"transpile": "babel src -d dist --copy-files"
},
...
2. 尝试编译
npm run transpile
现在在我们项目根目录下面会有一个 dist 目录,包含了 index.js 的编译版本,和拷贝的样式文件 styles.css, 这些文件是用户可以直接 可以 import 到他们项目的文件,接下来我们再在我们的工作流中添加一个脚本 prepublishOnly , 这个脚本会在每次我们需要发布我们的组件到 npm 上去的时候会自动执行,他能确保我们每次发布上去的代码都是最新代码编译的。
5. 发布以及善后
编译完成后,并且通过测试,接下来就是发布了。
发布之前,还有一点小小的工作需要处理。我们需要告诉用户在用户我们的组件的时候对于 React 版本的要求,peerDependency 能够很好的表达这个信息,同时在我们的发布的组件包中不会包含 react , 这样也减小了包的大小,更加重要是可以避免在用户的项目中存在多个 react 版本,更新 package.json 如下:
...
"peerDependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0"
},
...
最后让我们在项目的根目录下添加.npmignore 文件,告诉 npm,我们项目中哪些文件和文件夹是在发布的包中被忽略掉的
# .npmignore
src
examples
.babelrc
.gitignore
webpack.config.js
发布我们的组件到 npm 上
npm publish
这时你去浏览器的 npm 主页,应该就能看到我们刚才发布的新包了。
6. GitHub Pages 上发布一个在线 demo
在 GitHub Pages 托管在线 Demo 是免费的,需要使用 webpack 来构建我们的生产环境版本,然后发布到 GitHub 仓库指定的分支上去,接下来让我们自动化完成这些吧!
首先,我们需要借助一个帮助维护特性分支的包,我们还没有对我们的项目添加 git 代码版本控制,稍等片刻
npm i gh-pages -D
然后在 package.json 中添加三个脚本
{
"name": "my-component",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --mode development",
"transpile": "babel src -d dist --copy-files",
"prepublishOnly": "npm run transpile",
"build": "webpack --mode production",
"deploy": "gh-pages -d examples/dist",
"publish-demo": "npm run build && npm run deploy"
},
"author": "",
"license": "ISC",
"peerDependencies": {
"react": "^16.3.0",
"react-dom": "^16.3.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.11",
"gh-pages": "^1.1.0",
"html-webpack-plugin": "^3.2.0",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"style-loader": "^0.20.3",
"webpack": "^4.5.0",
"webpack-cli": "^2.0.14",
"webpack-dev-server": "^3.1.3"
}
}
build 脚本目的是用 webpack 帮我们构建一个 boundled, 和压缩生产环境代码,这里我们需要告诉 webpack 哪个文件是我们项目输出的结果
/*** webpack.config.js ***/
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlWebpackPlugin = new HtmlWebpackPlugin({
template: path.join(__dirname, "examples/src/index.html"),
filename: "./index.html"
});
module.exports = {
entry: path.join(__dirname, "examples/src/index.js"),
output: {
path: path.join(__dirname, "examples/dist"),
filename: "bundle.js"
},
module: {
rules: [{
test: /\.(js|jsx)$/,
use: "babel-loader",
exclude: /node_modules/
},{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}]
},
plugins: [htmlWebpackPlugin],
resolve: {
extensions: [".js", ".jsx"]
},
devServer: {
port: 3001
}
};
来,试一试
npm run build
你会发现生成版本的代码已经打包到了 examples/dist
现在我们的本地和远程的仓库都已经创建并连接上了,准备将 demo 发布到托管环境了,这时,首先需要去这个项目的仓库中为它新建一个 gh-pages
的分支,deploy 脚本就是为了帮我们干这个事的
npm run deploy
点击设置连接到你的 github 仓库页面,然后滚动到 github pages 栏目,你将会看到你的 demo 在线连接地址,恭喜你 上线了!
网友评论