前言
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