使用Rollup + React + TypeScript搭建组件库,支持tree shanking,按需加载
项目目录
组件库入口文件
src/index.ts
export type { TextProps } from "./Text";
export { default as Text } from "./Text";
先来一个基本组件,src/Text/index.tsx (文本组件)
index.less
.text{
font-size: 30px;
color: #f00;
}
src/Text/index.tsx
import React, { FC } from "react";
import styles from "./index.less"
export interface TextProps {
text: string;
}
const Text: FC<TextProps> = (porps) => {
const { text = "" } = porps;
return <div className={styles.text}>{text}</div>;
};
export default Text;
tsconfig.json 配置文件
"compilerOptions": {
"sourceMap": false,
"allowJs": false,
"target": "es5",
"lib": ["es2015", "dom", "es5", "es2016", "es2017"],
"jsx": "react",
"noEmit": true,
"moduleResolution": "node",
"strictNullChecks": false,
"noImplicitAny": false,
"noImplicitReturns": true,
"noImplicitThis": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
},
"include": [
"src",
"globals.d.ts"
],
"exclude": ["node_modules", "*.js", "dist"]
}
rollup.config.js配置文件
打包生成esm,umd文件
- ESM由于具有简单的语法,异步加载的特性,以及Tree-shakeable的特性,因此被广泛使用。
- UMD可以在任何环境下使用,并且在ESM不能使用的情况下回选择UMD。
iimport { name } from "./package.json";
import typescript from "rollup-plugin-typescript2";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import eslint from "@rollup/plugin-eslint";
import postcss from "rollup-plugin-postcss";
export const file = (type) => `dist/index.${type}.js`;
const overrides = {
compilerOptions: {
noUnusedParameters: true,
noUnusedLocals: true,
strictNullChecks: true,
moduleResolution: "node",
declaration: true,//抽离声明代码 *.d.js
allowSyntheticDefaultImports: true,
},
useTsconfigDeclarationDir: true,
};
export default {
input: "src/index.ts",
output: [
{
name,
file: file("umd"),
format: "umd",
globals: {
react: "React",
},
},
{
file: file("esm"),
format: "es",
sourcemap: "inline",
globals: {
react: "React",
},
},
],
external: ["react", "react-dom"],
plugins: [
postcss({
extract: true, // 独立导出css文件 ,使用组件时需要单独引入
namedExports: true,
minimize: true,
modules: true,
extensions: [".less", ".css"],
}), // 处理css、less 文件
eslint({
exclude: ["node_modules"],
}),
typescript({
tsconfigOverride: overrides,
}),
nodeResolve({
extensions: [".js", ".jsx", ".ts", ".tsx", ".less"], //允许我们加载第三方模块
}),
commonjs(), // 转换为ES6版本
],
};
package.json 相关配置
"main": "dist/index.umd.js", //打包生成的umd
"module": "dist/index.esm.js", //打包生成的esm
"types": "dist/index.d.ts",// 声明文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rm -fr dist && set NODE_ENV=production&& rollup -c rollup.config.js",
"prepublishOnly": "npm run build" // npm publish 前执行命令
},
"files": [ // 只提交dist 文件代码到npm
"dist"
],
"peerDependencies": { // 核心依赖库必须先下载安装
"react": ">=17.0.0",
"react-dom": ">=17.0.0"
},
出现 less 报错
在根目录添加 globals.d.ts文件
declare module "*.less" {
const content: { [className: string]: string };
export default content;
}
本地如何测试组件库
在当前组件库 执行npm link
在使用项目文件下执行 npm link name(组件库 package.json配置name值 )
代码发布到npm
登录自己的npm账号,
npm login
npm publish