9月7日-8日,相约 2023 腾讯全球数字生态大会!聚焦产业未来发展新趋势! 了解详情
写点什么

esbuild:一款快 10-100 倍的 JS 打包 / 压缩工具

  • 2020-03-10
  • 本文字数:2155 字

    阅读完需:约 7 分钟

esbuild:一款快10-100倍的JS打包/压缩工具

为什么又造个轮子?

为什么又要构建一个 JavaScript 构建工具呢?因为当前用于 Web 的构建工具比用户期望的性能至少慢一个数量级。我希望这个项目可以作为一种“存在证明”,证明我们的 JavaScript 工具实际上能比现在快得多。

基准测试

我想到的用例是打包用于生产的大型代码库。这个流程包括压缩代码以减少网络传输时间,以及生成源映射(对于调试生产中的错误是非常重要的)。理想情况下,构建工具还应该具备快速构建能力,而不必先预热缓存。


我的主基准测试会将 three.js 库复制 10 次并从头开始构建单个包,过程中没有任何缓存,从而模拟一个大型代码库。在这个基准测试中,esbuild 比我测试的其他 JavaScript 打包器(Webpack、Rollup、Parcel 和 FuseBox)快 10-100 倍。这个基准测试可以使用’make bench-three’来运行。




时间数据取三次运行中最好的一次,主要运行环境如下:


  • 使用’–bundle --minify --sourcemap’来运行 esbuild。

  • 使用’rollup-plugin-terser’插件,因为 rollup 自身不支持压缩。

  • Webpack 使用的是’–mode = production --devtool = sourcemap’。

  • Parcel 使用默认选项。

  • FuseBox 使用’useSingleBundle: true’配置。

  • 绝对速度基于总行数(包括注释和空白行),当前为 547,441。

  • 测试是在配备 16GB RAM 的 6 核 2019 MacBook Pro 上完成的。

为什么这么快?

几个原因:


  • 它是用 Go 语言编写的,该语言可以编译为原生代码;

  • 解析,打印和源映射生成全部完全并行化;

  • 无需昂贵的数据转换,只需很少的几步即可完成所有操作;

  • 编写代码时处处注意速度表现,并尽量避免不必要的配置。

状态

目前支持:


  • CommonJS 模块

  • ES6 模块

  • 使用’–bundle’与 ES6 模块的静态绑定打包

  • 使用’–minify’完全压缩(空格、标识符和修饰符)

  • 启用’–sourcemap’时,完全支持源映射

  • .jsx 文件的 JSX 到 JavaScript 转换

  • 通过’–define’进行编译时标识符替换

  • 使用 package.json 中的’browser’字段进行路径替换

  • 自动检测 tsconfig.json 中的’baseUrl’


这是我在 2019-2020 年寒假期间写的一项业余爱好项目。我相信它是相对完整和实用的。但它是全新的代码,可能有很多错误。还没有任何人在生产中使用过它。使用风险自负。


还请记住,它并不完全支持将现代语言语法降低到早期语言版本。目前只有类字段和 nullish 合并运算符是支持的。


我个人不想运营一个大型的开源项目,因此我目前没在寻求贡献。

安装

如果你已安装 Go 语言工具链,可以使用’make’生成可执行文件。当前可在 npm 上的单独软件包中找到预构建的二进制文件:


npm install -g esbuild-linux-64   # for Linuxnpm install -g esbuild-darwin-64  # for macOSnpm install -g esbuild-windows-64 # for Windowsnpm install -g esbuild-wasm       # for all other platforms
复制代码


这将添加一个名为’esbuild’的命令。

用法

命令行界面获取入口点列表,并为每个入口点生成一个打包文件。以下是可用的选项:


Usage:  esbuild [options] [entry points]
Options: --name=... 模块名称 --bundle 将所以依赖项打包进输出文件 --outfile=... 输出文件 (用于一个入口点) --outdir=... 输出目录 (用于多个入口点) --sourcemap 发出一个源映射 --error-limit=... 最大错误计数,0是禁用 (默认值为10) --target=... 语言目标 (默认esnext)
--minify 设置所有 --minify-* flags --minify-whitespace 移除空格 --minify-identifiers 缩短标识符 --minify-syntax 使用较短的等效语法
--define:K=V 解析时用V替换K --jsx-factory=... 用来替换React.createElement的内容 --jsx-fragment=... 用来替换React.Fragment的内容
--trace=... 在这个文件中写入一个CPU trace --cpuprofile=... 在这个文件中写入一个CPU profile
Example: # Produces dist/entry_point.js and dist/entry_point.js.map esbuild --bundle entry_point.js --outdir=dist --minify --sourcemap
复制代码

与 React 一起使用

要将 esbuild 与 React 一起使用:


  • 确保所有 JSX 语法都放在.jsx 文件而不是.js 文件中,因为 esbuild 使用文件扩展名来确定要解析的语法。

  • 如果你使用的是 TypeScript,请先运行’tsc’以将.tsx 文件转换为.jsx 或.js 文件。

  • 如果你使用 esbuild 打包 React 自身,而不是在 HTML 中使用<script>标记添加它,则需要传递 ‘–define:process.env.NODE_ENV=“development”’ 或’–define:process.env.NODE_ENV=“production”'以在命令行上运行 esbuild。

  • 如果你使用的是 Preact 而不是 React,则还需要传递–jsx-factory = preact.h --jsx-fragment = preact.Fragment 在命令行上运行 esbuild。


例如,如果你有一个名为 example.jsx 的文件,其中包含以下内容:


import * as React from 'react'import * as ReactDOM from 'react-dom'
ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root'));
复制代码


那么用于开发构建:


esbuild example.jsx --bundle '--define:process.env.NODE_ENV="development"' --outfile=out.js
复制代码


用于生产构建:


esbuild example.jsx --bundle '--define:process.env.NODE_ENV="production"' --minify --outfile=out.js
复制代码

项目地址

https://github.com/evanw/esbuild


活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2020-03-10 11:115373
用户头像
小智 让所有人认同的文字称不上表达

发布了 408 篇内容, 共 366.8 次阅读, 收获喜欢 1958 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

springBoot中redis的自动装配

Rubble

8月日更

百度地图开发-搭建基础脚手架 01

Andy阿辉

android Android Studio 8月日更

Linux之yum命令

入门小站

Linux

摸鱼小技巧之IDEA调试篇一~

4ye

Java debug 后端 IDEA 8月日更

Battle:你会TLAB,我会逃逸分析

阿Q说代码

逃逸分析 8月日更 栈上分配 同步省略 标量替换

前端人员必会工具-apipost两分钟上手(2分钟玩转apipost)

Proud lion

大前端 测试 后端 Postman 开发工具

微信业务架构图 & 学生管理系统

I see you

儿子教会我的态度

箭上有毒

8月日更

极客时间架构实战营作业一

jjn0703

架构实战营

在openGauss上做开发?这个大赛拿出30万寻找开源的你

华为云开发者联盟

数据库 开源 信创 opengauss 鲲鹏

Go Channel实例剖析

非晓为骁

源码 channel Go 语言 实例分析

如何构建 Spring Boot 12 因素应用

码语者

Sprint Boot

神策分析 iOS SDK 全埋点解析之启动与退出

神策技术社区

ios 代码 埋点 神策数据

“挂图作战”网络实体定位技术

郑州埃文科技

container 包详解

Rayjun

Go 语言

判断是否为数组的 JavaScript 方法总结

编程三昧

JavaScript 数组 8月日更

docker入门:elk环境安装记录

小鲍侃java

8月日更

Go- if-else结构

HelloBug

if Go 语言 else

统计机器学习导论(一)

数据与智能

机器学习 统计

WEB常用HTML颜色代码表

入门小站

工具

Windows Server 内存高排查

耳东@Erdong

windows 内存 Windows Server 8月日更 rammap

国产数据库的挑战与机遇

晨山资本

数据库 大数据 云原生 超融合

apipost--接口流程化测试

与风逐梦

软件测试 接口测试 软件自动化测试

混合云时代来临,你的存储ready了吗?

焱融科技

云计算 分布式 高性能 云存储 混合云

遇见低码:在价值中审视

华为云开发者联盟

ide 低代码 应用 开发语言 低成本

FusionInsight怎么帮「宇宙行」建一个好的「云数据平台」?

华为云开发者联盟

大数据 数据仓库 FusionInsight 云数据平台 LakeHouse

多看了几套房

escray

生活记录 8月日更

手撸二叉树之另一棵树的子树

HelloWorld杰少

数据结构与算法 8月日更

通过 UIView 和 UIControl 实现的蒙层,哪种更简单?

fuyoufang

swift iOS 知识体系 8月日更

自适应负载均衡算法原理与实现

万俊峰Kevin

负载均衡 微服务 负载均衡算法 Go 语言

MySQL远程连接

一个大红包

8月日更

  • 扫码添加小助手
    领取最新资料包
esbuild:一款快10-100倍的JS打包/压缩工具_GMTC_Evan Wallace_InfoQ精选文章