@hpcc-js/esbuild-plugins 1.0.10 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/build.ts CHANGED
@@ -1,143 +1,122 @@
1
- import * as process from "process";
2
- import { readFileSync } from "fs";
3
- import * as path from "path";
4
- import * as esbuild from "esbuild";
5
- import type { BuildOptions, Format } from "esbuild";
6
- import { umdWrapper } from "esbuild-plugin-umd-wrapper";
7
- import yargs from "yargs";
8
- import { hideBin } from "yargs/helpers";
9
- import { rebuildLogger } from "./rebuild-logger.ts";
10
- import { sfxWasm } from "./sfx-wrapper.ts";
11
-
12
- const myYargs = yargs(hideBin(process.argv));
13
- myYargs
14
- .usage("Usage: node esbuild.mjs [options]")
15
- .demandCommand(0, 0)
16
- .example("node esbuild.mjs --watch", "Bundle and watch for changes")
17
- .option("mode", {
18
- alias: "m",
19
- describe: "Build mode",
20
- choices: ["development", "production"],
21
- default: "production"
22
- })
23
- .option("w", {
24
- alias: "watch",
25
- describe: "Watch for changes",
26
- type: "boolean"
27
- })
28
- .help("h")
29
- .alias("h", "help")
30
- .epilog("https://github.com/hpcc-systems/hpcc-js-wasm")
31
- ;
32
-
33
- export const pkg = JSON.parse(readFileSync(path.join(process.cwd(), "./package.json"), "utf8"));
34
- export const NODE_MJS = pkg.type === "module" ? "js" : "mjs";
35
- export const NODE_CJS = pkg.type === "module" ? "cjs" : "js";
36
-
37
- export const argv = await myYargs.argv;
38
- export const isDevelopment = argv.mode === "development";
39
- export const isProduction = !isDevelopment;
40
- export const isWatch = argv.watch;
41
-
42
- export function build(config: BuildOptions) {
43
- if (isDevelopment && Array.isArray(config.entryPoints)) {
44
- // eslint-disable-next-line no-console
45
- console.log("Start: ", config.entryPoints[0], config.outfile);
46
- }
47
- return esbuild.build({
48
- sourcemap: "linked",
49
- ...config,
50
- plugins: [
51
- ...(config.plugins ?? []),
52
- sfxWasm()
53
- ]
54
- }).finally(() => {
55
- if (isDevelopment && Array.isArray(config.entryPoints)) {
56
- // eslint-disable-next-line no-console
57
- console.log("Stop: ", config.entryPoints[0], config.outfile);
58
- }
59
- });
60
- }
61
-
62
- export async function watch(config: BuildOptions) {
63
- await build(config);
64
- return esbuild.context({
65
- sourcemap: "external",
66
- ...config,
67
- plugins: [
68
- ...(config.plugins ?? []),
69
- rebuildLogger(config),
70
- sfxWasm()
71
- ]
72
- }).then(ctx => {
73
- return ctx.watch();
74
- });
75
- }
76
-
77
- export function buildWatch(config: BuildOptions) {
78
- return isWatch ? watch(config) : build(config);
79
- }
80
-
81
- export function browserTpl(input: string, output: string, format: Format | "umd" = "esm", globalName?: string, libraryName?: string, external: string[] = []) {
82
- return buildWatch({
83
- entryPoints: [input],
84
- outfile: `${output}.${format === "esm" ? "js" : `${format}.js`}`,
85
- platform: "browser",
86
- target: "es2022",
87
- format: format as Format,
88
- globalName,
89
- bundle: true,
90
- minify: isProduction,
91
- external,
92
- plugins: format === "umd" ? [umdWrapper({ libraryName })] : []
93
- });
94
- }
95
-
96
- export function browserBoth(input: string, output: string, globalName?: string, libraryName?: string, external: string[] = []) {
97
- return Promise.all([
98
- browserTpl(input, output, "esm", globalName, libraryName, external),
99
- browserTpl(input, output, "umd", globalName, libraryName, external)
100
- ]);
101
- }
102
-
103
- export function nodeTpl(input: string, output: string, format: Format | "umd" = "esm", external: string[] = []) {
104
- return buildWatch({
105
- entryPoints: [input],
106
- outfile: `${output}.${format === "esm" ? NODE_MJS : NODE_CJS}`,
107
- platform: "node",
108
- target: "node20",
109
- format: format as Format,
110
- bundle: true,
111
- minify: isProduction,
112
- external
113
- });
114
- }
115
-
116
- export function neutralTpl(input: string, output: string, format: Format | "umd" = "esm", globalName?: string, libraryName?: string, external: string[] = []) {
117
- return buildWatch({
118
- entryPoints: [input],
119
- outfile: `${output}.${format === "esm" ? "js" : "umd.js"}`,
120
- platform: "neutral",
121
- target: "es2022",
122
- format: format as Format,
123
- globalName,
124
- bundle: true,
125
- minify: isProduction,
126
- external,
127
- plugins: format === "umd" ? [umdWrapper({ libraryName })] : []
128
- });
129
- }
130
-
131
- export function nodeBoth(input: string, output: string, external: string[] = []) {
132
- return Promise.all([
133
- nodeTpl(input, output, "esm", external),
134
- nodeTpl(input, output, "cjs", external)
135
- ]);
136
- }
137
-
138
- export function bothTpl(input: string, output: string, globalName?: string, libraryName?: string, external: string[] = []) {
139
- return Promise.all([
140
- browserBoth(input, output, globalName, libraryName, external),
141
- nodeTpl(input, output, "cjs", external)
142
- ]);
143
- }
1
+ import * as process from "process";
2
+ import { readFileSync } from "fs";
3
+ import * as path from "path";
4
+ import * as esbuild from "esbuild";
5
+ import type { BuildOptions, Format } from "esbuild";
6
+ import { umdWrapper } from "esbuild-plugin-umd-wrapper";
7
+ import yargs from "yargs";
8
+ import { hideBin } from "yargs/helpers";
9
+ import { rebuildLogger } from "./rebuild-logger.ts";
10
+ import { sfxWasm } from "./sfx-wrapper.ts";
11
+
12
+ const myYargs = yargs(hideBin(process.argv));
13
+ myYargs
14
+ .usage("Usage: node esbuild.mjs [options]")
15
+ .demandCommand(0, 0)
16
+ .example("node esbuild.mjs --watch", "Bundle and watch for changes")
17
+ .option("mode", {
18
+ alias: "m",
19
+ describe: "Build mode",
20
+ choices: ["development", "production"],
21
+ default: "production"
22
+ })
23
+ .option("w", {
24
+ alias: "watch",
25
+ describe: "Watch for changes",
26
+ type: "boolean"
27
+ })
28
+ .help("h")
29
+ .alias("h", "help")
30
+ .epilog("https://github.com/hpcc-systems/hpcc-js-wasm")
31
+ ;
32
+
33
+ export const pkg = JSON.parse(readFileSync(path.join(process.cwd(), "./package.json"), "utf8"));
34
+ export const NODE_MJS = pkg.type === "module" ? "js" : "mjs";
35
+ export const NODE_CJS = pkg.type === "module" ? "cjs" : "js";
36
+
37
+ export const argv = await myYargs.argv;
38
+ export const isDevelopment = argv.mode === "development";
39
+ export const isProduction = !isDevelopment;
40
+ export const isWatch = argv.watch;
41
+
42
+ async function buildWatch(input: string, format: Format | "umd" = "esm", external: string[] = [], config: BuildOptions): Promise<void> {
43
+
44
+ const ctx = await esbuild.context({
45
+ entryPoints: [input],
46
+ format: format as Format,
47
+ bundle: true,
48
+ minify: isProduction,
49
+ sourcemap: isDevelopment,
50
+ external,
51
+ ...config,
52
+ plugins: [
53
+ ...(isWatch ? [rebuildLogger(config)] : []),
54
+ ...(config.plugins ?? []),
55
+ sfxWasm()
56
+ ]
57
+ });
58
+
59
+ if (isWatch) {
60
+ await ctx.watch();
61
+ } else {
62
+ if (isDevelopment && Array.isArray(config.entryPoints)) {
63
+ // eslint-disable-next-line no-console
64
+ console.log("Start: ", config.entryPoints[0], config.outfile);
65
+ }
66
+ await ctx.rebuild();
67
+ await ctx.dispose();
68
+ if (isDevelopment && Array.isArray(config.entryPoints)) {
69
+ // eslint-disable-next-line no-console
70
+ console.log("Stop: ", config.entryPoints[0], config.outfile);
71
+ }
72
+ }
73
+ }
74
+
75
+ export function browserTpl(input: string, output: string, format: Format | "umd" = "esm", globalName?: string, libraryName?: string, external: string[] = []) {
76
+ return buildWatch(input, format, external, {
77
+ outfile: `${output}.${format === "esm" ? "js" : `${format}.js`}`,
78
+ platform: "browser",
79
+ target: "es2022",
80
+ globalName,
81
+ plugins: format === "umd" ? [umdWrapper({ libraryName })] : []
82
+ });
83
+ }
84
+
85
+ export function nodeTpl(input: string, output: string, format: Format | "umd" = "esm", external: string[] = []) {
86
+ return buildWatch(input, format, external, {
87
+ outfile: `${output}.${format === "esm" ? NODE_MJS : NODE_CJS}`,
88
+ platform: "node",
89
+ target: "node20"
90
+ });
91
+ }
92
+
93
+ export function neutralTpl(input: string, output: string, format: Format | "umd" = "esm", globalName?: string, libraryName?: string, external: string[] = []) {
94
+ return buildWatch(input, format, external, {
95
+ outfile: `${output}.${format === "esm" ? "js" : "umd.js"}`,
96
+ platform: "neutral",
97
+ target: "es2022",
98
+ globalName,
99
+ plugins: format === "umd" ? [umdWrapper({ libraryName })] : []
100
+ });
101
+ }
102
+
103
+ export function browserBoth(input: string, output: string, globalName?: string, libraryName?: string, external: string[] = []) {
104
+ return Promise.all([
105
+ browserTpl(input, output, "esm", globalName, libraryName, external),
106
+ browserTpl(input, output, "umd", globalName, libraryName, external)
107
+ ]);
108
+ }
109
+
110
+ export function nodeBoth(input: string, output: string, external: string[] = []) {
111
+ return Promise.all([
112
+ nodeTpl(input, output, "esm", external),
113
+ nodeTpl(input, output, "cjs", external)
114
+ ]);
115
+ }
116
+
117
+ export function bothTpl(input: string, output: string, globalName?: string, libraryName?: string, external: string[] = []) {
118
+ return Promise.all([
119
+ browserBoth(input, output, globalName, libraryName, external),
120
+ nodeTpl(input, output, "cjs", external)
121
+ ]);
122
+ }
@@ -1,20 +1,20 @@
1
- import { readFile } from "fs/promises";
2
- import type { PluginBuild, Plugin } from "esbuild";
3
-
4
- export interface ExcludeSourcemapOptions {
5
- filter: RegExp;
6
- }
7
- export function excludeSourcemap(opts: ExcludeSourcemapOptions): Plugin {
8
- return {
9
- name: "exclude-sourcemap",
10
-
11
- setup(build: PluginBuild) {
12
- build.onLoad({ filter: opts.filter }, async args => {
13
- return {
14
- contents: await readFile(args.path, "utf8") + "\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==",
15
- loader: "default",
16
- };
17
- });
18
- },
19
- };
20
- }
1
+ import { readFile } from "fs/promises";
2
+ import type { PluginBuild, Plugin } from "esbuild";
3
+
4
+ export interface ExcludeSourcemapOptions {
5
+ filter: RegExp;
6
+ }
7
+ export function excludeSourcemap(opts: ExcludeSourcemapOptions): Plugin {
8
+ return {
9
+ name: "exclude-sourcemap",
10
+
11
+ setup(build: PluginBuild) {
12
+ build.onLoad({ filter: opts.filter }, async args => {
13
+ return {
14
+ contents: await readFile(args.path, "utf8") + "\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==",
15
+ loader: "default",
16
+ };
17
+ });
18
+ },
19
+ };
20
+ }
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
- export * from "./build.ts";
2
- export * from "./exclude-sourcemap.ts";
3
- export * from "./problem-matcher.ts";
4
- export * from "./rebuild-logger.ts";
5
- export * from "./sfx-wrapper.ts";
1
+ export * from "./build.ts";
2
+ export * from "./exclude-sourcemap.ts";
3
+ export * from "./problem-matcher.ts";
4
+ export * from "./rebuild-logger.ts";
5
+ export * from "./remove-strict.ts";
6
+ export * from "./sfx-wrapper.ts";
@@ -1,24 +1,24 @@
1
- import type { PluginBuild, Plugin } from "esbuild";
2
-
3
- export function problemMatcher(): Plugin {
4
- return {
5
- name: "problem-matcher",
6
-
7
- setup(build: PluginBuild) {
8
-
9
- build.onStart(() => {
10
- // eslint-disable-next-line no-console
11
- console.log("[watch] build started");
12
- });
13
-
14
- build.onEnd((result) => {
15
- result.errors.forEach(({ text, location }) => {
16
- console.error(`✘ [ERROR] ${text}`);
17
- console.error(` ${location?.file}:${location?.line}:${location?.column}:`);
18
- });
19
- // eslint-disable-next-line no-console
20
- console.log("[watch] build finished");
21
- });
22
- }
23
- };
24
- }
1
+ import type { PluginBuild, Plugin } from "esbuild";
2
+
3
+ export function problemMatcher(): Plugin {
4
+ return {
5
+ name: "problem-matcher",
6
+
7
+ setup(build: PluginBuild) {
8
+
9
+ build.onStart(() => {
10
+ // eslint-disable-next-line no-console
11
+ console.log("[watch] build started");
12
+ });
13
+
14
+ build.onEnd((result) => {
15
+ result.errors.forEach(({ text, location }) => {
16
+ console.error(`✘ [ERROR] ${text}`);
17
+ console.error(` ${location?.file}:${location?.line}:${location?.column}:`);
18
+ });
19
+ // eslint-disable-next-line no-console
20
+ console.log("[watch] build finished");
21
+ });
22
+ }
23
+ };
24
+ }
@@ -1,24 +1,24 @@
1
- import type { PluginBuild, Plugin } from "esbuild";
2
-
3
- export interface RebuildLoggerOptions {
4
- outfile?: string;
5
- }
6
-
7
- export function rebuildLogger(opts: RebuildLoggerOptions): Plugin {
8
- return {
9
- name: "rebuild-logger",
10
-
11
- setup(build: PluginBuild) {
12
-
13
- build.onStart(() => {
14
- // eslint-disable-next-line no-console
15
- console.log("[watch] build started");
16
- });
17
-
18
- build.onEnd(() => {
19
- // eslint-disable-next-line no-console
20
- console.log(`Rebuilt ${opts.outfile ?? "Unknown"}`);
21
- });
22
- }
23
- };
24
- }
1
+ import type { PluginBuild, Plugin } from "esbuild";
2
+
3
+ export interface RebuildLoggerOptions {
4
+ outfile?: string;
5
+ }
6
+
7
+ export function rebuildLogger(opts: RebuildLoggerOptions): Plugin {
8
+ return {
9
+ name: "rebuild-logger",
10
+
11
+ setup(build: PluginBuild) {
12
+
13
+ build.onStart(() => {
14
+ // eslint-disable-next-line no-console
15
+ console.log("[watch] build started");
16
+ });
17
+
18
+ build.onEnd(() => {
19
+ // eslint-disable-next-line no-console
20
+ console.log(`Rebuilt ${opts.outfile ?? "Unknown"}`);
21
+ });
22
+ }
23
+ };
24
+ }
@@ -0,0 +1,24 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import type { PluginBuild, Plugin } from "esbuild";
3
+
4
+ export function removeStrict(): Plugin {
5
+ return {
6
+ name: "remove-strict",
7
+ setup(build: PluginBuild) {
8
+ build.initialOptions.write = false;
9
+ build.onEnd((result) => {
10
+ result?.outputFiles?.forEach(file => {
11
+ if (file.path.endsWith(".js")) {
12
+ const contents = file.text.replace(/"use strict";/g, "");
13
+ if (contents.indexOf("use strict") >= 0) {
14
+ console.error("remove-strict: ", file.path);
15
+ }
16
+ writeFileSync(file.path, contents, { encoding: "utf8" });
17
+ } else {
18
+ writeFileSync(file.path, file.contents, { encoding: "binary" });
19
+ }
20
+ });
21
+ });
22
+ }
23
+ };
24
+ }
@@ -1,108 +1,108 @@
1
- import { readFile } from "fs/promises";
2
- import { existsSync } from "fs";
3
- import { Base91 } from "@hpcc-js/wasm-base91";
4
- import { Zstd } from "@hpcc-js/wasm-zstd";
5
- import type { Plugin, PluginBuild } from "esbuild";
6
-
7
- function tpl(wasmJsPath: string, base91Wasm: string, base91CompressedWasm: string) {
8
-
9
- const compressed = (base91CompressedWasm.length + 8 * 1024) <= base91Wasm.length;
10
- const wasmJsExists = existsSync(wasmJsPath);
11
-
12
- return `\
13
- ${compressed ? 'import { decompress } from "fzstd";' : ""}
14
- ${wasmJsExists ? `import wrapper from "${wasmJsPath}";` : ""}
15
-
16
- const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
17
-
18
- function decode(raw: string): Uint8Array {
19
- const len = raw.length;
20
- const ret: number[] = [];
21
-
22
- let b = 0;
23
- let n = 0;
24
- let v = -1;
25
-
26
- for (let i = 0; i < len; i++) {
27
- const p = table.indexOf(raw[i]);
28
- /* istanbul ignore next */
29
- if (p === -1) continue;
30
- if (v < 0) {
31
- v = p;
32
- } else {
33
- v += p * 91;
34
- b |= v << n;
35
- n += (v & 8191) > 88 ? 13 : 14;
36
- do {
37
- ret.push(b & 0xff);
38
- b >>= 8;
39
- n -= 8;
40
- } while (n > 7);
41
- v = -1;
42
- }
43
- }
44
-
45
- if (v > -1) {
46
- ret.push((b | v << n) & 0xff);
47
- }
48
-
49
- return new Uint8Array(ret);
50
- }
51
-
52
- const blobStr = '${compressed ? base91CompressedWasm : base91Wasm}';
53
-
54
- let g_module: Uint8Array | undefined;
55
- let g_wasmBinary: Uint8Array | undefined;
56
- export default function() {
57
- if (!g_wasmBinary) {
58
- g_wasmBinary = ${compressed ? "decompress(decode(blobStr))" : "decode(blobStr)"};
59
- }
60
- ${!wasmJsExists ? `\
61
- return g_wasmBinary;
62
- `: `\
63
- if (!g_module) {
64
- g_module = wrapper({
65
- wasmBinary: g_wasmBinary,
66
- locateFile: undefined
67
- });
68
- }
69
- return g_module;
70
- `}
71
- }
72
-
73
- export function reset() {
74
- if (g_module) {
75
- g_module = undefined;
76
- }
77
- } `.trim();
78
- }
79
-
80
- export async function wrap(path: string) {
81
- const base91 = await Base91.load();
82
- const zstd = await Zstd.load();
83
-
84
- const wasm = await readFile(path);
85
- path = path.replace(/\.js$/, ".xxx");
86
- const wasmJsPath = path.replace(/\.wasm$/, ".js");
87
- const base91Wasm = base91.encode(wasm);
88
- const compressedWasm = zstd.compress(wasm);
89
- const base91CompressedWasm = base91.encode(compressedWasm);
90
-
91
- return tpl(wasmJsPath, base91Wasm, base91CompressedWasm);
92
- }
93
-
94
- export function sfxWasm(): Plugin {
95
- return {
96
- name: "sfx-wasm",
97
-
98
- setup(build: PluginBuild) {
99
-
100
- build.onLoad({ filter: /\.wasm$/ }, async args => {
101
- return {
102
- contents: await wrap(args.path),
103
- loader: "ts",
104
- };
105
- });
106
- }
107
- };
108
- }
1
+ import { readFile } from "fs/promises";
2
+ import { existsSync } from "fs";
3
+ import { Base91 } from "@hpcc-js/wasm-base91";
4
+ import { Zstd } from "@hpcc-js/wasm-zstd";
5
+ import type { Plugin, PluginBuild } from "esbuild";
6
+
7
+ function tpl(wasmJsPath: string, base91Wasm: string, base91CompressedWasm: string) {
8
+
9
+ const compressed = (base91CompressedWasm.length + 8 * 1024) <= base91Wasm.length;
10
+ const wasmJsExists = existsSync(wasmJsPath);
11
+
12
+ return `\
13
+ ${compressed ? 'import { decompress } from "fzstd";' : ""}
14
+ ${wasmJsExists ? `import wrapper from "${wasmJsPath}";` : ""}
15
+
16
+ const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
17
+
18
+ function decode(raw: string): Uint8Array {
19
+ const len = raw.length;
20
+ const ret: number[] = [];
21
+
22
+ let b = 0;
23
+ let n = 0;
24
+ let v = -1;
25
+
26
+ for (let i = 0; i < len; i++) {
27
+ const p = table.indexOf(raw[i]);
28
+ /* istanbul ignore next */
29
+ if (p === -1) continue;
30
+ if (v < 0) {
31
+ v = p;
32
+ } else {
33
+ v += p * 91;
34
+ b |= v << n;
35
+ n += (v & 8191) > 88 ? 13 : 14;
36
+ do {
37
+ ret.push(b & 0xff);
38
+ b >>= 8;
39
+ n -= 8;
40
+ } while (n > 7);
41
+ v = -1;
42
+ }
43
+ }
44
+
45
+ if (v > -1) {
46
+ ret.push((b | v << n) & 0xff);
47
+ }
48
+
49
+ return new Uint8Array(ret);
50
+ }
51
+
52
+ const blobStr = '${compressed ? base91CompressedWasm : base91Wasm}';
53
+
54
+ let g_module: Uint8Array | undefined;
55
+ let g_wasmBinary: Uint8Array | undefined;
56
+ export default function() {
57
+ if (!g_wasmBinary) {
58
+ g_wasmBinary = ${compressed ? "decompress(decode(blobStr))" : "decode(blobStr)"};
59
+ }
60
+ ${!wasmJsExists ? `\
61
+ return g_wasmBinary;
62
+ `: `\
63
+ if (!g_module) {
64
+ g_module = wrapper({
65
+ wasmBinary: g_wasmBinary,
66
+ locateFile: undefined
67
+ });
68
+ }
69
+ return g_module;
70
+ `}
71
+ }
72
+
73
+ export function reset() {
74
+ if (g_module) {
75
+ g_module = undefined;
76
+ }
77
+ } `.trim();
78
+ }
79
+
80
+ export async function wrap(path: string) {
81
+ const base91 = await Base91.load();
82
+ const zstd = await Zstd.load();
83
+
84
+ const wasm = await readFile(path);
85
+ path = path.replace(/\.js$/, ".xxx");
86
+ const wasmJsPath = path.replace(/\.wasm$/, ".js");
87
+ const base91Wasm = base91.encode(wasm);
88
+ const compressedWasm = zstd.compress(wasm);
89
+ const base91CompressedWasm = base91.encode(compressedWasm);
90
+
91
+ return tpl(wasmJsPath, base91Wasm, base91CompressedWasm);
92
+ }
93
+
94
+ export function sfxWasm(): Plugin {
95
+ return {
96
+ name: "sfx-wasm",
97
+
98
+ setup(build: PluginBuild) {
99
+
100
+ build.onLoad({ filter: /\.wasm$/ }, async args => {
101
+ return {
102
+ contents: await wrap(args.path),
103
+ loader: "ts",
104
+ };
105
+ });
106
+ }
107
+ };
108
+ }