本篇为翻译的文章,由于笔者能力有限,倘若阅读体验不好,可点击原文地址查看,原文地址:Rollup Config for React Component Library With TypeScript + SCSS
前言
在这篇文章中,我将尝试覆盖在构建React
组件库时使用Rollup
配置发挥作用的关键领域(特别是TypeScript
和SCSS
)。
同时,我将会为使用到的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
主题范围
请跳转到你感兴趣的部分
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
中设置的包,在我的例子中,,就是react
和react-dom
两个包
TypeScript 配置
以下是我的tsconfig
文件。我有2个,一个是Rollup
用于构建,另一个类似于基本配置,主要是用于开发
背后的原因是,我想排除我的Storybook stories files被TypeScript
转译。它只用于开发时,我需要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
,在node_modules
中查找和捆绑第三方依赖项。这里所指的依赖关系是package.json
文件中列出的依赖关系(dependencies
)。
对于Rollup
,将CommonJS
模块转换为ES6
,以便将其包含在Rollup
捆绑包中。它通常与@rollup/plugin-node-resolve
一起使用,以捆绑CommonJS
依赖项。
帮助以更简单的方式与TypeScript
集成。包括将TypeScript
转换为JavaScript
等内容。
与PostCSS
集成。对于我的用例,它有助于将CSS
和SCSS
文件分别构建为*.CSS.js
和*.SCSS.js
文件。然后,当导入相应的组件时,这些文件会相应地注入HTML head
标签(依赖于style-inject)
在我目前的开发中,我已经改用样式化组件,而倾向于在
JS
模式中尝试CSS
。
此插件用于帮助我们分析捆绑输出。它将为我们的检查生成一个很酷的可视化。在进行捆绑包大小优化时,它特别有用,因为它可以让我们可视化捆绑包文件的各个大小。
它基本上是一个插件,用于集成terser的用法。它有助于缩小和压缩我们的输出JavaScript
文件。
总结
在使用Rollup
和Webpack
构建使用TypeScript
和SCSS
的React
组件库之后。。。我不得不说,只是为了这个目的而疯狂地使用Rollup
。与Webpack
相比,它更易于配置。
单是配置的复杂性就足以让我跳过去。我希望有一个配置文件,我可以在任何时间点轻松推理,而不是一些冗长复杂的东西,我可能会在几周内忘记正在做什么!
然而,我可能不一定对应用程序开发有同样的感觉,因为Webpack
具有真正强大的热模块替换功能。这绝对是一个救命稻草,也是应用程序开发的必备工具。
构建工具的前景正在发生变化,如果第二天出现另一个事实上的bundler
,并在社区中掀起风暴,这可能并不奇怪!但至少现在,Rollup
是我的新情人😛
参考
- https://github.com/rollup/plugins
- https://rollupjs.org/guide/en/
- https://marcobotto.com/blog/compiling-and-bundling-typescript-libraries-with-webpack/
- https://github.com/HarveyD/react-component-library
- https://github.com/rollup/rollup-plugin-commonjs
本文分享自作者个人站点/博客: https://www.yxlazy.xyz
欢迎评论留言