Rollup + React + TypeScript搭建组件库

2,108 阅读2分钟

使用Rollup + React + TypeScript搭建组件库,支持tree shanking,按需加载

项目目录

image.png

组件库入口文件

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文件
  1. ESM由于具有简单的语法,异步加载的特性,以及Tree-shakeable的特性,因此被广泛使用。
  2. 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