使用Rollup,TypeScript,SCSS配置React组件库

本文介绍了如何使用Rollup配置构建React组件库,特别是与TypeScript和SCSS的集成。作者通过对比Webpack,强调Rollup在库构建中的简洁性和效率,并分享了自己的Rollup配置文件、代码分割方法及所用插件的说明。文章还提到了TypeScript配置文件的细节,并讨论了代码可视化和压缩工具的使用。
摘要由CSDN通过智能技术生成

本篇为翻译的文章,由于笔者能力有限,倘若阅读体验不好,可点击原文地址查看,原文地址:Rollup Config for React Component Library With TypeScript + SCSS

前言

在这篇文章中,我将尝试覆盖在构建React组件库时使用Rollup配置发挥作用的关键领域(特别是TypeScriptSCSS)。

同时,我将会为使用到的Rollup插件写一些说明,来说明插件的作用。

我绝对不是Rollup的大师,也不是构建React组件库的权威指南。我仅仅只是分享了用于构建我自己的React组件库(Codefee-Kit)时的Rollup配置,这只是我自己的一个笔记,或许能帮到一些人。

顺便说一下,组件库托管在Github

动机

在此之前,我使用webpack去构建库。当时,我在获得第一个工作版本时遇到了很多麻烦。我仍然记得有个属性叫"library",为了让webpack对库收集信息,你需要显示设置。我很傻,在我明白整个事情之前我在谷歌上搜索了很多信息。在整个踩坑过程中投入了大量时间。我当然不喜欢那里的配置文件的复杂性。嗯,是谁?哈哈哈

尽管如此,当时的工作版本并没有得到很好的优化。我的意思是,没有配置任何代码分割,构建的输出总是一个越来越大的index.js文件

最近,我终于又有了一些空闲时间!因此,我决定重新审视这个话题。在Webpack中对如何进行代码拆分进行了一些深挖,我只是觉得它太麻烦了。

最后,我决定彻底停止,然后跳到另一个流行的构建库的选择——Rollup!而且,它的配置简单得多,而且节省了我很多时间!天啊,我为什么不早点跳过去?!去我的!

有一句话是这样说的,“Rollup for libraries, Webpack for apps”。事实证明,在这一点上,它仍然非常重要!

“Rollup for libraries, Webpack for apps” https://medium.com/@PepsRyuu/why-i-use-rollup-and-not-webpack-e3ab163f4fd3

主题范围

请跳转到你感兴趣的部分

  1. Rollup 配置文件
  2. Rollup 代码分割
  3. Rollup 插件说明

Rollup 配置文件

这是适用于我的配置文件。那里有相当多的活动部件,但我尽可能地把它清理干净,这样就不会太伤眼睛了哈哈。。。😛

rollup.config.js

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';

import postcss from "rollup-plugin-postcss";
import visualizer from 'rollup-plugin-visualizer';
import { terser } from 'rollup-plugin-terser';
import { getFiles } from './scripts/buildUtils';

const extensions = ['.js', '.ts', '.jsx', '.tsx'];

export default {
  input: [
    './src/index.ts',
    ...getFiles('./src/common', extensions),
    ...getFiles('./src/components', extensions),
    ...getFiles('./src/hooks', extensions),
    ...getFiles('./src/utils', extensions),
  ],
  output: {
    dir: 'dist',
    format: 'esm',
    preserveModules: true,
    preserveModulesRoot: 'src',
    sourcemap: true,
  },
  plugins: [
    resolve(),
    commonjs(),
    typescript({
      tsconfig: './tsconfig.build.json',
      declaration: true,
      declarationDir: 'dist',
    }),
    postcss(),
    terser(),
    visualizer({
      filename: 'bundle-analysis.html',
      open: true,
    }),
  ],
  external: ['react', 'react-dom'],
};

正如你所看到的,为了让Rollup工作,你仅仅只需要导出一个JSON对象。当然,如果你有多个配置需要配置,你也能导出一个数组。例如构建不同的目标文件时,像umd,cjs

我在这里配置了4个属性:

  • input - 打包文件的入口。可以是字符串或者字符串数组
  • output - 打包文件的输出配置,例如配置打包输出的文件夹,配置sourcemap生成等
  • plugins - 外部包调用,帮助操作、更改构建行为,例如TypeScript, SCSS
  • external - 不需要打包进构建包中的包,通常是指peerDependencies中设置的包,在我的例子中,,就是reactreact-dom两个包
TypeScript 配置

以下是我的tsconfig文件。我有2个,一个是Rollup用于构建,另一个类似于基本配置,主要是用于开发

背后的原因是,我想排除我的Storybook stories filesTypeScript转译。它只用于开发时,我需要tsconfig。因此,创建了一个带有excludes的单独的配置文件

tsconfig.build.json

{
  "extends": "./tsconfig.json",
  "exclude": [
    "node_modules",
    "build",
    "dist",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/stories/**"
  ]
}

tsconfig.json

{
  "compilerOptions": {
    "module": "esnext",
    "target": "es5",
    "lib": [ "es6", "dom" ],
    "sourceMap": true,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": "src",
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "esModuleInterop": true,
    "baseUrl": "src/",
    "paths": {
      "common": ["src/common/*"],
      "components": ["src/components/*"],
      "hooks": ["src/hooks/*"],
      "utils": ["src/utils/*"]
    }
  },
  "exclude": [
    "node_modules",
    "build",
    "dist",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest"
  ],
  "types": ["typePatches"]
}

Rollup 代码分割

在上面的配置中,我实际上使用了Rollup的代码分割 (code-splitting) 功能。

如果您注意到,我导出的JSON对象中的input属性实际上是字符串数组,而不是单个字符串。这实际上告诉Rollup将这些字符串中的每一个作为构建的单独入口点。所以,这就是代码分割构建。

数组中的所有这些字符串实际上是我在src文件夹中拥有的单个.ts.tsx文件的相对路径。getFiles方法是我编写的一个实用方法,它帮助我深入检索所有扩展名为.js、.jsx、.ts.tsx的文件。

下面是getFiles方法的代码:

const fs = require('fs');

export const getFiles = (entry, extensions = [], excludeExtensions = []) => {
  let fileNames = [];
  const dirs = fs.readdirSync(entry);

  dirs.forEach((dir) => {
    const path = `${entry}/${dir}`;

    if (fs.lstatSync(path).isDirectory()) {
      fileNames = [
        ...fileNames,
        ...getFiles(path, extensions, excludeExtensions),
      ];

      return;
    }

    if (!excludeExtensions.some((exclude) => dir.endsWith(exclude))
      && extensions.some((ext) => dir.endsWith(ext))
    ) {
      fileNames.push(path);
    }
  });

  return fileNames;
};

Rollup 插件说明

以下是我在上面的配置文件中使用的插件,以及使用它们后我的一些解释和理解。

@rollup/plugin-node-resolve

对于Rollup,在node_modules中查找和捆绑第三方依赖项。这里所指的依赖关系是package.json文件中列出的依赖关系(dependencies)。

@rollup/plugin-commonjs

对于Rollup,将CommonJS模块转换为ES6,以便将其包含在Rollup捆绑包中。它通常与@rollup/plugin-node-resolve 一起使用,以捆绑CommonJS依赖项。

@rollup/plugin-typescript

帮助以更简单的方式与TypeScript集成。包括将TypeScript转换为JavaScript等内容。

rollup-plugin-postcss

PostCSS集成。对于我的用例,它有助于将CSSSCSS文件分别构建为*.CSS.js*.SCSS.js文件。然后,当导入相应的组件时,这些文件会相应地注入HTML head标签(依赖于style-inject

在我目前的开发中,我已经改用样式化组件,而倾向于在JS模式中尝试CSS

rollup-plugin-visualizer

此插件用于帮助我们分析捆绑输出。它将为我们的检查生成一个很酷的可视化。在进行捆绑包大小优化时,它特别有用,因为它可以让我们可视化捆绑包文件的各个大小。

rollup-plugin-terser

它基本上是一个插件,用于集成terser的用法。它有助于缩小和压缩我们的输出JavaScript文件。

总结

在使用RollupWebpack构建使用TypeScriptSCSSReact组件库之后。。。我不得不说,只是为了这个目的而疯狂地使用Rollup。与Webpack相比,它更易于配置。

单是配置的复杂性就足以让我跳过去。我希望有一个配置文件,我可以在任何时间点轻松推理,而不是一些冗长复杂的东西,我可能会在几周内忘记正在做什么!

然而,我可能不一定对应用程序开发有同样的感觉,因为Webpack具有真正强大的热模块替换功能。这绝对是一个救命稻草,也是应用程序开发的必备工具。

构建工具的前景正在发生变化,如果第二天出现另一个事实上的bundler,并在社区中掀起风暴,这可能并不奇怪!但至少现在,Rollup是我的新情人😛

参考

  1. https://github.com/rollup/plugins
  2. https://rollupjs.org/guide/en/
  3. https://marcobotto.com/blog/compiling-and-bundling-typescript-libraries-with-webpack/
  4. https://github.com/HarveyD/react-component-library
  5. https://github.com/rollup/rollup-plugin-commonjs

本文分享自作者个人站点/博客: https://www.yxlazy.xyz
欢迎评论留言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值