首先npm文檔擺在這里:
參考組件
https://github.com/rakuten-rex/rex-dropdown
https://www.npmjs.com/package/react-slot
“造輪子”是非常有效的學習方法。在熟練掌握API的搬運方法之后,我們可以通過自己“造輪子”來進一步掌握和理解更底層的知識。自己完成一個組件的開發之后,我們可以打包上傳到 NPM 來分享自己的成果。在后面的步驟中,將會實現以下幾個小目標:
- 配置開發環境
- 開發組件
- 打包組件,並在測試項目中引入打包組件模塊,驗證組件功能
- 發布到 NPM
初始化
開始一個最基本的 React 工程,我們至少需要以下幾項配置:
- React: 用於開發組件
- React dom: 渲染組件
- Babel: 用於轉義 JSX
- webpack: 打包組件
我在這個例子里面做了一個叫做 react-tiny-autosuggest 的組件。首先創建 project 並且初始化。
mkdir react-tiny-autosuggest
cd react-tiny-autosuggest
npm init -y
這里我們需要改動三個地方:
- main: 這里是我們組件的入口文件。開發者在 import 我們的組件的時候會引入這里 export 的內容
- files: 申明將要發布到 npm 的文件。如果省略掉這一項,所有文件包括源代碼會被一起上傳到 npm
- scripts: 申明命令行可用的各種指令。
// package.json
...
"main": "dist/bundle.js",
"files": ["dist"],
"scripts": {
"start": "webpack-dev-server --config webpack.dev.config.js",
"dev": "webpack-dev-server --config webpack.dev.config.js",
"build": "webpack --config webpack.prod.config.js"
},
...
接下來安裝依賴
npm i react react-dom npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-react webpack webpack-dev-server webpack-cli html-webpack-plugin webpack-node-externals css-loader style-loader
依賴版本的升級很快,所以如果讀者發現依賴有問題,請參考官方文檔正確安裝。這篇文章最開始寫於2018年初,到年之后更新的時候,好幾個依賴都經過大更新了。
接下來配置 webpack。這里分成兩份配置,一份用於開發環境(development),一份用於單獨打包組件用於生產環境(production)。
在開發環境下,我們需要搭建一個完整的項目,讓我們可以開發組件,並可以將其引入其他組件,渲染到瀏覽器中看到效果。同時我們也需要一些開發工具的支持,比如 HMR(hot module reloa) 組件熱更新和詳細的報錯信息。
在生產環境下,只需要打包組件本身,不包括工程里面的其他組件。同時我們需要壓縮文件體積,盡量減小組件打包之后的體積。
Webpack 配置
下面是我們的 webpack 開發配置
const path = require('path'); const htmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: './src/app.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, '../dist'), }, module: { rules: [ { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.cm\.styl$/, loader: 'style-loader!css-loader?modules&camelCase&localIdentName=[local]-[hash:base64:5]!stylus-loader' } ] }, devServer: { contentBase: './dist' }, plugins: [ new htmlWebpackPlugin({ template: 'public/index.html' }) ], };
production 打包配置,區別是改變了 entry,因為我們只需要單獨的組件,並且改變了 libraryTarget,這個配置項的默認參數是 'var',我們需要改成 commonjs2,這樣可以通過模塊系統引入這個組件。另一點區別是使用了 nodeExternals 使得打包的組件中不包括任何 node_modules 里面的第三方組件,起到減小體積的作用。
const path = require('path'); const nodeExternals = require('webpack-node-externals'); module.exports = { mode: 'production', entry: './src/autosuggest.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, '../dist'), libraryTarget: 'commonjs2' }, module: { rules: [ { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.cm\.styl$/, loader: 'style-loader!css-loader?modules&camelCase&localIdentName=[local]-[hash:base64:5]!stylus-loader' } ] }, externals: [nodeExternals()] };
在 package.json 中,我們可以通過 --config 指定 webpack 使用哪一套配置。在這個 demo 里使用了 stylus 來寫樣式文檔,所以添加了相應的 css pre-processor,把 stylus 語法 轉化為 css 語法。並且在引入 css 的時候使用了模塊化 css 以避免全局命名沖突。
.babelrc
{ "presets": ["@babel/preset-env", "@babel/preset-react"] }
開發組件
完成以上配置以后,我們可以在 src 文件夾里面開發自己組件。運行 npm run dev,讓 webpack-dev-server 渲染到瀏覽器中,實時看到效果。
打包並驗證
打包組件,只需要運行 npm run build 就可以了。
接下來可以通過 npm link
把打包之后的組件引入到 global node_modules 中,然后在驗證 demo 中再通過 npm link react-tiny-autosuggest
引入這個組件,並驗證是否符合預期。
// At development directory
npm run build
npm link
cd [test project folder]
npm link react-tiny-autosuggest
接下下 demo 里面就可以直接 import AutoSuggest from 'react-tiny-autosuggest'
了。
發布到 NPM
發布組件到 npm: npm publish
取消發布: npm unpublish
更行版本: 更改 package.json 里面的版本號並重新發布