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

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

上篇文章使用 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. 🤔从开源角度去思考,如何优化一个组件库 - 掘金

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

相关推荐
花花鱼3 分钟前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09337 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang135828 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning28 分钟前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人38 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
超雄代码狂1 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax
长弓三石1 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙
小马哥编程1 小时前
【前端基础】CSS基础
前端·css
嚣张农民2 小时前
推荐3个实用的760°全景框架
前端·vue.js·程序员
周亚鑫2 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf