Solutions:
1. How to configure ESBuild using an external config file?
- Create a new file in root: esbuild.mjs with the following contents:
import esbuild from "esbuild";
esbuild
.build({
entryPoints: ["src/styles/style.css", "src/scripts/script.js"],
outdir: "dist",
bundle: true,
plugins: [],
})
.then(() => console.log("⚡ Build complete! ⚡"))
.catch(() => process.exit(1));
- Add the following code in your package.json:
{
...
"scripts": {
...
"build": "node esbuild.mjs"
},
...
}
- Run the build by using npm run build command and this would bundle up your stylesheets and scripts and output them in dist directory.
- For more details and/or adding custom build options, please refer to ESBuild's Build API documentation.
2. ESBuild doesn't support SCSS out-of-the-box. How to configure external plugins like esbuild-sass-plugin and to go even further, how to setup PostCSS and plugins like Autoprefixer?
- Install npm dependencies:
npm i -D esbuild-sass-plugin postcss autoprefixer
- Edit your esbuild.mjs to the following code:
import esbuild from "esbuild";
import { sassPlugin } from "esbuild-sass-plugin";
import postcss from 'postcss';
import autoprefixer from 'autoprefixer';
// Generate CSS/JS Builds
esbuild
.build({
entryPoints: ["src/styles/style.scss", "src/scripts/script.js"],
outdir: "dist",
bundle: true,
metafile: true,
plugins: [
sassPlugin({
async transform(source) {
const { css } = await postcss([autoprefixer]).process(source);
return css;
},
}),
],
})
.then(() => console.log("⚡ Build complete! ⚡"))
.catch(() => process.exit(1));
3. How to setup dev server with auto-rebuild?
- ESBuild has a limitation on this end, you can either pass in
watch: true
or run its server. It doesn't allow both.
- ESBuild also has another limitation, it doesn't have HMR support like Webpack does.
- So to live with both limitations and still allowing a server, we can use Live Server. Install it using
npm i -D @compodoc/live-server
.
- Create a new file in root: esbuild_watch.mjs with the following contents:
import liveServer from '@compodoc/live-server';
import esbuild from 'esbuild';
import { sassPlugin } from 'esbuild-sass-plugin';
import postcss from 'postcss';
import autoprefixer from 'autoprefixer';
// Turn on LiveServer on http://localhost:7000
liveServer.start({
port: 7000,
host: 'localhost',
root: '',
open: true,
ignore: 'node_modules',
wait: 0,
});
// Generate CSS/JS Builds
esbuild
.build({
logLevel: 'debug',
metafile: true,
entryPoints: ['src/styles/style.scss', 'src/scripts/script.js'],
outdir: 'dist',
bundle: true,
watch: true,
plugins: [
sassPlugin({
async transform(source) {
const { css } = await postcss([autoprefixer]).process(
source
);
return css;
},
}),
],
})
.then(() => console.log('⚡ Styles & Scripts Compiled! ⚡ '))
.catch(() => process.exit(1));
- Edit the scripts in your package.json:
{
...
"scripts": {
...
"build": "node esbuild.mjs",
"watch": "node esbuild_watch.mjs"
},
...
}
- To run build use this command
npm run build
.
- To run dev server with auto-rebuild run
npm run watch
. This is a "hacky" way to do things but does a fair-enough job.
4. How to setup PurgeCSS?
I found a great plugin for this: esbuild-plugin-purgecss by peteryuan but it wasn't allowing an option to be passed for the html/views paths that need to be parsed so I
created esbuild-plugin-purgecss-2 that does the job. To set it up, read below:
- Install dependencies
npm i -D esbuild-plugin-purgecss-2 glob-all
.
- Add the following code to your esbuild.mjs and esbuild_watch.mjs files:
// Import Dependencies
import glob from 'glob-all';
import purgecssPlugin2 from 'esbuild-plugin-purgecss-2';
esbuild
.build({
plugins: [
...
purgecssPlugin2({
content: glob.sync([
// Customize the following URLs to match your setup
'./*.html',
'./views/**/*.html'
]),
}),
],
})
...
- Now running the
npm run build
or npm run watch
will purgeCSS from the file paths mentioned in glob.sync([...]
in the code above.
TL;DR:
- Create an external config file in root esbuild.mjs and add the command to run it in package.json inside
scripts: {..}
e.g. "build": "node esbuild.mjs"
to reference and run the config file by using npm run build
.
- ESBuild doesn't support HMR. Also, you can either
watch
or serve
with ESBuild, not both. To overcome, use a separate dev server library like Live Server.
- For the complete setup, please refer to my custom-esbuild-with-scss-purgecss-and-liveserver repository on github.
Final Notes:
I know this is a long thread but it took me a lot of time to figure these out. My intention is to have this here for others looking into the same problems and trying to figure out where to get started.
Thanks.