持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
1 初始化项目
- 使用脚手架创建react项目:npx create-react-app wison-uilib
- 简化目录,运行yarn eject暴露webpack配置文件
- 简化目录结构,修改index.js如下图,运行yarn start启动项目
//简化后的index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.less";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<div>test</div>);
- 添加less支持 修改config目录下的webpack.config.js
...
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
//搜索上面sassModuleRegex关键字并在后面新增以下两行
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
...
然后在module对象的rules属性下新增下面两条格则
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
},
"less-loader"
),
sideEffects: true,
},
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
"less-loader"
),
}
- 关闭shouldUseSourceMap
// const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';注释这行,新增下行
const shouldUseSourceMap = false;
- 配置别名(也可以跳过不配置,看个人喜好) 找到resolve对象下的alias属性,新增下行
"@": path.resolve(__dirname, "../src")
2 开始编写组件
- 在componetns目录下新增Loading文件夹,写入代码,并修改index.js重新启动项目
//components/Button/index.jsx
import React from "react";
import "./index.less";
export default function Loading() {
return (
<div className="loading-wrapper">
<svg width="100" height="100">
<g>
<text x="50" y="55">
loading···
</text>
<circle cx="50" cy="50" r="40" />
</g>
</svg>
</div>
);
}
//components/Button/index.less
.loading-wrapper {
g {
text {
font-size: 14px;
text-anchor: middle;
fill: #418bfd;
}
circle {
fill: none;
stroke-width: 5px;
stroke: #418bfd;
stroke-dasharray: 300;
stroke-dashoffset: 300;
animation: svg-loading-rolling 1.5s linear infinite;
}
}
@keyframes svg-loading-rolling {
from {
stroke-dasharray: 600;
stroke-dashoffset: 600;
transform: rotate(0);
transform-origin: 50px 50px;
}
to {
stroke-dashoffset: 0;
transform: rotate(720deg);
transform-origin: 50px 50px;
opacity: 0.1;
}
}
}
//index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.less";
import Loading from "@/components/Loading";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Loading />);
- 此时预览效果如下(当然如果不了解svg的可以写个Button组件测试,想学习svg的可以看SVG基础及其动画应用浅析)
3 打包发布npm
- 在根目录下新建dist文件夹用来存放npm包文件
- cd dist 进入dist目录执行npm init
- 根据提示完成配置
- 往其中添加peerDependencies配置,设置组件库的核心依赖
- 根据提示完成配置
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
},
- 运行yarn build,发现脚手架默认配置产物加上了哈希值,但是我们需要固定一个index.js文件名
- 我们修改下webpack配置自定下我们想要的产物文件名,并把文件输出到dist文件夹下的lib目录下 1)修改output下的path属性设置输出目录
// path: paths.appBuild,
path: path.join(__dirname, "../dist"),
2)在output下新增libraryTarget属性指明模块系统的兼容性
output: {
...
libraryTarget: 'umd',//该方案支持commonjs、commonjs2、amd,可以在浏览器、node中通用。
...
}
3)找到output对象的filename属性,修改如下
filename: isEnvProduction
// ? 'static/js/[name].[contenthash:8].js' 修改这一行为'lib/index.js'
? 'lib/index.js'
4)继续修改css产物文件名
new MiniCssExtractPlugin({
// filename: 'static/css/[name].[contenthash:8].css',修改这一行为下面的'lib/index.css'
filename: 'lib/index.css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
5)关闭index.html,asset-manifest.json及LICENSE.txt文件的输出
在plugins数组下注释掉WebpackManifestPlugin插件
在plugins数组下修改HtmlWebpackPlugin使其仅在开发环境下输出index.html
在new TerserPlugin最后新增下面两行关闭LICENSE.txt文件输出
parallel: true, //此处为新增配置
extractComments: false, //此处为新增配置
- 修改index.js入口文件后重新打包
//index.js
export { default as Loading } from "./components/Loading"; //这是下面两行的简写
// import {default as Loading} from './components/Loading'
// export Loading
- 注册npm账号注册入口
- 如果设置了其他npm镜像源的务必要换回官方源
- npm config set registry registry.npmjs.org
- 登录 npm login 按提示操作
- npm publish 发布(注意要在dist目录下)
- 如果发布错误可执行npm unpublish 包名@版本号 删除该版本
- 但注意执行了删除操作后同名的包只能在删除命令执行完24小时后才能再publish(如果不想等24小时再发布可换个包名发布)
4 在其他项目中使用发布后的包
- yarn add weison-react-uilib
import React from "react";
import ReactDOM from "react-dom";
import {Loading} from 'weison-react-uilib'
import 'weison-react-uilib/lib/index.css'
ReactDOM.render(<Loading />, document.getElementById("root"));
5 组件库文档docz的使用
待更新
6 单元测试
待更新
7 按需加载
待更新