前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何用 esbuild 替换 Create React App 中的 Webpack

如何用 esbuild 替换 Create React App 中的 Webpack

作者头像
chuckQu
发布2022-08-19 15:12:18
2.7K0
发布2022-08-19 15:12:18
举报
文章被收录于专栏:前端F2E

原文链接:https://devtails.xyz/how-to-replace-webpack-in-create-react-app-with-esbuild[1]

作者:Adam[2]

正文从这开始~

今年是2022年,你所有搞web开发的朋友都告诉你要学习React。为了让事情变得简单,他们告诉你有一个神器叫做create-react-app[3]。你会看到,在三个命令行的帮助下,你可以拥有一个完整配置的React应用程序运行,并为此感到高兴。

代码语言:javascript
复制
npx create-react-app my-app
cd my-app
npm start

在大约一分钟的依赖包安装和几秒钟的npm启动后,你就可以开始了。

现在你拥有了一个基础的React应用程序,你添加了几个额外的组件和页面来建立你梦寐以求的React应用程序。到目前为止,一切都很顺利,你所做的更改神奇地展示在localhost上。

最后,是时候将这个应用程序部署到网络上,并分享你的创造。为了使事情变得简单,你只需运行npm run build,并添加一个命令将文件scp到你的服务器上。

这是你第一次运行npm run build,你发现运行该命令需要花费20秒。"这是我唯一一次部署",你告诉自己,并忽略了构建所需的时间。

你加载很炫酷的新网站,却发现上面有一个错别字。你快速的修改完并重新部署。在你的改动生效之前,又要花费漫长的20秒时间。

"嗯,也许我应该更新这里的padding。" "如果这是不同的颜色呢?" "我应该添加谷歌网站分析。" 各种各样的新想法涌入你的脑海。它们中的每一个都只需要更新一行代码。然而,要让这些代码被部署起来,却要花上20-30秒。

当你意识到在刚刚部署成功后,却有一个严重bug需要被修复时,问题变得糟糕起来。问题修复起来很简单,但是我们又要花费半分钟才能上线。

这不是一个编造的故事。这是我目前在Kaizen做的一个音乐应用程序的情况。

在其他项目中,我看到生产环境构建时间已经膨胀到超过一分钟。在一个较慢的构建机器上运行时,有时需要两倍的时间。

以前,我曾写过快速迭代的重要性,三行代码不应花费一整天[4]。这个原则同样适用于部署代码。在生产环境被充分验证之前,不能声称事情已经搞定。这个过程越慢,就必须等待更长的时间才能看到代码是否按预期工作。

这篇文章演示了如何用速度更快的esbuild打包器替换create-react-app中安装的webpack打包器。

安装esbuild

代码语言:javascript
复制
npm i -D esbuild

在package.json中更新构建脚本

代码语言:javascript
复制
// package.json
"scripts": {
    "start": "react-scripts start",
    "build": "esbuild src/index.js --bundle --outfile=public/js/app.js --loader:.js=jsx",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
},

重新运行构建

代码语言:javascript
复制
npm run build

在默认的create-react-app应用程序中,你应该会看到以下错误:

esbuild-errors.png

启用JS文件的JSX语法

前两个错误建议在构建命令中加入 --loader:.js=jsxesbuild对扩展名为jsx的文件默认会进行处理,但要处理扩展名为.js的文件则需要添加上述命令。

代码语言:javascript
复制
// package.json
"build": "esbuild src/index.js --bundle --outfile=build/js/app.js --loader:.js=jsx"

添加SVG Loader

默认的应用程序使用import语法来包含一个svg图像。esbuild默认不处理这种类型的文件。为了支持这些类型的文件,esbuild提供了插件支持。你可以在这里[5]找到社区esbuild插件的列表。此时,我们将使用esbuild-plugin-inline-image来内联我们的svg图片。额外的,该插件也可以处理未来有关img的需求。

代码语言:javascript
复制
npm i -D esbuild-plugin-inline-image

为了加载新的插件,我们需要改变我们的构建命令,来使用esbuild的JavaScript API。

代码语言:javascript
复制
// build.js
const esbuild = require("esbuild");
const inlineImage = require("esbuild-plugin-inline-image");

esbuild.build({
  entryPoints: ["./src/index.js"],
  outfile: "./public/js/app.js",
  minify: true,
  bundle: true,
  loader: {
    ".js": "jsx",
  },
  plugins: [inlineImage()],
}).catch(() => process.exit(1));
代码语言:javascript
复制
// package.json
"build": "node build.js"

更改完之后,当运行npm run build 时,将会看到构建成功。

esbuild-success.png

在我的电脑上,这个构建命令现在大概需要60毫秒。比起6秒的webpack构建,快了整整100倍。但是还没结束,我们仍需要真正的看到并运行这些改动。

更新index.html

Create React App创建了一个public文件夹,里面预置了几个文件。包含在其中的index.html更像是一个模板,在运行react-scripts build时,会被处理并输出到build文件夹。

在我们新的esbuild构建中,index.html不需要成为模板。删除对%PUBLIC_URL%的引用,并添加一个script标签,指向我们新构建的app.jsapp.css包。

代码语言:javascript
复制
// public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="/logo192.png" />
    <link rel="manifest" href="/manifest.json" />
    <title>React App</title>
    <script src="/assets/app.js" async defer></script>
    <link rel="stylesheet" href="/assets/app.css"/>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

你可能想把public/js添加到你的.gitignore中,因为你可能不想在生产构建的时候进行检查。

添加serve.js来自动重新构建

代码语言:javascript
复制
// serve.js
const esbuild = require("esbuild");
const inlineImage = require("esbuild-plugin-inline-image");

esbuild
  .serve(
    {
      servedir: "public",
      port: 8000,
    },
    {
      entryPoints: ["./src/index.js"],
      outfile: "./public/js/app.js",
      bundle: true,
      loader: {
        ".js": "jsx",
      },
      plugins: [inlineImage()],
    }
  )
  .catch(() => process.exit());

替换npm start

代码语言:javascript
复制
// package.json
"start": "node serve.js"

运行npm start会在8000端口启动一个本地开发服务器,这样你就可以通过http://localhost:8000[6]进行访问。有了esbuild,你将看到应用程序会如期运行,而且初始构建和后续构建都快如闪电。

总结

只需仅仅几步,我们就将一个6秒的构建转换为60毫秒的构建。有一些地方还可以再调整一下,但这应该给你留下了一个良好的开端,也就是如何将基于webpackReact构建转换为esbuild。如前所述,我将在Kaizen的前端代码中进一步探索这种转换,并将写下我在一个更大的项目中遇到的任何问题。

参考资料

[1]

https://devtails.xyz/how-to-replace-webpack-in-create-react-app-with-esbuild: https://devtails.xyz/how-to-replace-webpack-in-create-react-app-with-esbuild

[2]

Adam: https://devtails.xyz/about/

[3]

create-react-app: https://github.com/facebook/create-react-app

[4]

三行代码不应花费一整天: https://devtails.xyz/3-lines-of-code-shouldnt-take-all-day

[5]

这里: https://github.com/esbuild/community-plugins

[6]

http://localhost:8000: http://localhost:8000

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端F2E 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装esbuild
  • 在package.json中更新构建脚本
  • 重新运行构建
  • 启用JS文件的JSX语法
  • 添加SVG Loader
  • 更新index.html
  • 添加serve.js来自动重新构建
  • 替换npm start
  • 总结
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档