diff --git a/bin/elm-react-build.js b/bin/elm-react-build.js new file mode 100644 index 0000000..3f65230 --- /dev/null +++ b/bin/elm-react-build.js @@ -0,0 +1,41 @@ +#!/usr/bin/env node +const path = require('path'); +const fs = require('fs'); +const ElmPlugin = require('esbuild-plugin-elm'); +const EnvFilePlugin = require('./lib/env.js'); + +require('esbuild') + .build({ + entryPoints: ['web/ts/index.ts', 'web/react/index.tsx'], + outdir: 'dist/js', + entryNames: '[dir]/[name]-[hash]', + allowOverwrite: true, + bundle: true, + metafile: true, + minify: true, + plugins: [EnvFilePlugin, ElmPlugin({ pathToElm: 'paack-elm-wrapper' })], + }) + .catch(() => process.exit(1)) + .then((result) => { + const htmlPath = 'dist/index.html'; + + fs.copyFile('web/index.html', htmlPath, console.log); + + fs.readFile(htmlPath, 'utf8', (err, data) => { + if (err) return console.error(err); + + const path = Object.keys(result.metafile.outputs)[0].replace('dist/', ''); + const reactPath = Object.keys(result.metafile.outputs)[1].replace( + 'dist/', + '', + ); + fs.writeFile( + htmlPath, + data + .replace('/ts/index.js', path) + .replace('/react/index.js', reactPath), + 'utf8', + console.log, + ); + }); + }); diff --git a/bin/elm-react-serve.js b/bin/elm-react-serve.js new file mode 100644 index 0000000..ea2a70a --- /dev/null +++ b/bin/elm-react-serve.js @@ -0,0 +1,50 @@ +#!/usr/bin/env node +const ElmPlugin = require('esbuild-plugin-elm'); +const EnvFilePlugin = require('./lib/env'); +const http = require('http'); + +require('esbuild') + .serve( + { + servedir: 'web', + }, + { + entryPoints: ['web/ts/index.ts', 'web/react/index.tsx'], + outdir: 'web', + bundle: true, + plugins: [EnvFilePlugin, ElmPlugin({ debug: true })], + }, + ) + .then((esbuildServer) => { + const { host, port } = esbuildServer; + + http + .createServer((req, res) => { + const forwardRequest = (path) => { + const options = { + hostname: host, + port, + path, + method: req.method, + headers: req.headers, + }; + + const proxyReq = http.request(options, (proxyRes) => { + if (proxyRes.statusCode === 404) { + // If esbuild 404s the request, assume it's a route needing to + // be handled by the JS bundle, so forward a second attempt to `/`. + // https://gist.github.com/martinrue/2896becdb8a5ed81761e11ff2ea5898e + return forwardRequest('/'); + } + + res.writeHead(proxyRes.statusCode, proxyRes.headers); + proxyRes.pipe(res, { end: true }); + }); + + req.pipe(proxyReq, { end: true }); + }; + + forwardRequest(req.url); + }) + .listen(1234); + }); diff --git a/package.json b/package.json index 59923cd..bf03bc6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@PaackEng/frontend-elm-kit", - "version": "4.1.1", + "version": "4.1.2", "description": "", "private": false, "files": [ @@ -62,7 +62,9 @@ "bin": { "paack-elm-wrapper": "bin/elm-wrapper.sh", "paack-elm-build": "bin/build.js", - "paack-elm-serve": "bin/serve.js" + "paack-elm-serve": "bin/serve.js", + "paack-elm-react-build": "bin/elm-react-build.js", + "paack-elm-react-serve": "bin/elm-react-serve.js" }, "engines": { "node": ">=0.16"