107 lines
3.3 KiB
JavaScript
107 lines
3.3 KiB
JavaScript
require("dotenv").config()
|
|
|
|
const sass = require("sass")
|
|
const path = require("path")
|
|
const fs = require("fs")
|
|
const esbuild = require("esbuild")
|
|
const rimraf = require("rimraf")
|
|
const chokidar = require("chokidar")
|
|
|
|
const mode = process.argv[2]
|
|
|
|
if (!mode) {
|
|
throw Error("Specify 'build' or 'watch' as argument")
|
|
}
|
|
const stubImportsPlugin = (paths) => {
|
|
return {
|
|
name: "stub-imports",
|
|
setup(build) {
|
|
const regex = new RegExp(`^(${paths.join("|")})\$`)
|
|
build.onResolve({ filter: regex }, (args) => ({
|
|
path: args.path,
|
|
namespace: "stub-imports-namespace",
|
|
}))
|
|
build.onLoad({ filter: /.*/, namespace: "stub-imports-namespace" }, () => ({
|
|
contents: "{}",
|
|
loader: "json",
|
|
}))
|
|
},
|
|
}
|
|
}
|
|
|
|
const sassPlugin = {
|
|
name: "sass",
|
|
setup(build) {
|
|
build.onResolve({ filter: /(\.svg|\.png)$/ }, (args) => {
|
|
return {
|
|
path: path.resolve(CWD, "src", args.path),
|
|
}
|
|
})
|
|
build.onResolve({ filter: /\.scss$/ }, (args) => {
|
|
return {
|
|
path: path.resolve(args.resolveDir, args.path),
|
|
namespace: "sass",
|
|
}
|
|
})
|
|
build.onLoad({ filter: /.*/, namespace: "sass" }, (args) => {
|
|
let compiled = sass.renderSync({ file: args.path })
|
|
return {
|
|
contents: compiled.css.toString(),
|
|
loader: "css",
|
|
}
|
|
})
|
|
},
|
|
}
|
|
|
|
const CWD = process.cwd()
|
|
const DIST_FOLDER = path.resolve(CWD, "dist")
|
|
|
|
const envFallback = (envVar, fb = null) => (envVar ? `"${envVar}"` : `${fb}`)
|
|
|
|
async function build() {
|
|
if (fs.existsSync(DIST_FOLDER)) rimraf.sync(DIST_FOLDER)
|
|
const randomString = Math.random().toString(36).slice(2)
|
|
const outfile = path.resolve(CWD, `dist/bundle.${randomString}.js`)
|
|
const metafile = path.resolve(CWD, `dist/bundle.${randomString}.meta.json`)
|
|
const now = Date.now()
|
|
await esbuild.build({
|
|
entryPoints: [path.resolve(CWD, "src", "index.tsx")],
|
|
bundle: true,
|
|
minify: mode !== "watch",
|
|
outfile,
|
|
metafile,
|
|
sourcemap: true,
|
|
platform: "browser",
|
|
plugins: [sassPlugin, stubImportsPlugin(["path"])],
|
|
loader: { ".png": "file", ".svg": "file" },
|
|
define: {
|
|
"process.env.NODE_ENV": envFallback(process.env.NODE_ENV, `"development"`),
|
|
},
|
|
})
|
|
|
|
fs.writeFileSync(
|
|
path.resolve(CWD, "dist/index.html"),
|
|
fs
|
|
.readFileSync(path.resolve(CWD, "index.tmpl.html"), "utf8")
|
|
.replace("JAVASCRIPT_BUNDLE", `/bundle.${randomString}.js`)
|
|
.replace("CSS_BUNDLE", `/bundle.${randomString}.css`),
|
|
)
|
|
console.log(`Frontend build done, took ${Date.now() - now} ms`)
|
|
}
|
|
|
|
if (mode === "build") {
|
|
build().catch((e) => !console.error(e) && process.exit(1))
|
|
} else if (mode === "watch") {
|
|
build()
|
|
.catch((e) => console.error(e))
|
|
.then(() => {
|
|
chokidar
|
|
.watch([path.resolve(CWD, "src"), path.resolve(CWD, "../common/src")], { ignoreInitial: true })
|
|
.on("all", (...arg) => {
|
|
build().catch((e) => console.error(e))
|
|
})
|
|
})
|
|
} else {
|
|
throw Error("Unknown mode: " + mode)
|
|
}
|