发布于 2026-01-06 0 阅读
0

🔥🔥🔥 隆重推出 ESBuild,编译速度飞快!!!

🔥🔥🔥 隆重推出 ESBuild,编译速度飞快!!!

目前项目热更新速度越来越慢,因此出现了这篇文章,这是一篇教程文章,当前设置是基于公司开发环境,此示例是之前测试和操作的。本文教程代码与实际项目代码或存在一定差异,如果合作伙伴也想为公司项目引入esbuild打包,可以留言。

由于公司的项目比较老旧,我主要谈的是开发环境下的工作经验。

🔥 创建一个基本的 CRA 项目

让我们从创建一个基本的 React 项目开始。

yarn create react-app my-app
Enter fullscreen mode Exit fullscreen mode

预览文件夹

2021-10-16 15.17.42.gif

创建测试项目之后,让我们看看引入 esbuild 需要解决哪些问题?

  1. 我们需要一个本地服务器来显示打包后的文件。
  2. 还需要一个用于解析命令行参数的库,以便传递开发环境所需的变量。
  3. 每次启动项目时,还需要删除最后一个打包的文件。
  4. 此外,还需要解决端口号的问题。
  5. 解决svg 图标问题
  6. 引入 esbuild 用于打包。

上述问题解决后,我们就可以实现这个演示了。

🔥 下载依赖包

yarn add browser-sync --dev
Enter fullscreen mode Exit fullscreen mode

该软件包的主要目的是创建服务器、渲染打包文件,并监听指定文件中的文件更改,以便 esbuild 重新打包。

yarn add chalk --dev
Enter fullscreen mode Exit fullscreen mode

该软件包的主要目的是美化终端的字符样式。

yarn add command-line-args --dev
Enter fullscreen mode Exit fullscreen mode

这是一个主要用于解析命令行参数的库,我们主要用它来确认是否处于开发环境。

yarn add del --dev
Enter fullscreen mode Exit fullscreen mode

我们主要使用此软件包对打包的文件或文件夹执行删除操作。

yarn add get-port@5.1.1 --dev
Enter fullscreen mode Exit fullscreen mode

我们主要使用这个库来获取当前可用的 TCP 端口号。我没有安装最新版本,因为最新版本对 Node.js 有要求,我的 Node 版本是 v12.18.3,而它要求的 Node 版本是:"^12.20.0 || ^14.13.1 || >=16.0.0"。

我们将 public 文件夹复制并重命名为 public-dev,该文件夹中的 index.html 是我们应用程序的入口点。

yarn add --dev esbuild-plugin-svgr
Enter fullscreen mode Exit fullscreen mode

为 esbuild 添加插件,支持将*.svg文件作为 React 组件导入。

yarn add esbuild --dev
Enter fullscreen mode Exit fullscreen mode

最后一步是安装esbuild。

🔥 修改 package.json

    "scripts": {
        ...
+++     "dev": "node devBuild.js --dev"
      },
      ...
+++ "type": "module"
Enter fullscreen mode Exit fullscreen mode

🔥 创建 devBuild.js

修改 package.json 文件后,接下来在根文件夹中创建 devBuild.js 文件。

import browserSync from "browser-sync";
import chalk from "chalk";
import commandLineArgs from "command-line-args";
import del from "del";
import esbuild from "esbuild";
import getPort from "get-port";
import svgrPlugin from "esbuild-plugin-svgr";
// Create the server.
const bs = browserSync.create();
// Deconstructing environment variables
const { dev } = commandLineArgs({ name: "dev", type: Boolean });
// Delete the package folder from the public-dev folder
del.sync("./public-dev/dist");

// Start esbuild to build the package
(async () => {
  const buildResult = await esbuild
    .build({
      format: "esm", // Sets the output format of the generated JavaScript file.
      target: "es2017", // Compile to convert version
      entryPoints: ["./src/index.jsx"], // Packed Entrance
      outdir: "./public-dev/dist", // Output Directory
      chunkNames: "chunks/[name].[hash]", // Packed out file name
      incremental: dev, // Because we are listening for file changes to repack, and we want the development environment to use esbuild, dev is true.
      loader: {
        // This option changes the way the given input file is interpreted.
        ".svg": "text",
        ".png": "dataurl",
      },
      bundle: true, // Bundling files means inlining any imported dependencies into the file itself.
      splitting: true, // Code splitting is currently only available for esm output format.
      plugins: [svgrPlugin()],
      inject: ["./public-dev/react-shim.js"], // Import React into esbuild as a global variable
    })
    .catch((err) => {
      console.error(chalk.red(err));
      process.exit(1);
    });
  console.log(chalk.green("The build has finished! 📦\n"));
  // Get the port number that can be used
  const port = await getPort({
    port: getPort.makeRange(4000, 4999),
  });

  console.log(
    chalk.cyan(
      `Launching the Shoelace dev server at http://localhost:${port}! 🥾\n`
    )
  );
  // Server initialization
  bs.init({
    startPath: "/", // Initial path
    port, // Port number
    logLevel: "silent", // Log level
    logFileChanges: true, // Log file changes
    notify: true, // Small pop-up notifications in the browser
    single: true, // Provide separate index.html
    server: {
      baseDir: "public-dev", // Base Folder
      index: "index.html", // Set the server's entry file
    },
    files: "src/", // Listening to files under src
  });

  // Listening for changes under the src folder
  bs.watch(["src/"]).on("change", async (filename) => {
    console.log(`Source file changed - ${filename}`);
    // Repackaging
    buildResult.rebuild();
  });
})();

Enter fullscreen mode Exit fullscreen mode

🔥 index.html

因为我不想直接修改 public 文件下的内容,所以我直接复制了 public 文件夹并将其重命名为 public-dev。我为什么要这样做呢?主要是因为我不想影响 webpack 打包的文件。所以我直接复制了一个文件夹。

在 index.html 文件中,我们需要引入打包好的 CSS 和 JS 文件。这里引入 JS 文件时要格外小心,必须使用 ESM 方式引入,否则会报错!

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <link rel="icon" href="%PUBLIC_URL%/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="%PUBLIC_URL%/logo192.png" />
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
++  <link rel="stylesheet" type="text/css" href="./dist/index.css" />
  <title>React App</title>
</head>

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
++  <script type="module">
++    import './dist/index.js'
++  </script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

将组件后缀名称更改为.jsx

🔥 react-shim.js

创建此文件的主要目的是将 React 作为全局变量导入 esbuild,这样就不需要在每个组件中引入 React 了。

import * as React from "react";
export { React };
Enter fullscreen mode Exit fullscreen mode

🔥 修改 App.jsx

关键在于需要更改 SVG 的使用方式。这是因为esbuild-plugin-svgr必须符合插件的使用规范。

此外,将所有带有先前 js 后缀的组件名称更改为 jsx也至关重要。

++ import Logo from "./logo.svg";
import "./App.css";

function App() {
  return (
    <div className="App">
      <header className="App-header">
++        <Logo className="App-logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

现在在 CRA 中引入 esbuild 是可以的!如果您感兴趣,不妨尝试一下!

🔥 预览演示

2021-10-16 18.29.06.gif

文章来源:https://dev.to/liujinyi/introducing-esbuild-compiling-is-straight-up-fast-59n7