1. 搭建storybook环境
# 安装rollup
sudo npm install --global rollup
# 初始化react项目
npx create-react-app ./ --template typescript
# 初始化storybook
npx -p @storybook/cli sb init --type react
# 支持ts、sass等
npm install -D @storybook/preset-create-react-app @storybook/react
npm install -D @storybook/preset-scss css-loader sass sass-loader style-loader
启动
npm run storybook
2. lerna进行多包管理
# 安装lerna
npm install lerna -g
# 初始化lerna
lerna init
# 增加组件
lerna create utils
lerna create sierpinski
修改启动目录
.storybook/main.js
module.exports = {
"stories": [
// "../src/**/*.stories.mdx",
// 修改目录
'../packages/**/*.stories.@(js|jsx|ts|tsx)'
],
"addons": [
"@storybook/preset-scss",
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions"
],
"framework": "@storybook/react",
"core": {
"builder": "@storybook/builder-webpack5"
}
}
增加stories文件
packages/sierpinski/lib/index.stories.tsx
import React from 'react'
import { ComponentStory, ComponentMeta } from '@storybook/react'
const Component = () => {
return <div>button</div>
}
export default {
title: 'Component',
component: Component,
} as ComponentMeta<typeof Component>
//storybook 定义的一种args写法,可以在界面生成配置界面
const Template: ComponentStory<typeof Component> = (args: any) => <Component {...args} />
//示例一
export const defaultButton = Template.bind({})
defaultButton.args = {
bgcolor: '#f0f0f0',
color: '#000000',
btnname: '按钮',
}
//示例二
export const BlackButton = Template.bind({})
BlackButton.args = {
bgcolor: '#333333',
color: '#ffffff',
btnname: '按钮',
}
运行看下效果
3. rollup编译并发布组件
安装rollup、babel、cross-env相关插件
npm install -D rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-replace @rollup/plugin-image rollup-plugin-terser rollup-plugin-postcss postcss cssnano postcss-nested postcss-simple-vars
npm install -D @babel/cli @babel/core @babel/plugin-external-helpers @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread @babel/plugin-transform-react-jsx @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react @babel/preset-typescript
npm install -D cross-env rollup-plugin-typescript2 @rollup/plugin-json rollup-plugin-dts
# 报错需要全局安装
sudo npm i cross-env -g
配置rollup
// rollup.config.js
// Rollup plugins
// babel插件用于处理es6代码的转换,使转换出来的代码可以用于不支持es6的环境使用
import babel from 'rollup-plugin-babel'
// resolve将我们编写的源码与依赖的第三方库进行合并
import resolve from 'rollup-plugin-node-resolve'
// 解决rollup.js无法识别CommonJS模块
import commonjs from 'rollup-plugin-commonjs'
// 全局替换变量比如process.env
import replace from 'rollup-plugin-replace'
// 使rollup可以使用postCss处理样式文件scss、css等
import postcss from 'rollup-plugin-postcss'
import autoprefixer from 'autoprefixer'
// 可以处理组件中import图片的方式,将图片转换成base64格式,但会增加打包体积,适用于小图标
import image from '@rollup/plugin-image'
// 压缩打包代码(这里弃用因为该插件不能识别es的语法,所以采用terser替代)
// import { uglify } from 'rollup-plugin-uglify';
// 压缩打包代码
import { terser } from 'rollup-plugin-terser'
// PostCSS plugins 处理css定义的变量
import simplevars from 'postcss-simple-vars'
// 处理scss嵌套样式写法
import nested from 'postcss-nested'
// 替代cssnext
import postcssPresetEnv from 'postcss-preset-env'
// css代码压缩
import cssnano from 'cssnano'
// 支持typescript
import typescript from 'rollup-plugin-typescript2'
// 支持rollup.js导入json模块
import json from '@rollup/plugin-json'
// 用于打包生成*.d.ts文件
import dts from 'rollup-plugin-dts'
// 引入package
// import pkg from "./package.json";
const env = process.env.NODE_ENV
const PACKAGE_ROOT_PATH = process.cwd()
const config = [{
// 入口文件我这里在components下统一导出所有自定义的组件
input: `${PACKAGE_ROOT_PATH}/src/index.tsx`,
// 输出文件夹,可以是个数组输出不同格式(umd,cjs,esm...)通过env是否是生产环境打包来决定文件命名是否是.min
output: [
{
file: `${PACKAGE_ROOT_PATH}/dist/index.esm.js`,
format: 'esm',
},
{
file: `${PACKAGE_ROOT_PATH}/dist/index.js`,
format: 'cjs',
},
],
// 注入全局变量比如jQuery的$这里只是尝试 并未启用
// globals: {
// react: 'React',// 这跟external 是配套使用的,指明global.React即是外部依赖react
// antd: 'antd'
// },
// 自定义警告事件,这里由于会报THIS_IS_UNDEFINED警告,这里手动过滤掉
onwarn: function (warning) {
if (warning.code === 'THIS_IS_UNDEFINED') {
return
}
},
// 将模块视为外部模块,不会打包在库中
external: ['react', 'react-dom'],
// 插件
plugins: [
typescript(),
image(),
postcss({
plugins: [
simplevars(),
nested(),
postcssPresetEnv(),
autoprefixer(),
cssnano(),
],
// 处理.css和.scss文件
extensions: ['.css', '.scss'],
}),
// 告诉 Rollup 如何查找外部模块并安装它
resolve(),
// babel处理不包含node_modules文件的所有js,ts,tsx
babel({
exclude: 'node_modules/**',
runtimeHelpers: true,
plugins: ['@babel/plugin-external-helpers'],
extensions: ['.js', '.ts', 'tsx'],
}),
// 将 CommonJS 转换成 ES2015 模块
// 这里有些引入使用某个库的api但报未导出该api通过namedExports来手动导出
commonjs({
namedExports: {
'node_modules/react-is/index.js': ['isFragment'],
'node_modules/react/index.js': [
'Fragment',
'cloneElement',
'isValidElement',
'Children',
'createContext',
'Component',
'useRef',
'useImperativeHandle',
'forwardRef',
'useState',
'useEffect',
'useMemo',
],
'node_modules/react-dom/index.js': [
'render',
'unmountComponentAtNode',
'findDOMNode',
],
'node_modules/gojs/release/go.js': [
'Diagram',
'GraphLinksModel',
'Overview',
'Spot',
],
},
}),
json(),
// 全局替换NODE_ENV,exclude表示不包含某些文件夹下的文件
replace({
// exclude: 'node_modules/**',
'process.env.NODE_ENV': JSON.stringify(env || 'development'),
}),
// 生产环境执行terser压缩代码
env === 'production' && terser(),
],
},
{
// 打包*.d.ts配置,用于支持typescript项目
input: `${PACKAGE_ROOT_PATH}/src/index.tsx`,
output: [{
file: `${PACKAGE_ROOT_PATH}/dist/index.d.ts`,
format: 'esm',
}],
external: [/.scss$/, /.css$/],
plugins: [dts()],
}];
export default config
修改tsconfig.json
"jsx": "react"
修改.gitignore
packages/*/dist
packages/*/lib
storybook-static
每个子包加上scripts
"build:sit": "cross-env BABEL_ENV=rollup rollup -c ../../rollup.config.js",
"build": "cross-env NODE_ENV=production rollup -c ../../rollup.config.js"
修改根目录script
"build": "lerna run build",