sliftutils 1.7.7 → 1.7.9
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/bundler/bundleEntry.ts +27 -11
- package/bundler/bundleEntryCaller.ts +9 -1
- package/bundler/bundler.ts +6 -1
- package/package.json +1 -1
package/bundler/bundleEntry.ts
CHANGED
|
@@ -12,15 +12,26 @@ async function main() {
|
|
|
12
12
|
if (!outputFolder) {
|
|
13
13
|
throw new Error("No output folder provided. Please use the --outputFolder option.");
|
|
14
14
|
}
|
|
15
|
-
// We prefer production, as this is what the bundler uses internally. This ensures that in the build and when run, we will have the same environment, which will result in the same requires being called.
|
|
15
|
+
// We prefer production, as this is what the bundler uses internally. This ensures that in the build and when run, we will have the same environment, which will result in the same requires being called.
|
|
16
16
|
process.env.NODE_ENV = process.env.NODE_ENV || "production";
|
|
17
17
|
require(entryPoint);
|
|
18
18
|
|
|
19
|
+
// Warm pass: this process only exists to compile the entry's whole graph
|
|
20
|
+
// (and this bundler's own modules, compiled at our startup) into typenode's
|
|
21
|
+
// on-disk cache, then exit. The caller runs a SECOND, fresh process for the
|
|
22
|
+
// real bundle — that process reads everything from the warm cache and so
|
|
23
|
+
// never has typenode lazy-load the TypeScript compiler. Without this, a
|
|
24
|
+
// cold-cache build (e.g. a fresh CI/server checkout, or an entry whose files
|
|
25
|
+
// no other entry imports) leaves `typescript` in require.cache and the
|
|
26
|
+
// bundler serializes the entire 9 MB+ compiler into the output bundle.
|
|
27
|
+
if (process.argv[4] === "--warm") {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
let name = path.basename(entryPoint);
|
|
20
32
|
if (name.endsWith(".ts") || name.endsWith(".tsx")) {
|
|
21
33
|
name = name.split(".").slice(0, -1).join(".");
|
|
22
34
|
}
|
|
23
|
-
name += ".js";
|
|
24
35
|
|
|
25
36
|
let modules = Object.values(require.cache).filter(x => x?.id !== module.id);
|
|
26
37
|
|
|
@@ -30,16 +41,21 @@ async function main() {
|
|
|
30
41
|
entryPoints: [entryPoint],
|
|
31
42
|
});
|
|
32
43
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
await fs.promises.rename(tempPath, finalPath);
|
|
39
|
-
} finally {
|
|
44
|
+
// Two artifacts: `name.js` without the sourcemap (the sourcemap is usually bigger than the code
|
|
45
|
+
// itself, so this is what production serves) and `name.debug.js` with the inline sourcemap
|
|
46
|
+
// appended (serve it behind something like a ?debug query param).
|
|
47
|
+
async function write(finalPath: string, contents: string) {
|
|
48
|
+
let tempPath = `${finalPath}.tmp`;
|
|
40
49
|
try {
|
|
41
|
-
await fs.promises.
|
|
42
|
-
|
|
50
|
+
await fs.promises.writeFile(tempPath, contents);
|
|
51
|
+
await fs.promises.rename(tempPath, finalPath);
|
|
52
|
+
} finally {
|
|
53
|
+
try {
|
|
54
|
+
await fs.promises.unlink(tempPath);
|
|
55
|
+
} catch { }
|
|
56
|
+
}
|
|
43
57
|
}
|
|
58
|
+
await write(`${outputFolder}/${name}.js`, bundled.bundle);
|
|
59
|
+
await write(`${outputFolder}/${name}.debug.js`, bundled.bundle + "\n" + bundled.sourceMapComment);
|
|
44
60
|
}
|
|
45
61
|
main().catch(err => { console.error(err); process.exitCode = 1; }).finally(() => process.exit());
|
|
@@ -10,5 +10,13 @@ export async function bundleEntryCaller(config: {
|
|
|
10
10
|
entryPoint = path.resolve(entryPoint).replace(/\\/g, "/");
|
|
11
11
|
outputFolder = path.resolve(outputFolder).replace(/\\/g, "/");
|
|
12
12
|
let bundleEntryPath = path.resolve(__dirname, "bundleEntry.ts").replace(/\\/g, "/");
|
|
13
|
-
|
|
13
|
+
let base = `node -r ./node_modules/typenode/index.js ${JSON.stringify(bundleEntryPath)} ${JSON.stringify(entryPoint)} ${JSON.stringify(outputFolder)}`;
|
|
14
|
+
// Run twice in SEPARATE processes. The first ("--warm") only imports the
|
|
15
|
+
// entry, which compiles its whole graph into typenode's on-disk cache. The
|
|
16
|
+
// second is a fresh process that imports from that warm cache — so typenode
|
|
17
|
+
// never has to compile anything and never lazy-loads the TypeScript compiler,
|
|
18
|
+
// which would otherwise be captured in require.cache and serialized (9 MB+)
|
|
19
|
+
// into the output bundle. See bundleEntry.ts.
|
|
20
|
+
await runPromise(`${base} --warm`);
|
|
21
|
+
await runPromise(base);
|
|
14
22
|
}
|
package/bundler/bundler.ts
CHANGED
|
@@ -9,7 +9,12 @@ export async function bundle(config: {
|
|
|
9
9
|
rootPath: string;
|
|
10
10
|
entryPoints: string[];
|
|
11
11
|
}): Promise<{
|
|
12
|
+
// The runnable bundle, WITHOUT the sourcemap comment (the sourcemap is usually bigger than the
|
|
13
|
+
// code itself, so the default artifact ships without it).
|
|
12
14
|
bundle: string;
|
|
15
|
+
// The trailing inline-sourcemap line comment. Append to `bundle` (with a newline) for the debug
|
|
16
|
+
// variant of the bundle.
|
|
17
|
+
sourceMapComment: string;
|
|
13
18
|
}> {
|
|
14
19
|
const { modules, rootPath, entryPoints } = config;
|
|
15
20
|
|
|
@@ -55,9 +60,9 @@ export async function bundle(config: {
|
|
|
55
60
|
code += `\n;globalThis.require(${JSON.stringify(entryPoint)});`;
|
|
56
61
|
}
|
|
57
62
|
code += "\n;});";
|
|
58
|
-
code += "\n" + encodeSourceMapLineComment(finalizeInProgressSourceMap(inProgressSourceMap));
|
|
59
63
|
return {
|
|
60
64
|
bundle: code,
|
|
65
|
+
sourceMapComment: encodeSourceMapLineComment(finalizeInProgressSourceMap(inProgressSourceMap)),
|
|
61
66
|
};
|
|
62
67
|
}
|
|
63
68
|
|