This is the third day of my participation in the August More text Challenge. For details, see: August More Text Challenge

Understand esbuild

What is esbuild

The official description of ESBuild is what it is: a JavaScript packaging and compression tool. Esbuild is developed using Golang and is very fast in packaging. The vite tools we are familiar with use esbuild for packaging in Dev mode.

Main features of ESbuild

  • Extreme performance without caching
  • Support for ES6 Tree shaking
  • Native support for typescript and JSX packaging
  • Support the Source Map
  • Code compression
  • Support for defining plug-ins

Comparison of packing speed

One of the most important features of esBuild is extreme performance. For details on how fast it is, see the esBuild official chart

As you can see, esBuild is over 100 times faster than mainstream packaging tools today. You can see how scary it is in terms of performance.

Because the current mainstream packaging tools are still executed in the JS execution environment, the CPU can not be fully used, so the execution speed will be slow.

Esbuild use

Now that you know the esbuild concept, let’s take a look at some of the main concepts of how to use esBuild

API

  • This API can be called to convert ts, JSX and other files to JS files. Supported files are:

    export type Loader = 'js' | 'jsx' | 'ts' | 'tsx' | 'css' | 'json' | 'text' | 'base64' | 'file' | 'dataurl' | 'binary' | 'default';
    Copy the code

    Using Transform we first create a test TS file

        // test.ts
        const str: string = 'Hello World';
    Copy the code

    Transform to JS using transform

        // cli
        exbuild ./test.ts --loader=ts // Output const STR = 'Hello World';
        
        // The js API call
        const esbuild = require('esbuild');
        const fs = require('fs');
        const path = require('path');
        const filePath = path.resolve(__dirname, 'test.ts');
        const code = esbuild.transformSync(fs.readFilesync(filePath), {
            loader: 'ts',})console.log(code);
        / / output
        / / {
        // code: 'const str = 'Hello World'',
        // map: '',
        // warnings: []
        // }
    Copy the code

    Transform can also minify code while transforming it, specify the module type of the code, and so on. Some of the configurations are as follows:

    interface TransformOptions {
      // The type of source codeloader? : Loader;// Inject code at the top of the codebanner? :string;
      // Inject code at the bottom of the codefooter? :string;
      
      // Sourcemap configurationsourcemap? :boolean | 'inline' | 'external' | 'both'; legalComments? :'none' | 'inline' | 'eof' | 'linked' | 'external'; sourceRoot? :string; sourcesContent? :boolean;
      
      // Code compression relatedminify? :boolean; minifyWhitespace? :boolean; minifyIdentifiers? :boolean; minifySyntax? :boolean; charset? : Charset; treeShaking? : TreeShaking;/ / JSX relatedjsx? :'transform' | 'preserve'; jsxFactory? :string; jsxFragment? :string;
    }
    Copy the code

    You can see it here

  • Build Build integrates the code after transform to convert one or more files and save them as files. Use:

        // cli
        esbuild test.ts --outfile=./dist/test.js // { errors: [], warnings: [] }
        
        // The js API call
        const esbuild = require('esbuild');
        const path = require('path');
    
        const result = esbuild.buildSync({
          entryPoints: [path.resolve(__dirname, 'test.ts')].outdir: path.resolve(__dirname, 'dist')});console.log(result); // { errors: [], warnings: [] }
    Copy the code

    After the execution, the converted code file will be generated to the specified directory. The specific configuration parameters can be click here

Esbuild Plugins

Like other packaging tools, esBuild has a plugin that provides hooks at build time that allow you to perform custom actions at certain stages of the packaging process. The plugin provides four hooks that are executed in order :onStart, onResolve, onLoad, and onEnd

const esbuild = require('esbuild');
const path = require('path');

// Test the plug-in
const testPlugin = {
  name: 'testPlugin'.setup({ onStart, onResolve, onLoad, onEnd }) {
    onStart(() = > {
      console.log('onStart');
    });
    onResolve({ filter: /. * / }, (msg) = > {
      console.log('onResolve', msg);
    });
    onLoad({ filter: /. * / }, (msg) = > {
      console.log('onLoad', msg);
    });
    onEnd((msg) = > {
      console.log('onEnd', msg); }); }}; esbuild.buildSync({entryPoints: [path.resolve(__dirname, 'test.ts')].outdir: path.resolve(__dirname, 'dist'),
  bundle: true.plugins: [testPlugin],
});
Copy the code

Return after execution

Practice: Use ESBuild to package TS projects

After talking about the general usage of ESbuild, we will do a practical project. General steps in the project:

  • 1. Package typescript projects as JS files
  • 2. Put the packaged file into the HTML and run the HTML.

First, write a ts file test.ts to insert the node

// test.ts
(function () {
  const app = document.querySelector('#app');
  const div = document.createElement('div');
  div.innerHTML = '<div>Hello World</div>'; app.appendChild(div); }) ();Copy the code

Create an HTML file

<! DOCTYPEhtml>
<html>
  <head>
    <title>test html</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="{{scripts}}"></script>
  </body>
</html>
Copy the code

Next, write the packaging logic

// esbuild.js
const esbuild = require('esbuild');
const path = require('path');
const fs = require('fs');
// HTML file address
const HTML_PATH = path.resolve(__dirname, 'index.html');
// The destination address
const TARGET_PATH = path.resolve(__dirname, 'dist');
// Output the js address
const OUTPUT_PATH = './test.js';
/** * Custom plugin *@type { import('esbuild').Plugin }* /
const testPlugin = {
  name: 'testPlugin'.setup({ onEnd }) {
    // Replace and copy the HTML after packaging
    onEnd(({ errors }) = > {
      console.log(errors);
      if(! errors.length) {let data = fs.readFileSync(HTML_PATH, { encoding: 'utf-8' });
        data = data.replace(`{scripts}`, OUTPUT_PATH);
        fs.writeFileSync(path.resolve(TARGET_PATH, 'index.html'), data, {
          encoding: 'utf-8'}); }}); }};// Package the main method
esbuild
  .build({
    entryPoints: [path.resolve(__dirname, 'test.ts')].outdir: path.resolve(__dirname, 'dist'),
    bundle: true.plugins: [testPlugin],
  })
  .then((msg) = > {
    if (msg.length) throw new Error('compile error');
    console.log('compile success');
  });
Copy the code

Execute the esbuild.js file

The file has been generated successfully. Open the HTML file to see if js was executed

Successful code execution

summary

This article focuses on the ESBuild packaging tool. It mainly introduces:

  • Esbuild delivers much faster performance than mainstream packaging tools today
  • Esbuild API and usage
  • How does ESBuild define a plug-in
  • Package a TS project with ESBuild

If there are any inaccuracies or errors in this article, please note them in the comments section

reference

  1. esbuild