前言
esbuild 的小名置信大家也有耳闻,它是一个十分快的 Javascript 打包工具,用 GO 语言编写,是 figma 的 cto Evan Wallace 著述的,一个 30 min 的 webpack 我的项目用 esbuild 能够分钟级运行。本文将记录应用 esbuild 来打包一个 React 库。
需要
这里我打算开发一个 react-checkbox 为例
<input type=”checkbox” checked={true}/>
<input type=”checkbox” checked={false}/>
复制代码
因为 checkbox 只有两种值:选中(checked)或未选中(unchecked),在视觉上 checkbox 有三种状态:checked、unchecked、indeterminate(不确定的),在实现全选成果时,你可能会用到 indeterminate 属性, 对于 indeterminate 这个状态无奈在 HTML 中设置 checkbox 的状态为 indeterminate。因为 HTML 中没有 indeterminate 这个属性,你能够通过 Javascript 脚本来设置
const checkbox = document.getElementById(“checkbox”);
checkbox.indeterminate = true;
复制代码
成果如下:
所以咱们的需要是须要给 checkbox 减少一个 indeterminate 属性
我的项目初始化
首先咱们来创立一个文件夹并且初始化 npm.
mkdir react-checkbox && cd react-checkbox && npm init –yes
复制代码
咱们应用 typescript,当然也要装置 react 和 react-dom
npm i esbuild typescript @types/react @types/react-dom –save-dev
复制代码
而后咱们在根目录下创立文件 ./tsconfig.json
{
“compilerOptions”: {
"outDir": "./lib",
"target": "es6",
"module": "commonjs",
"noImplicitAny": true,
"strictNullChecks": true,
"declaration": true,
"sourceMap": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"typeRoots": ["node_modules/@types"]
},
“include”: [“./src//.tsx”, “./src//.ts”, “example/index.tsx”],
“exclude”: [“node_modules”]
}
复制代码
代码实现
接下来咱们创立 src/checkbox.tsx, 上面是实现代码
import {ReactElement, CSSProperties, ChangeEvent} from “react”;
export interface CheckboxProps {
checked?: boolean;
indeterminate?: boolean;
className?: string;
style?: CSSProperties;
disabled?: boolean;
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
}
const Checkbox = ({
checked = false,
indeterminate = false,
className = “”,
style = {},
disabled = false,
onChange,
}: CheckboxProps): ReactElement => {
return (
<input
type="checkbox"
className={className}
style={style}
ref={(input) => {if (input) {
input.checked = checked;
input.indeterminate = indeterminate as boolean;
input.disabled = disabled as boolean;
}
}}
onChange={(e) => {if (onChange) {onChange(e);
}
}}
/>
);
};
export default Checkbox;
复制代码
很简略,间接应用 ref 设置 dom 属性就能够了。
代码打包
接着咱们在我的项目根目录下建设./esbuild.js 文件
写入打包配置
const esbuild = require(‘esbuild’);
esbuild
.build({entryPoints: ['src/checkbox.tsx'],
outdir: 'lib',
bundle: true,
sourcemap: true,
minify: true,
splitting: true,
format: 'esm',
target: ['esnext']
})
.catch(() => process.exit(1));
复制代码
entryPoints 和 ourdir 指定须要将哪些文件输出和打包输入目录
bundle 代表是否递归援用打包文件。
sourcemap 代表是否生成 sourcemap 源映射文件
minify 代表是否压缩代码
splitting 代表
多入口的是否提取公共代码
是否将 import() 异步文件独自打包
target 定义了咱们想要输入的 javascript 类型
format 是设置生成的 javascript 文件的输入格局,有 3 个值可选,cjs、esm、iife
iife 格局代表“立刻调用函数表达式”,能够在浏览器中运行。
cjs 格局代表“CommonJS”,在 node 中运行。
esm 格局代表“ECMAScript 模块”,既能够在浏览器中应用,也能够在 node 中应用
而后应用 node ./esbuild.js 就能够打包胜利了,然而一个 typescript 我的项目最终要提供 d.ts 进去给内部用,然而 esbuild 最终 build 进去的内容中并没有 d.ts,因而咱们要独自运行 tsc,略微批改一下下面的代码。
咱们在 package.json 中退出如下代码
“scripts”: {
"ts-types": "tsc --emitDeclarationOnly --outDir lib",
"build": "rm -rf lib && node ./esbuild.js && npm run ts-types"
},
复制代码
还是应用 tsc 的 emitDeclarationOnly 来生成 d.ts
而后咱们在 package.json 中指定入口文件
“main”: “lib/checkbox.js”,
“module”: “lib/checkbox.js”,
“types”: “lib/checkbox.d.ts”,
“files”: [
"lib"
]
复制代码
至此打包实现,如果须要发包,咱们要还须要增加测试。
本地预览
当然咱们的我的项目须要预览,建设一个 example/index.tsx 文件
import React, {ReactElement} from “react”;
import {render} from “react-dom”;
import Checkbox from “../src/checkbox”;
function App(): ReactElement {
return (
<div>
<Checkbox></Checkbox>
<Checkbox checked={true}></Checkbox>
<Checkbox indeterminate={true}></Checkbox>
</div>
);
}
render(<App />, document.querySelector(“#root”));
复制代码
这个文件作为预览 js 的打包入口;
而后建设一个./example/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>checkbox</title>
</head>
<body>
<div id="root"></div>
<script src="./bandle.js"></script>
</body>
</html>
复制代码
这个 html 就援用了 bandle.js,接下来,咱们须要打包出一个 bandle.js
建设一个./example/esbuild.js 文件,代码如下:
const esbuild = require(“esbuild”);
const path = require(“path”);
esbuild
.build({
entryPoints: [path.resolve(__dirname, "./index.tsx")],
outfile: path.resolve(__dirname, "./bandle.js"),
bundle: true,
minify: true,
target: ["esnext"],
watch: {onRebuild(error, result) {if (error) console.error("watch build failed:", error);
else console.log("watch build succeeded:", result);
},
},
format: "esm",
})
.then((result) => {
console.log("watching...");
});
复制代码
这个 esbuild.js 是打包预览文件的配置,这里开启了监听模式,这样批改 js 就会主动打包了。
而后在 package.json 的 scripts 中增加 :
“start”: ” node ./example/esbuild.js”
复制代码
接着批改 js 就会主动打包了,咱们一起来看下成果,惟一的毛病是没有热更新,咱们须要手动刷新。
小结
本文联合 react 对 esbuid 这个打包工具进行了简略应用;
esbuid 的毛病
es5 反对不是很好,不反对将 es6 转 es5。
esbuild 没有提供 AST 的操作能力 (如 babel-plugin-import)
esbuild 的长处
esbuild 除了打包速度飞快,对于 ts、css 文件的解决也是十分敌对,不须要设置各种 loader,配置简略。如果你的我的项目不须要兼容 es5、齐全能够将一些 Monorepo 的 js 库迁徙到 esbuild。
最初
如果你感觉此文对你有一丁点帮忙,点个赞。或者能够退出我的开发交换群:1025263163 互相学习,咱们会有业余的技术答疑解惑
如果你感觉这篇文章对你有点用的话,麻烦请给咱们的开源我的项目点点 star: https://gitee.com/ZhongBangKeJi 不胜感激!
PHP 学习手册:https://doc.crmeb.com
技术交换论坛:https://q.crmeb.com