👨面试官:如何测试不同模块的构建产物?我:呃....

不知道面试会不会问这个问题,万一呢?😛

上篇文章使用 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 构建相关的其他文章:

  1. 🎉纯干货不废话,用rollup搭建组件库,再用vite搭建测试环境 - 掘金
  2. 👊承接上文,用vite搭建rollup组件库的开发环境 - 掘金
  3. 🤔从开源角度去思考,如何优化一个组件库 - 掘金

看完这篇文章你有什么收获吗,欢迎在评论区留言

相关推荐
y先森3 分钟前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy4 分钟前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189117 分钟前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
虾球xz3 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员3 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐3 小时前
前端图像处理(一)
前端