Skip to content

Instantly share code, notes, and snippets.

@v9n
Created October 14, 2021 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save v9n/c40a6ad2078d09dd86117924b415b7fb to your computer and use it in GitHub Desktop.
Save v9n/c40a6ad2078d09dd86117924b415b7fb to your computer and use it in GitHub Desktop.
Esbuild with devserber and scss
const esbuild = require('esbuild');
const sassPlugin = require('esbuild-plugin-sass')
const http = require('http');
let publicURL = "/"
let nodeEnv = "development"
const buildOptions = {
entryPoints: ['src/index.jsx'],
bundle: true,
outfile: 'public/main.js',
plugins: [sassPlugin()],
loader: {
'.png': 'dataurl',
'.ttf': 'file',
},
sourcemap: true,
platform: 'browser',
define: {
'process.env.PUBLIC_URL': JSON.stringify(publicURL),
'process.env.NODE_ENV': JSON.stringify(nodeEnv),
'global': 'window',
},
}
const serverOptions = {
servedir: 'public',
}
const dynamicScriptInject = `
<script>
// dynamically inject by esbuild dev server
(function() {
let node = document.createElement("script");
node.type = "text/javascript";
node.src = "/main.js?ts=" + new Date().getTime();
node.async = true;
node.dataset.cfasync = false;
document.body.appendChild(node);
node.addEventListener("load", () => {
console.log("js node added successfully");
});
node = document.createElement("link");
node.rel = 'stylesheet';
node.type = "text/css";
node.media = 'all';
node.href = "/main.css?ts=" + new Date().getTime();
document.head.appendChild(node);
node.addEventListener("load", () => {
console.log("css node added successfully");
});
})()
</script>`
function runServer() {
// Start esbuild's server on a random local port
esbuild.serve(serverOptions, buildOptions).then(result => {
// The result tells us where esbuild's local server is
const {host, port} = result
// Then start a proxy server on port 3000
http.createServer(async (req, res) => {
const options = {
hostname: host,
port: port,
path: req.url,
method: req.method,
headers: req.headers,
}
if (req.url.indexOf(".") >= 0) {
// Forward each incoming request to esbuild
const proxyReq = http.request(options, proxyRes => {
// If esbuild returns "not found", send a custom 404 page
if (proxyRes.statusCode === 404) {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>A custom 404 page</h1>');
return;
}
// Otherwise, forward the response from esbuild to the client
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res, { end: true });
});
// Forward the body of the request to esbuild
req.pipe(proxyReq, { end: true });
} else {
// serve index.html and strip out tag
fs = require('fs');
let index = new Buffer.from(await fs.readFileSync('./public/index.html')).toString();
index = index.replaceAll("%PUBLIC_URL%", publicURL);
index = index.replace("</body>", dynamicScriptInject + "</body>");
res.write(index);
res.end();
}
}).listen(3000);
console.log("Listen on http://localhost:3000");
});
}
function runBuild() {
esbuild.build(buildOptions).catch(e => {
console.log("Error bundling", e);
process.exit(1);
})
}
if (process.argv.includes('--serve')) {
runServer();
} else {
runBuild();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment