乐趣区

关于php:使用-esbuild-来打包一个-React-库

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

退出移动版