Created
October 14, 2021 17:59
-
-
Save v9n/c40a6ad2078d09dd86117924b415b7fb to your computer and use it in GitHub Desktop.
Esbuild with devserber and scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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