初始化项目
使用webpack4.X版本结合React实现对组件的封装并发不到npm官方仓库进行使用
新建package.json
其中有涉及到对css样式文件进行构建的依赖包,可根据实际场景进行选择性安装
{
"name": "kechenexample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --mode development --config webpack.config.dev.js",
"build": "webpack --config webpack.config.prod.js",
"update": "concurrently \"npm version patch\" \"npm run build\""
},
"author": "",
"license": "ISC",
"dependencies": {
"antd": "^4.24.14",
"react": "^16.14.0",
"react-dom": "^16.14.0"
},
"devDependencies": {
"@babel/core": "^7.22.17",
"@babel/plugin-proposal-class-properties": "^7.12.13",
"@babel/plugin-transform-runtime": "^7.22.15",
"@babel/preset-env": "^7.22.15",
"@babel/preset-react": "^7.12.10",
"@babel/runtime": "^7.22.15",
"@babel/runtime-corejs3": "^7.22.15",
"autoprefixer": "^10.4.15",
"babel-loader": "^8.1.3",
"babel-plugin-import": "^1.13.8",
"concurrently": "^8.2.1",
"copy-webpack-plugin": "^5.1.2",
"css-loader": "^5.2.7",
"html-webpack-plugin": "^4.5.0",
"postcss-loader": "^4.0.0",
"style-loader": "^2.0.0",
"url-loader": "^3.0.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.2"
}
}
新建.babelrc
配置预处理以及相关的插件,配置antd按需加载
{
"presets": ["@babel/preset-react", "@babel/preset-env"],
"plugins":[[
"import",{
"libraryName":"antd",
"libraryDirectory":"es",
"style":"css"
}],
[
"@babel/plugin-transform-runtime",
{
"corejs": 3
},
"@babel/plugin-proposal-class-properties"
]
]
}
新建src/index.js
import React from "react";
import {Card} from 'antd';
import 'antd/dist/antd.css';
import './index.css';
const MyComponent = () => {
return <div>
<p>hello,我 是title</p>
<Card title="我是title">我是card</Card>
</div>
};
export default MyComponent;
新建example/index.js与index.html
- index.js
import React from 'react';
import { render } from 'react-dom';
import MyComponent from '../src';
const App = () => (
<MyComponent>hello</MyComponent>
);
render(<App />, document.getElementById("root"));
- 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>
新建webpack.common.js
将要构建的文件构建成umd的库文件,构建目的文件夹为dist,构建出的文件名称根据实际入口文件进行自动生成。
const path = require('path');
module.exports = {
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'umd',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {loader: 'babel-loader'},
// 配置都加到了.babelrc
exclude: /node_modules/
//排除 node_modules 目录,
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
require('autoprefixer')
]
}
}
}
]
},
{
test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
exclude: /node_modules/,
use: [
{
loader: 'url-loader',
options: {
// limit: 102400, //低于10k的资源将会被转化成base64
esModule: false // 设置为 false,否则,<img src={require('XXX.jpg')} /> 会出现 <img src=[Module Object] />
}
}
],
}
]
},
resolve: {
extensions: [".js", ".jsx"]
}
}
新建webpack.dev.js
本地开发需要使用devserver,并且入口文件需要配置多文件,将demo的入口也进行配置,同时也要使用HtmlWebpackPlugin将html进行构建,才能运行demo。
const commonConfig = require('./webpack.common');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
...commonConfig,
entry: {
index: './src/index.js',
demo: './example/index.js'
},
mode: "development",
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "./example/index.html"),
filename: 'index.html', //打包后的文件名
hash: true //是否加上hash,默认是 false
})
],
devServer: {
port: '3001', //默认是8080
open: true, //自动打开浏览器
hot: true, //热更新
}
}
新建webpack.prod.js
最后要发布到npm的文件只需要src下面的文件即可,所以入口处只需要配置src
下面的index.js
即可,输出文件名默认设置为index.js
,后续在使用npm包的时候方便引入。externals
配置项可以将不需要构建的包进行排除,copy-webpack-plugin
将package.json复制到跟构建目标文件夹,便于npm发布时使用。
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
const commonConfig = require('./webpack.common');
module.exports = {
...commonConfig,
entry: './src/index.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'umd',
},
mode: "production",
externals: {
react: 'React'
},
plugins: [
new CopyPlugin([
{
from: 'package.json',
to: ".",
}]
),
],
performance: {
// 禁用 size 警告
hints: false,
// 入口起点的最大体积
maxEntrypointSize: 50000000,
// 生成文件的最大体积
maxAssetSize: 30000000,
// 只给出 js 文件的性能提示
assetFilter: function (assetFilename) {
return assetFilename.endsWith('.js');
},
}
}
构建发布
在package.json中已经配置了publish命令,可以通过npm run update
进行构建与自动迭代版本号,默认使用了的每执行一次自动增加一个patch版本号,可以根据自己的使用进行进行修改。
发布时需要先登陆npm,进入dist文件夹后进行发布。
注意事项
- 不支持ts语法,需要使用ts语法的可以自己增加ts-loader等ts的配置;
- 发布时,如果只执行
npm run publish
命令则所在文件夹必须是dist文件夹,或者使用npm run publish dist
的方式对执行文件夹进行发布; - 项目示例中使用的是webpack4.x版本,用到的
copy-webpack-plugin
插件要注意版本不能太高,截止20230921时,copy-webpack-plugin的版本最新为11.x,在webpack4.x中应该使用5.x版本; - webapck内部的配置方式有很多种,使用相关的插件也可以根据文档自行摸索;
评论区