不知道面试会不会问这个问题,万一呢?😛
上篇文章使用 rollup 对组件库进行构建,构建产物有三种模块,分别是 esm 模块,umd 模块,iife 模块。具体构建过程可以看这篇文章:🤔从开源角度去思考,如何优化一个组件库 - 掘金
这篇文章分享的是如何对不同模块的构建产物进行测试
下面开始
回顾
先来回顾组件库的内容
组件库中,准备了两个组件,Button,Input
样式也是随便写的,长下面这样:
构建产物放在了 dist 文件夹下面
packagejson 中也对引入路径做了设置:
json
{
"main": "./dist/umd/rollup-build.js",
"types": "./dist/types",
"module": "./dist/es/index.js",
}
如果调用方是在 esm 模式下引入的,就会得到 es 文件夹下面的文件;如果是在 commonjs 模式下引入的,就会得到 umd 文件夹下面的文件。
iife 构建文件没有准备的入口,因为这个模块的使用场景是在浏览器中的 script,测试的时候直接 copy 这个文件到 html 文件中就可以了
测试 ESM 模块
现来测试 ESM 模块的构建产物
在之前的文章中提到过,在另外一个项目中,通过 npm link 的方式链接到本地组件库项目,然后在代码中使用 import 语句就可以调用构建产物中的组件了
因为是 import 引入的,所以会被当成是 esm 模式导入,所以测试到的文件就是 dist/es
文件夹下面的
具体过程可以看这篇文章:用rollup搭建组件库--测试构建产物
测试 UMD 模块
UMD 模块可以在 commonjs 模块中使用,也可以直接在 script 的场景直接引入。
- 如果使用 require 的方式引入组件库组件,就会得到
dist/umd
下的文件,这是测试 commonjs 场景的思路。 - 对于 script 的场景,就需要 copy 构建产物的路径到 html 文件中了。具体操作可以往下看
commonjs 模块中使用
在 esm 模块的测试基础上,添加一个 require 引入组件的方式就可以了。
准备一个 CustomButton.jsx 文件:
jsx
const { Button } = require("rollup-build");
const CustomButton = () => {
return (
<div>
<Button contents='custom Button' />
</div>
);
};
module.exports = CustomButton;
可以看到这里使用的是 commonjs 语法。然后在入口文件中引入它:
jsx
// index.tsx
import * as ReactDOM from 'react-dom/client'
import CustomButton from './CustomButton.jsx'
const App = () => {
return <div>
App App App
<CustomButton />
</div>
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />)
保存,刷新浏览器:
发现报错了,查了下,是因为 vite 并不支持 commonjs 模块的文件解析,所以需要加上一个插件:
javascript
//vite.config.js
import commonjs from "vite-plugin-commonjs";
export default {
plugins: [viteReact(), commonjs()],
}
保存,再刷新浏览器:
组件出现了,但是没有预期中的样式,按钮应该是蓝色,而不是原生的灰色。
原来组件库在构建的时候,将 css 单独构建成一个文件了,在调用方需要单独引入。这一点和 antd 一致。
javascript
//index.tsx
import * as ReactDOM from 'react-dom/client'
import CustomButton from './CustomButton.jsx'
//引入样式文件
import "rollup-build/dist/es/rollup-build.css"
const App = () => {
return <div>
App App App
<CustomButton />
</div>
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />)
保存,再刷新浏览器:
组件正常显示,umd 模块下的 commonjs 导入没有问题
搞定🤝
script 场景下使用
script 场景测试需要在 vite buid 之后。vite build 过程中,将 react,react-dom, 组件库 rollup-build全都 external 掉,不打包,然后在 build 之后的 index.html 中,额外将 react,react-dom,rolluo-build 都用 script 导入,最后用浏览器打开 index.html,就知道 umd 模块的构建产物在 script 场景下是否可以正常使用了
组件库 package.name 是 rollup-build
external 需要vite-plugin-externals
插件,修改下 vite 配置文件:
javascript
import viteReact from "@vitejs/plugin-react";
import commonjs from "vite-plugin-commonjs";
import { viteExternalsPlugin } from "vite-plugin-externals";
/**@type {import('vite').UserConfig} */
export default {
plugins: [
viteReact(),
commonjs(),
viteExternalsPlugin({
react: "React",
"react-dom": "ReactDOM",
"rollup-build": "RB",
})
],
server: {
port: 8080,
open: "/",
},
};
配置vite-plugin-externals
,将三个库都 external 出去,并且设置好每个库在全局环境下的变量名
先准备一个基础 vite 项目,并且支持 react 的解析
组件库在构建时,设定的全局变量名就是 RB
添加一个 npm script
json
{
"scripts": {
"build": "vite build",
},
}
执行npm run build
花费了 188ms,生成了三个文件,一个 html,一个 js,一个 css
这是 html 中的内容:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>use-rollup</title>
<script type="module" crossorigin src="./assets/index-8wqCi6qd.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index--sNeZMP7.css" />
</head>
<body>
<div id="root"></div>
</body>
</html>
vite 为我们自动引入了 build 好的文件 js 和 css 文件,下面我们需要手动将 external 的库引入进 html 中。我事先将三个库的 js 文件放到了 src 同机目录下的 pro 目录中:
react 和 react-dom 是从 node_modules 中拷贝来的,rollup-build 也是从 dist/umd
中拷贝过来的。
将这三个文件引入进 html 中:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>use-rollup</title>
<script type="module" crossorigin src="./assets/index-8wqCi6qd.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index--sNeZMP7.css" />
</head>
<body>
<div id="root"></div>
<!-- 添加额外的script文件 -->
<script src="../prod/react.development.js"></script>
<script src="../prod/react-dom.development.js"></script>
<script src="../prod/rollup-build.js"></script>
</body>
</html>
然后启动一个本地服务器,打开这个 html 文件:
显示正常,没有问题。
到这里,测试 umd 模块的两个场景都已测试成功🏅
iife 模块
测试 iife 模块,和 umd 模块的 script 场景测试过程相同,就不赘述了
测试体验优化
不过,script 场景的测试有些麻烦。
第一点:需要手动 copy 文件,和手动修改 index.html 文件,这不太友好。我们可以借助 vite 插件,来自动生成一个动态的 html,生成 html 可以自定义插入任何 script 脚本
第二点:external 只适应于build 模式,而不能用于普通的 dev 模式,所以两者的配置文件是不相同,需要分开来
针对上面两点,我们可以在项目根目录中创建一个新的配置文件 vite.config.test.js
:
javascript
// vite.config.test.js
// 导出普通的配置文件
import viteConfig from "./vite.config.js";
import { viteExternalsPlugin } from "vite-plugin-externals";
import { createHtmlPlugin } from "vite-plugin-html";
// 生成需要插入的script脚本
const getscript = () => {
const sources = ["../prod/react.development.js", "../prod/react-dom.development.js", "../prod/rollup-build.js"];
return sources
.map((item) => {
return `<script src='${item}'></script>`;
})
.join("\n");
};
// 在原先的基础之上添加两个plugin
viteConfig.plugins.push(
viteExternalsPlugin({
react: "React",
"react-dom": "ReactDOM",
"rollup-build": "RB",
}),
// 基于public/index.html, 将其作为tamplate
createHtmlPlugin({
minify: false,
entry: "../src/index.tsx",
template: "public/index.html",
inject: {
data: {
injectScript: getscript(),
},
},
})
);
export default viteConfig;
新配置文件基于原先的普通配置文件,在基础上添加了两个插件,用作测试 script 场景下的构建产物
createHtmlPlugin 插件基于public/index.html
,这个 html 文件需要单独准备,其中支持 ejs 语法。该插件正是基于 ejs 语法来做插入 script 脚本操作的
public/index.html
的内容:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>use-rollup</title>
</head>
<body>
<div id="root"></div>
<%- injectScript %>
</body>
</html>
总结:
这篇文章分享了如何测试组件库的构建产物,该测试方法不仅适用于 rollup 构建的库,还适用于所有的构建产物
与 rollup 构建相关的其他文章:
看完这篇文章你有什么收获吗,欢迎在评论区留言