基于create-react-app脚手架编写UI组件包发布到npm平台

mac2025-11-04  14

webpack属性定义

Entry: 入口Module:模块,webpack中一切皆是模块Chunk:代码库,一个chunk由十多个模块组合而成,用于代码合并与分割Loader:模块转换器,用于把模块原内容按照需求转换成新内容Plugin:扩展插件,在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要做的事情Output: 输出结果

webpack执行流程

webpack启动后会从 Entry 里配置的 Module 开始递归解析 Entry 依赖的所有Module.每找到一个Module,就会根据配置的Loader去找出对应的转换规则,对Module进行转换后,再解析出当前的Module依赖的Module.这些模块会以Entry为单位进行分组,一个Entry和其所有依赖的Module被分到一个组也就是一个Chunk。最好Webpack会把所有Chunk转换成文件输出。在整个流程中Webpack会在恰当的时机执行Plugin里定义的逻辑。

初始化和安装

Create-react-app初始化新建项目

执行命令

npx create-react-app ui-component-demo cd ui-component-demo npm start

会自动打开http://localhost:3000:

安装webpack,配置webpack.config.js,package.json

执行命令:

npm install --save-dev webpack webpack-cli

配置webpack.config.js

const path = require('path'); module.exports = { mode: "production", entry: { index: "./src/components/index.js" }, output: { path: path.resolve(__dirname, "dist"), filename: '[name].js', library: "myLibrary", libraryTarget: 'umd', publicPath: '/', // 上线时配置的是cdn的地址 }, resolve: { modules: [ "node_modules", path.resolve(__dirname, "app") ], // 用于查找模块的目录 extensions: [".js", ".json", ".jsx", ".css"], alias: { } }, devServer: { hot: true, https: false, compress: false, port: 4000, host: 'localhost', contentBase: './dist' } }

webpack配置loader

module: { rules: [{ test: /\.jsx?$/, use: [{ loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/react'], // ts装饰器专属,或者可以在package.json配置“babel”,或者根目录下增加`.babelrc`文件 plugins: [ ["@babel/plugin-proposal-decorators", { "legacy": true }] ] } }], include: path.resolve(__dirname, 'src'), exclude: /node_modules/ }, { test: /\.css/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.less/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'less-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.scss/, use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'sass-loader'], exclude: /node_modules/, include: path.resolve(__dirname, 'src') }, { test: /\.(gif|jpg|png|bmp|eot|woff|woff2|ttf|svg)/, use: [{ loader: 'url-loader', options: { limit: 1024, outputPath: 'images' } }] } ] },

配置package.json文件需要强调的部分

{ "name": "ui-component-test", "version": "0.1.0", "private": false, "main": "dist/index.js", // 打包后生成的被引用的文件入口 "module": "es/index.js", "author": "hcw", "license": "MIT", "dependencies": { "mini-css-extract-plugin": "^0.8.0", "react": "^16.11.0", "react-dom": "^16.11.0", "react-scripts": "3.2.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "build:dev": "cross-env NODE_ENV=development webpack --progress --colors --open webpack.config.js" // 打包组件 }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "babel": { "plugins": [ [ "@babel/plugin-proposal-decorators", // @装饰器 { "legacy": true } ] ], "presets": [ "react-app" ] }, "devDependencies": { "@babel/cli": "^7.6.4", "@babel/core": "^7.6.4", "@babel/preset-env": "^7.6.3", "@babel/preset-react": "^7.6.3", "cpx": "^1.5.0", "cross-env": "^6.0.3", "webpack-cli": "^3.3.10" } }

目录结构说明

├── dist // 打包生成后的文件都放在这里 | ├── index.jsx ├── src // 开发文件 | ├── components // 所有的组件放在这里 | | ├── Button.js // 组件 | | ├── index.js // 组件的统一入口 | ├── index.js // 开发过程中调试引用入口

Button.js

import React from 'react'; class Button extends React.Component { render() { return ( <div style={{color: 'red'}}> Button test </div> ) } } export default Button

components/index.js

export {default as Button} from './Button'

打包

执行命令:

npm run build:dev

引用

安装包

npm install ui-component-test

Usage

import {Button} from 'ui-component-test'; class App extends React.Component { render (){ return ( <div className="App"> <header className="App-header"> <p> <Button></Button> Edit <code>src/App.js</code> and save to reload. </p> </header> </div> ); } }
最新回复(0)