build tools
This commit is contained in:
parent
a8681035b4
commit
ebf91aef1d
@ -65,6 +65,35 @@ const buildConfigBase = {
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Build time libraries, under node runtime
|
||||
*/
|
||||
const buildConfigBuild = {
|
||||
...buildConfigBase,
|
||||
entryPoints: ["src/index.build.ts"],
|
||||
outExtension: {
|
||||
'.js': '.mjs'
|
||||
},
|
||||
format: 'esm',
|
||||
platform: 'node',
|
||||
external: ["esbuild"],
|
||||
// https://github.com/evanw/esbuild/issues/1921
|
||||
// How to fix "Dynamic require of "os" is not supported"
|
||||
// esbuild cannot convert external "static" commonjs require statements to static esm imports
|
||||
banner: {
|
||||
js: `
|
||||
import { fileURLToPath } from 'url';
|
||||
import { createRequire as topLevelCreateRequire } from 'module';
|
||||
const require = topLevelCreateRequire(import.meta.url);
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
`
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Development libraries, under node runtime
|
||||
*/
|
||||
const buildConfigNode = {
|
||||
...buildConfigBase,
|
||||
entryPoints: ["src/index.node.ts", "src/cli.ts"],
|
||||
@ -76,6 +105,9 @@ const buildConfigNode = {
|
||||
external: ["preact"],
|
||||
};
|
||||
|
||||
/**
|
||||
* Support libraries, under browser runtime
|
||||
*/
|
||||
const buildConfigBrowser = {
|
||||
...buildConfigBase,
|
||||
entryPoints: ["src/tests/mock.ts", "src/tests/swr.ts", "src/index.browser.ts", "src/live-reload.ts", 'src/stories.tsx'],
|
||||
@ -89,7 +121,7 @@ const buildConfigBrowser = {
|
||||
jsxFragment: 'Fragment',
|
||||
};
|
||||
|
||||
[buildConfigNode, buildConfigBrowser].forEach((config) => {
|
||||
[buildConfigNode, buildConfigBrowser, buildConfigBuild].forEach((config) => {
|
||||
esbuild
|
||||
.build(config)
|
||||
.catch((e) => {
|
||||
|
@ -21,6 +21,10 @@
|
||||
"types": "./lib/index.browser.js",
|
||||
"default": "./lib/index.browser.mjs"
|
||||
},
|
||||
"./lib/index.build": {
|
||||
"types": "./lib/index.build.js",
|
||||
"default": "./lib/index.build.mjs"
|
||||
},
|
||||
"./lib/index.node": {
|
||||
"types": "./lib/index.node.js",
|
||||
"default": "./lib/index.node.cjs"
|
||||
@ -48,6 +52,7 @@
|
||||
"rimraf": "^3.0.2",
|
||||
"swr": "2.0.3",
|
||||
"tslib": "^2.4.0",
|
||||
"sass": "1.56.1",
|
||||
"typescript": "^4.9.4",
|
||||
"ws": "7.4.5"
|
||||
},
|
||||
|
188
packages/web-util/src/index.build.ts
Normal file
188
packages/web-util/src/index.build.ts
Normal file
@ -0,0 +1,188 @@
|
||||
import esbuild from "esbuild";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import sass from "sass";
|
||||
import { PluginBuild } from "esbuild";
|
||||
|
||||
// this should give us the current directory where
|
||||
// the project is being built
|
||||
const BASE = process.cwd();
|
||||
const distProd = path.join(BASE, "dist", "prod");
|
||||
const distDev = path.join(BASE, "dist", "dev");
|
||||
const sourceDir = path.join(BASE, "src");
|
||||
|
||||
const preact = path.join(
|
||||
BASE,
|
||||
"node_modules",
|
||||
"preact",
|
||||
"compat",
|
||||
"dist",
|
||||
"compat.module.js",
|
||||
);
|
||||
|
||||
// https://preactjs.com/guide/v8/switching-to-preact/#how-to-alias-preact-compat
|
||||
const preactCompatPlugin: esbuild.Plugin = {
|
||||
name: "preact-compat",
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /^(react-dom|react)$/ }, (args) => {
|
||||
return {
|
||||
path: preact,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export function getFilesInSource(regex: RegExp): string[] {
|
||||
return getFilesInDirectory(sourceDir, regex);
|
||||
}
|
||||
|
||||
function getFilesInDirectory(startPath: string, regex: RegExp): string[] {
|
||||
if (!fs.existsSync(startPath)) {
|
||||
return [];
|
||||
}
|
||||
const files = fs.readdirSync(startPath);
|
||||
const result = files
|
||||
.flatMap((file) => {
|
||||
const filename = path.join(startPath, file);
|
||||
|
||||
const stat = fs.lstatSync(filename);
|
||||
if (stat.isDirectory()) {
|
||||
return getFilesInDirectory(filename, regex);
|
||||
}
|
||||
if (regex.test(filename)) {
|
||||
return [filename];
|
||||
}
|
||||
return [];
|
||||
})
|
||||
.filter((x) => !!x);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
let GIT_ROOT = BASE;
|
||||
while (!fs.existsSync(path.join(GIT_ROOT, ".git")) && GIT_ROOT !== "/") {
|
||||
GIT_ROOT = path.join(GIT_ROOT, "../");
|
||||
}
|
||||
if (GIT_ROOT === "/") {
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log("not found");
|
||||
// eslint-disable-next-line no-undef
|
||||
process.exit(1);
|
||||
}
|
||||
const GIT_HASH = GIT_ROOT === "/" ? undefined : git_hash();
|
||||
|
||||
const buf = fs.readFileSync(path.join(BASE, "package.json"));
|
||||
let _package = JSON.parse(buf.toString("utf-8"));
|
||||
|
||||
function git_hash() {
|
||||
const rev = fs
|
||||
.readFileSync(path.join(GIT_ROOT, ".git", "HEAD"))
|
||||
.toString()
|
||||
.trim()
|
||||
.split(/.*[: ]/)
|
||||
.slice(-1)[0];
|
||||
if (rev.indexOf("/") === -1) {
|
||||
return rev;
|
||||
} else {
|
||||
return fs.readFileSync(path.join(GIT_ROOT, ".git", rev)).toString().trim();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Put this into some helper library.
|
||||
function copyFilesPlugin(files: Array<string>) {
|
||||
return {
|
||||
name: "copy-files",
|
||||
setup(build: PluginBuild) {
|
||||
const outDir = build.initialOptions.outdir;
|
||||
if (outDir === undefined)
|
||||
throw Error("esbuild build options does not specify outdir");
|
||||
build.onEnd(() => {
|
||||
for (const file of files) {
|
||||
const name = path.parse(file).base;
|
||||
fs.copyFileSync(file, path.join(outDir, name));
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const DEFAULT_SASS_FILTER = /\.(s[ac]ss|css)$/;
|
||||
|
||||
const buildSassPlugin: esbuild.Plugin = {
|
||||
name: "custom-build-sass",
|
||||
setup(build) {
|
||||
build.onLoad({ filter: DEFAULT_SASS_FILTER }, ({ path: file }) => {
|
||||
const resolveDir = path.dirname(file);
|
||||
const { css: contents } = sass.compile(file, { loadPaths: ["./"] });
|
||||
|
||||
return {
|
||||
resolveDir,
|
||||
loader: "css",
|
||||
contents,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const buildConfig: esbuild.BuildOptions = {
|
||||
bundle: true,
|
||||
minify: false,
|
||||
loader: {
|
||||
".svg": "file",
|
||||
".png": "dataurl",
|
||||
".jpeg": "dataurl",
|
||||
".ttf": "file",
|
||||
".woff": "file",
|
||||
".woff2": "file",
|
||||
".eot": "file",
|
||||
},
|
||||
target: ["es6"],
|
||||
format: "esm",
|
||||
platform: "browser",
|
||||
sourcemap: true,
|
||||
jsxFactory: "h",
|
||||
jsxFragment: "Fragment",
|
||||
define: {
|
||||
__VERSION__: `"${_package.version}"`,
|
||||
__GIT_HASH__: `"${GIT_HASH}"`,
|
||||
},
|
||||
plugins: [
|
||||
preactCompatPlugin,
|
||||
copyFilesPlugin(["./src/index.html"]),
|
||||
buildSassPlugin,
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Build sources for prod environment
|
||||
*/
|
||||
export function buildProd(entryPoints: string[]) {
|
||||
return esbuild.build({
|
||||
...buildConfig,
|
||||
entryPoints,
|
||||
outdir: distProd,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Build sources for dev environment
|
||||
*/
|
||||
function buildDev(entryPoints: string[]): Promise<esbuild.BuildResult> {
|
||||
return esbuild.build({
|
||||
...buildConfig,
|
||||
entryPoints,
|
||||
outdir: distDev,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Do startup for development environment
|
||||
*/
|
||||
export function initializeDev(
|
||||
entryPoints: string[],
|
||||
): () => Promise<esbuild.BuildResult> {
|
||||
buildConfig.inject = [
|
||||
"./node_modules/@gnu-taler/web-util/lib/live-reload.mjs",
|
||||
];
|
||||
return () => buildDev(entryPoints);
|
||||
}
|
Loading…
Reference in New Issue
Block a user