I have a Webpack setup that I use to preprocess SCSS with PurgeCSS with a live HMR server with esbuild-loader for speeding up compiles in Webpack but even then my compile times are still slow and I would like the raw-speed of ESBuild and remove Webpack setup altogether.
The basic setup of ESBuild is easy, you install esbuild using npm and add the following code in your package.json:
{
...
"scripts": {
...
"watch": "esbuild --bundle src/script.js --outfile=dist/script.js --watch"
},
...
}
and run it by using the following command:
npm run watch
This single-line configuration will bundle your scripts and styles (you can import style.css in script.js) and output the files in the dist directory but this doesn't allow advance configuration for ESBuild like outputting a different name for your stylesheet and script files or using plugins.
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));
{
...
"scripts": {
...
"build": "node esbuild.mjs"
},
...
}
npm i -D esbuild-sass-plugin postcss autoprefixer
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));
watch: true
or run its server. It doesn't allow both.npm i -D @compodoc/live-server
.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));
{
...
"scripts": {
...
"build": "node esbuild.mjs",
"watch": "node esbuild_watch.mjs"
},
...
}
npm run build
.npm run watch
. This is a "hacky" way to do things but does a fair-enough job.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:
npm i -D esbuild-plugin-purgecss-2 glob-all
.// 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'
]),
}),
],
})
...
npm run build
or npm run watch
will purgeCSS from the file paths mentioned in glob.sync([...]
in the code above.scripts: {..}
e.g. "build": "node esbuild.mjs"
to reference and run the config file by using npm run build
.watch
or serve
with ESBuild, not both. To overcome, use a separate dev server library like Live Server.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.