DEV Community

Marcin Wosinek
Marcin Wosinek

Posted on • Updated on • Originally published at how-to.dev

How to build with esbuild code generated by Vue CLI

If you are interested in trying out esbuild with your Vue CLI generated app, in this article I will walk you through setting it up for a freshly generated application. This should be a good starting point for migrating your Vue application to esbuild.

Code generation

I generate new application with:

$ npx -p @vue/cli vue create esbuild-vue-cli -d
Enter fullscreen mode Exit fullscreen mode
  • -d - skips prompts with generating options & use default options - vue version 2
  • npx -p ... - generates code without global installation

The generate code can be build with:

$ npm run build
> esbuild-vue-cli@0.1.0 build
> vue-cli-service build


 DONE  Compiled successfully in 1622ms8:20:58 AM

  File                                 Size               Gzipped

  dist/js/chunk-vendors.5028b17c.js    90.35 KiB          32.40 KiB
  dist/js/app.5b09fec2.js              4.58 KiB           1.63 KiB
  dist/css/app.fb0c6e1c.css            0.33 KiB           0.23 KiB

  Images and other types of assets omitted.

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html
Enter fullscreen mode Exit fullscreen mode

Key information here - the built code has about 95 KiB, and it took about 1.6s to get it.

Esbuild installation & naive build

First we have to install esbuild:

$ npm install --save-dev esbuild

added 1 package, and audited 1326 packages in 3s

82 packages are looking for funding
  run `npm fund` for details

....
Enter fullscreen mode Exit fullscreen mode

If we were trying to apply the approach used in the (create-react-app example)[https://how-to.dev/how-to-build-code-generated-by-create-react-app-with-esbuild], we would en up with a build command in package.json like this one:

{
  ...
  "scripts": {
    ...
    "esbuild": "esbuild src/main.js --bundle --outfile=dist/main.js"
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

Running this script fails:

$ npm run esbuild

> esbuild-vue-cli@0.1.0 esbuild
> esbuild src/main.js --bundle --outfile=dist/main.js

 > src/main.js:2:16: error: No loader is configured for ".vue" files: src/App.vue
    2 │ import App from './App.vue'
      ╵                 ~~~~~~~~~~~

1 error
Enter fullscreen mode Exit fullscreen mode

There are 2 things happening here:

Installing the plugin & setting the build script

We can install the plugin with:

$ npm install --save-dev esbuild-vue

added 91 packages, and audited 1417 packages in 6s

82 packages are looking for funding
  run `npm fund` for details
...
Enter fullscreen mode Exit fullscreen mode

For the build script, I follow the example form esbuild-vue's Getting started:

const vuePlugin = require("esbuild-vue");

require("esbuild").build({
  entryPoints: ["src/main.js"],
  bundle: true,
  outfile: "dist/main.js",
  logLevel: "info",
  plugins: [vuePlugin()],
  define: {
    "process.env.NODE_ENV": JSON.stringify("development"),
  },
});
Enter fullscreen mode Exit fullscreen mode

Plus I:

  • added logLevel: "info", to get logs about successful builds as well
  • set entryPoints & outfile

Now, we replace the package.json esbuild script with:

{
  ...
  "scripts": {
    ...
    "esbuild": "node build.js"
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

The build passes:

$ npm run esbuild 

> esbuild-vue-cli@0.1.0 esbuild
> node build.js


  dist/main.js  200.2kb

⚡ Done in 634ms
Enter fullscreen mode Exit fullscreen mode

The build is faster - about 0.6s, but the output is bigger - 200 KiB. Before we will start optimizing it, let's first test if it's working as expected.

For testing our build, let's paste this into dist/index.html:

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="icon" href="./favicon.ico" />
    <title>esbuild-vue-cli</title>
  </head>
  <body>
    <noscript
      ><strong
        >We're sorry but esbuild-vue-cli doesn't work properly without
        JavaScript enabled. Please enable it to continue.</strong
      ></noscript
    >
    <div id="app"></div>
    <script src="./main.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

It's the HTML build by the original npm run build, but tweaked to the files names we used in esbuild. The application works:

Alt Text

but it's missing a logo. That's because contrary to webpack, esbuild is not parsing HTML files to treat src="<some-file>" as file imports - we will need to do it ourself, but this is something to be covered in other article in this series.

Size optimization

For optimizing the build size, we just need to add to build.js:

...
require("esbuild").build({
  ...
  minify: true,
  ...
});
Enter fullscreen mode Exit fullscreen mode

With this in place, our build is as fast as before:

$ npm run esbuild

> esbuild-vue-cli@0.1.0 esbuild
> node build.js


  dist/main.js  89.9kb

⚡ Done in 600ms
Enter fullscreen mode Exit fullscreen mode

but the size is more or less the same as for the original build script.

Links

Summary

In this article, we have seen how to build Vue CLI generate code with esbuild. You can find the code repository here , and the generate page here .

Discussion (0)