React组件库搭建(二)一行命令配置组件模版

316 阅读3分钟

简介

使用NX自定义插件,完成React组件生成器,一键tailwindcss配置,rollup自定义配置,发布自己的组件库到NPM

本节将实现一行命令,配置初始组件模版

pnpm exec nx generate @taibui/devkit:library awesome-ui

深入本命令,你将额外获得

  • 自定义代码生成器:在你的项目,快速生成你的自定义代码片段
  • 自动添加依赖:为你的项目自动安装Taiwindcss
  • 自动为Storybook和入口文件引入taiwind样式
  • 生成自定义rollup配置文件,并更新project.json
  • 一行命令推送自定义插件到到NPM

需求分析

Nx官方的插件不能满足个人需求,配置tailwindcss仍需手动引入相关文件,仍需新建自定义配置,更新配置文件才能自定义rollup。

手动配置文章 React组件库搭建(一)Monorepo篇(基于Nx)

相关知识点

  • Custom Nx plugin(自定义Nx插件)
  • Storybook-MDX-DOCS(使用MDX为UI组件编写丰富的交互式文档)(下篇-自定义组件生成器
  • rollup打包相关插件
  • 借助社区插件,NPM发布自己的库/工具

自定义插件

已发布。可在npm查看
git仓库(仍需优化+后续文章,暂无)

如何使用

1.确保在Nx工作区下
2.安装插件
3.执行插件

新建Nx工作区

npx create-nx-workspace --packageManager=pnpm

选择项

√ Choose your style                     · integrated
√ What to create in the new workspace   · apps
√ Repository name                       · test
√ Enable distributed caching to make your CI faster · No  

在工作区安装插件

cd test
pnpm add -D taibui-devkit@0.0.3

执行插件

pnpm exec nx g taibui-devkit:library

命令行面板,可看到相关文件生成

√ What name would you like to use for the library? · testuilib
√ Which stylesheet format would you like to use? · none 
√ What is the npm scope of the library? · uilib #设置了npm默认发布
√ What name would you like to use for the library? · testuilib
√ Which stylesheet format would you like to use? · none
√ What is the npm scope of the library? · uilib
adding .storybook folder to your library
CREATE libs/testuilib/project.json
CREATE libs/testuilib/.eslintrc.json
CREATE libs/testuilib/.babelrc
CREATE libs/testuilib/package.json
CREATE libs/testuilib/README.md
CREATE libs/testuilib/src/index.ts
CREATE libs/testuilib/tsconfig.lib.json
CREATE libs/testuilib/tsconfig.json
CREATE libs/testuilib/jest.config.ts
CREATE libs/testuilib/tsconfig.spec.json
UPDATE tsconfig.base.json
CREATE libs/testuilib/src/lib/test/test.spec.tsx
CREATE libs/testuilib/src/lib/test/test.tsx
CREATE libs/testuilib/.storybook/main.ts
CREATE libs/testuilib/.storybook/preview.ts
CREATE libs/testuilib/.storybook/tsconfig.json
CREATE libs/testuilib/src/lib/test/test.stories.tsx
CREATE libs/testuilib/src/styles.css
CREATE libs/testuilib/postcss.config.js
CREATE libs/testuilib/tailwind.config.js
CREATE libs/testuilib/custom-rollup.config.js
UPDATE package.json

React组件生成器(Custom Generator)

主要实现

  // 以下改善官方插件set-storybook工作流

  // 首先照常根据官方插件为项目配置storybook
  const setStorybookForLib = await storybookConfigurationGenerator(tree, {
    name: options.name,
    configureCypress: false,
    // Automatically generate *.stories.ts files for components declared in this project
    generateStories: true,
    generateCypressSpecs: false,
    bundler: 'webpack',
    tsConfiguration: true,
  });

  // 在配置tailwindcss之前,先在项目src目录下创建一个styles.css文件
  createFiles(tree, normOptions);

  // 正常为lib配置tailwindcss
  const setTaikwindForLib = await setupTailwindGenerator(tree, {
    project: options.name,
    // The name of the target used to build the project. This option is not needed in most cases
    buildTarget: `${options.name}-build`,
  });

  // .storybook/preset.[js/ts]引入先前创建的styles.css文件
  // src的入口文件index.ts中引入styles.css文件

  // 更新文件
  addExportsToBarrel(tree, normOptions);

  // 新建 custom-rollup.config.js
  generateFiles(
    tree,
    joinPathFragments(__dirname, 'files/rollup/'),
    joinPathFragments(normOptions.projectRoot),
    {
      template: '',
    }
  );

  // 更新project.json
  updateProject(tree, normOptions);

  const addPrettierTailwindPlugin = addDependenciesToPackageJson(
    tree,
    {},
    {
      'prettier-plugin-tailwindcss': '^0.2.7',
    }
  );

  // 删除原有的tailwindcss配置文件
  try {
    tree.exists(`${normOptions.projectRoot}/tailwind.config.js`) &&
      tree.delete(`${normOptions.projectRoot}/tailwind.config.js`);
  } catch (e) {
    throw new Error('删除原有的tailwindcss配置文件失败');
  }

  // 新建tailwind.config.js
  generateFiles(
    tree,
    joinPathFragments(__dirname, 'files/taiwind/'),
    joinPathFragments(normOptions.projectRoot),
    {
      template: '',
      configRelativeUrl: offsetFromRoot(normOptions.projectRoot),
    }
  );

  // 检查工作区是否存在配置文件taiwind-worksapce-preset.config.js,否则创建
  if (
    !tree.exists(
      joinPathFragments(tree.root, 'taiwind-worksapce-preset.config.js')
    )
  ) {
    generateFiles(
      tree,
      joinPathFragments(__dirname, 'files/twpreset/'),
      joinPathFragments(workspaceRoot),
      {
        template: '',
      }
    );
    logger.warn("Don't forget to check the preset to your tailwind.config.js");
  }

部署插件和UI库至npm

使用插件部署,会自动帮我们执行打包命令,同时该插件有安利CircleCI有需求评论区留言,我出一期相关的,

# 让项目可通过插件部署
pnpm exec nx g ngx-deploy-npm:install --projects=ui-taib-ui,nx-plugin-ui
# 部署至npm
pnpm exec nx deploy nx-plugin-ui --tag beta --access public --package-version 0.0.2
pnpm exec nx deploy ui-taib-ui --tag beta --access public --package-version 0.0.1

 pnpm exec nx deploy nx-plugin-ui --tag beta --access public --package-version 0.0.3

> nx run nx-plugin-ui:deploy --tag beta --access public --package-version 0.0.3                                          
📦 Building "nx-plugin-ui"
📦 Build target "nx-plugin-ui:build"
Compiling TypeScript files for project "nx-plugin-ui"...
Done compiling TypeScript files for project "nx-plugin-ui".
npm
notice
npm notice package: taibui-devkit@0.0.3

具体实现文章

组件库搭建二思路分享