20
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.
I generate new application with:
$ npx -p @vue/cli vue create esbuild-vue-cli -d
-d
- skips prompts with generating options & use default options - vue version 2npx -p ...
- generates code without global installationThe 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
Key information here - the built code has about 95 KiB, and it took about 1.6s to get it.
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
....
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"
},
...
}
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
There are 2 things happening here:
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
...
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"),
},
});
Plus I:
logLevel: "info",
to get logs about successful builds as wellNow, we replace the
package.json
esbuild script with:{
...
"scripts": {
...
"esbuild": "node build.js"
},
...
}
The build passes:
$ npm run esbuild
> esbuild-vue-cli@0.1.0 esbuild
> node build.js
dist/main.js 200.2kb
⚡ Done in 634ms
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>
It's the HTML build by the original
npm run build
, but tweaked to the files names we used in esbuild. The application works:
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.For optimizing the build size, we just need to add to
build.js
:...
require("esbuild").build({
...
minify: true,
...
});
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
but the size is more or less the same as for the original build script.