sku 15.15.3 → 15.15.4
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/CHANGELOG.md +22 -0
- package/dist/config/storybook.cjs +66 -20
- package/dist/packages/sku/package.mjs +3 -3
- package/dist/program/hooks/preAction/preAction.hook.mjs +2 -2
- package/dist/services/telemetry/index.mjs +16 -7
- package/dist/services/telemetry/provider.mjs +66 -20
- package/dist/services/vite/helpers/config/createConfig.mjs +3 -2
- package/dist/services/vite/helpers/prerender/prerenderConcurrently.mjs +23 -10
- package/dist/services/webpack/entry/render/render-to-string.mjs +3 -1
- package/dist/utils/buildFileUtils.mjs +1 -1
- package/dist/utils/copyDirContents.mjs +7 -13
- package/dist/utils/polyfillRegistry.mjs +7 -6
- package/dist/utils/polyfillWarnings.mjs +2 -2
- package/dist/vite/prerender-worker.mjs +11 -8
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# sku
|
|
2
2
|
|
|
3
|
+
## 15.15.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `vite`: Avoid redundant work during static pre-rendering ([#1590](https://github.com/seek-oss/sku/pull/1590))
|
|
8
|
+
|
|
9
|
+
- Simplify public asset copying logic ([#1592](https://github.com/seek-oss/sku/pull/1592))
|
|
10
|
+
|
|
11
|
+
- Increase minimum `@vocab/vite` to v1.0.4 to ensure improved translation bundling ([#1595](https://github.com/seek-oss/sku/pull/1595))
|
|
12
|
+
|
|
13
|
+
- Lazy load telemetry so the banner only shows up in commands that use it ([#1594](https://github.com/seek-oss/sku/pull/1594))
|
|
14
|
+
|
|
15
|
+
- Add `cross-fetch` to list of unnecessary polyfills ([#1596](https://github.com/seek-oss/sku/pull/1596))
|
|
16
|
+
|
|
17
|
+
- Unpin `@sku-lib/babel-plugin-display-name` and `@sku-lib/vite` dependencies ([#1587](https://github.com/seek-oss/sku/pull/1587))
|
|
18
|
+
|
|
19
|
+
- `vite`: Pass through options set via `dangerouslySetViteConfig` to the Vanilla Extract plugin ([#1588](https://github.com/seek-oss/sku/pull/1588))
|
|
20
|
+
|
|
21
|
+
- `vite`: Clear render timeout after successful `renderToStringAsync` ([#1590](https://github.com/seek-oss/sku/pull/1590))
|
|
22
|
+
|
|
23
|
+
Vite apps that use `renderToStringAsync` were being artificially slowed down by a 5 second timeout that was not being cleared.
|
|
24
|
+
|
|
3
25
|
## 15.15.3
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
|
@@ -2155,36 +2155,82 @@ const debug$7 = (0, debug.default)("sku:telemetry");
|
|
|
2155
2155
|
const noopDebug = (functionName) => (...args) => {
|
|
2156
2156
|
debug$7("noop telemetry call '%s' with data: %O", functionName, args);
|
|
2157
2157
|
};
|
|
2158
|
-
|
|
2158
|
+
const createNoopProvider = () => ({
|
|
2159
2159
|
count: noopDebug("count"),
|
|
2160
2160
|
timing: noopDebug("timing"),
|
|
2161
2161
|
gauge: noopDebug("gauge"),
|
|
2162
2162
|
addGlobalTags: noopDebug("addGlobalTags"),
|
|
2163
|
-
close: () => Promise.resolve()
|
|
2164
|
-
|
|
2163
|
+
close: () => Promise.resolve()
|
|
2164
|
+
});
|
|
2165
|
+
let activeProvider = createNoopProvider();
|
|
2166
|
+
const pendingGlobalTags = [];
|
|
2167
|
+
let providerResolved = false;
|
|
2168
|
+
let usingRealProvider = false;
|
|
2169
|
+
const flushPendingGlobalTags = () => {
|
|
2170
|
+
const tagsProviders = pendingGlobalTags.splice(0);
|
|
2171
|
+
if (!usingRealProvider) return;
|
|
2172
|
+
tagsProviders.forEach((getTags) => activeProvider.addGlobalTags(getTags()));
|
|
2165
2173
|
};
|
|
2166
|
-
|
|
2167
|
-
if (
|
|
2174
|
+
const resolveProvider = () => {
|
|
2175
|
+
if (providerResolved) return;
|
|
2176
|
+
providerResolved = true;
|
|
2177
|
+
if (process.env.SKU_TELEMETRY === "false") {
|
|
2178
|
+
debug$7("Sku telemetry is disabled, skipping initialization");
|
|
2179
|
+
flushPendingGlobalTags();
|
|
2180
|
+
return;
|
|
2181
|
+
}
|
|
2182
|
+
try {
|
|
2168
2183
|
const _mod = require$6("@seek/sku-telemetry");
|
|
2169
2184
|
const realProvider = (_mod?.default ?? _mod)({});
|
|
2170
2185
|
if (typeof realProvider.gauge !== "function") realProvider.gauge = noopDebug("gauge");
|
|
2171
|
-
|
|
2172
|
-
|
|
2186
|
+
activeProvider = realProvider;
|
|
2187
|
+
usingRealProvider = true;
|
|
2188
|
+
} catch {
|
|
2189
|
+
debug$7("@seek/sku-telemetry not installed, falling back to noop telemetry provider");
|
|
2190
|
+
banner("caution", "@seek/sku-telemetry not installed", [
|
|
2191
|
+
"To help us improve sku, please install our private telemetry package that gives us insights on usage, errors and performance.",
|
|
2192
|
+
getAddCommand({
|
|
2193
|
+
deps: ["@seek/sku-telemetry"],
|
|
2194
|
+
type: "dev"
|
|
2195
|
+
}),
|
|
2196
|
+
"Non SEEK based usage can disable this message with `SKU_TELEMETRY=false`"
|
|
2197
|
+
]);
|
|
2173
2198
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2199
|
+
flushPendingGlobalTags();
|
|
2200
|
+
};
|
|
2201
|
+
/**
|
|
2202
|
+
* Registers global tags to be applied to the telemetry provider. If the
|
|
2203
|
+
* provider hasn't been resolved yet, the tags are buffered and the (potentially
|
|
2204
|
+
* expensive) computation is deferred until the first metric is emitted.
|
|
2205
|
+
*/
|
|
2206
|
+
const registerGlobalTags = (getTags) => {
|
|
2207
|
+
if (!providerResolved) {
|
|
2208
|
+
pendingGlobalTags.push(getTags);
|
|
2209
|
+
return;
|
|
2210
|
+
}
|
|
2211
|
+
if (usingRealProvider) activeProvider.addGlobalTags(getTags());
|
|
2212
|
+
};
|
|
2213
|
+
const provider = {
|
|
2214
|
+
count: (...args) => {
|
|
2215
|
+
resolveProvider();
|
|
2216
|
+
activeProvider.count(...args);
|
|
2217
|
+
},
|
|
2218
|
+
timing: (...args) => {
|
|
2219
|
+
resolveProvider();
|
|
2220
|
+
activeProvider.timing(...args);
|
|
2221
|
+
},
|
|
2222
|
+
gauge: (...args) => {
|
|
2223
|
+
resolveProvider();
|
|
2224
|
+
activeProvider.gauge(...args);
|
|
2225
|
+
},
|
|
2226
|
+
addGlobalTags: (tagMap) => registerGlobalTags(() => tagMap),
|
|
2227
|
+
close: async () => {
|
|
2228
|
+
resolveProvider();
|
|
2229
|
+
await activeProvider.close();
|
|
2230
|
+
}
|
|
2231
|
+
};
|
|
2186
2232
|
(0, debug.default)("sku:telemetry");
|
|
2187
|
-
var telemetry_default =
|
|
2233
|
+
var telemetry_default = provider;
|
|
2188
2234
|
//#endregion
|
|
2189
2235
|
//#region src/services/webpack/config/plugins/metricsPlugin.ts
|
|
2190
2236
|
const log$2 = (0, debug.default)("sku:metrics");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region package.json
|
|
2
|
-
var version = "15.15.
|
|
2
|
+
var version = "15.15.4";
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "sku",
|
|
5
5
|
version,
|
|
@@ -80,8 +80,8 @@ var package_default = {
|
|
|
80
80
|
"@loadable/webpack-plugin": "^5.14.0",
|
|
81
81
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.0",
|
|
82
82
|
"@rolldown/plugin-babel": "^0.2.1",
|
|
83
|
-
"@sku-lib/babel-plugin-display-name": "workspace
|
|
84
|
-
"@sku-lib/vite": "workspace
|
|
83
|
+
"@sku-lib/babel-plugin-display-name": "workspace:^",
|
|
84
|
+
"@sku-lib/vite": "workspace:^",
|
|
85
85
|
"@swc/core": "^1.6.13",
|
|
86
86
|
"@types/express": "^4.17.11",
|
|
87
87
|
"@types/jest": "^30.0.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSkuContext } from "../../../context/createSkuContext.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { setGlobalTags } from "../../../services/telemetry/index.mjs";
|
|
3
3
|
//#region src/program/hooks/preAction/preAction.hook.ts
|
|
4
4
|
const preActionHook = (rootCommand, actionCommand) => {
|
|
5
5
|
const { port, strictPort } = actionCommand.opts();
|
|
@@ -11,7 +11,7 @@ const preActionHook = (rootCommand, actionCommand) => {
|
|
|
11
11
|
skuContext.convertLoadable = actionCommand.opts()?.convertLoadable;
|
|
12
12
|
skuContext.listUrls = actionCommand.opts()?.listUrls;
|
|
13
13
|
skuContext.commandName = actionCommand.name();
|
|
14
|
-
|
|
14
|
+
setGlobalTags(skuContext);
|
|
15
15
|
actionCommand.setOptionValue("skuContext", skuContext);
|
|
16
16
|
};
|
|
17
17
|
//#endregion
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { requireFromCwd } from "../../private/utils/src/filesystem/cwd.mjs";
|
|
2
2
|
import "../../private/utils/src/index.mjs";
|
|
3
3
|
import isCI_default from "../../utils/isCI.mjs";
|
|
4
|
-
import
|
|
4
|
+
import provider, { registerGlobalTags } from "./provider.mjs";
|
|
5
5
|
import { version } from "../../packages/sku/package.mjs";
|
|
6
6
|
import debug from "debug";
|
|
7
7
|
import os from "node:os";
|
|
8
8
|
//#region src/services/telemetry/index.ts
|
|
9
9
|
const log = debug("sku:telemetry");
|
|
10
|
-
const
|
|
10
|
+
const computeGlobalTags = ({ languages, bundler }) => {
|
|
11
11
|
let projectName = "unknown";
|
|
12
12
|
let braidVersion = "unknown";
|
|
13
13
|
const skuVersion = version;
|
|
@@ -18,16 +18,25 @@ const initializeTelemetry = ({ languages, bundler }) => {
|
|
|
18
18
|
} catch (e) {
|
|
19
19
|
log(`Error getting project name or braid version: ${e}`);
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
return {
|
|
22
22
|
ci: isCI_default,
|
|
23
23
|
version: skuVersion,
|
|
24
24
|
braidVersion,
|
|
25
25
|
project: projectName,
|
|
26
26
|
os: os.platform(),
|
|
27
|
-
languageSupport:
|
|
27
|
+
languageSupport: languages ? "multi" : "single",
|
|
28
28
|
bundler
|
|
29
|
-
}
|
|
29
|
+
};
|
|
30
30
|
};
|
|
31
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Registers the global tags for the current sku command. The tags are only
|
|
33
|
+
* computed if telemetry ends up being used, so this is safe to call eagerly
|
|
34
|
+
* (e.g. from the preAction hook) without triggering the work for commands that
|
|
35
|
+
* never emit metrics.
|
|
36
|
+
*/
|
|
37
|
+
const setGlobalTags = (skuContext) => {
|
|
38
|
+
registerGlobalTags(() => computeGlobalTags(skuContext));
|
|
39
|
+
};
|
|
40
|
+
var telemetry_default = provider;
|
|
32
41
|
//#endregion
|
|
33
|
-
export { telemetry_default as default,
|
|
42
|
+
export { telemetry_default as default, setGlobalTags };
|
|
@@ -10,33 +10,79 @@ const debug$1 = debug("sku:telemetry");
|
|
|
10
10
|
const noopDebug = (functionName) => (...args) => {
|
|
11
11
|
debug$1("noop telemetry call '%s' with data: %O", functionName, args);
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
const createNoopProvider = () => ({
|
|
14
14
|
count: noopDebug("count"),
|
|
15
15
|
timing: noopDebug("timing"),
|
|
16
16
|
gauge: noopDebug("gauge"),
|
|
17
17
|
addGlobalTags: noopDebug("addGlobalTags"),
|
|
18
|
-
close: () => Promise.resolve()
|
|
19
|
-
|
|
18
|
+
close: () => Promise.resolve()
|
|
19
|
+
});
|
|
20
|
+
let activeProvider = createNoopProvider();
|
|
21
|
+
const pendingGlobalTags = [];
|
|
22
|
+
let providerResolved = false;
|
|
23
|
+
let usingRealProvider = false;
|
|
24
|
+
const flushPendingGlobalTags = () => {
|
|
25
|
+
const tagsProviders = pendingGlobalTags.splice(0);
|
|
26
|
+
if (!usingRealProvider) return;
|
|
27
|
+
tagsProviders.forEach((getTags) => activeProvider.addGlobalTags(getTags()));
|
|
20
28
|
};
|
|
21
|
-
|
|
22
|
-
if (
|
|
29
|
+
const resolveProvider = () => {
|
|
30
|
+
if (providerResolved) return;
|
|
31
|
+
providerResolved = true;
|
|
32
|
+
if (process.env.SKU_TELEMETRY === "false") {
|
|
33
|
+
debug$1("Sku telemetry is disabled, skipping initialization");
|
|
34
|
+
flushPendingGlobalTags();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
23
38
|
const _mod = require("@seek/sku-telemetry");
|
|
24
39
|
const realProvider = (_mod?.default ?? _mod)({});
|
|
25
40
|
if (typeof realProvider.gauge !== "function") realProvider.gauge = noopDebug("gauge");
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
activeProvider = realProvider;
|
|
42
|
+
usingRealProvider = true;
|
|
43
|
+
} catch {
|
|
44
|
+
debug$1("@seek/sku-telemetry not installed, falling back to noop telemetry provider");
|
|
45
|
+
banner("caution", "@seek/sku-telemetry not installed", [
|
|
46
|
+
"To help us improve sku, please install our private telemetry package that gives us insights on usage, errors and performance.",
|
|
47
|
+
getAddCommand({
|
|
48
|
+
deps: ["@seek/sku-telemetry"],
|
|
49
|
+
type: "dev"
|
|
50
|
+
}),
|
|
51
|
+
"Non SEEK based usage can disable this message with `SKU_TELEMETRY=false`"
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
flushPendingGlobalTags();
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Registers global tags to be applied to the telemetry provider. If the
|
|
58
|
+
* provider hasn't been resolved yet, the tags are buffered and the (potentially
|
|
59
|
+
* expensive) computation is deferred until the first metric is emitted.
|
|
60
|
+
*/
|
|
61
|
+
const registerGlobalTags = (getTags) => {
|
|
62
|
+
if (!providerResolved) {
|
|
63
|
+
pendingGlobalTags.push(getTags);
|
|
64
|
+
return;
|
|
28
65
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
66
|
+
if (usingRealProvider) activeProvider.addGlobalTags(getTags());
|
|
67
|
+
};
|
|
68
|
+
const provider = {
|
|
69
|
+
count: (...args) => {
|
|
70
|
+
resolveProvider();
|
|
71
|
+
activeProvider.count(...args);
|
|
72
|
+
},
|
|
73
|
+
timing: (...args) => {
|
|
74
|
+
resolveProvider();
|
|
75
|
+
activeProvider.timing(...args);
|
|
76
|
+
},
|
|
77
|
+
gauge: (...args) => {
|
|
78
|
+
resolveProvider();
|
|
79
|
+
activeProvider.gauge(...args);
|
|
80
|
+
},
|
|
81
|
+
addGlobalTags: (tagMap) => registerGlobalTags(() => tagMap),
|
|
82
|
+
close: async () => {
|
|
83
|
+
resolveProvider();
|
|
84
|
+
await activeProvider.close();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
41
87
|
//#endregion
|
|
42
|
-
export {
|
|
88
|
+
export { provider as default, registerGlobalTags };
|
|
@@ -9,6 +9,8 @@ import babel from "@rolldown/plugin-babel";
|
|
|
9
9
|
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
|
|
10
10
|
//#region src/services/vite/helpers/config/createConfig.ts
|
|
11
11
|
const require = createRequire(import.meta.url);
|
|
12
|
+
const TSCONFIG_PLUGIN_NAME = "sku-tsconfig-paths";
|
|
13
|
+
const vanillaExtractCompilerPluginAllowlist = ["sku:dangerously-set-vite-config", TSCONFIG_PLUGIN_NAME];
|
|
12
14
|
const createConfig = (skuContext, environment) => {
|
|
13
15
|
const vocabConfig = getVocabConfig(skuContext);
|
|
14
16
|
const isProductionBuild = process.env.NODE_ENV === "production";
|
|
@@ -25,7 +27,6 @@ const createConfig = (skuContext, environment) => {
|
|
|
25
27
|
}]
|
|
26
28
|
];
|
|
27
29
|
if (skuContext.displayNamesProd) prodBabelPlugins.push(require.resolve("@sku-lib/babel-plugin-display-name"));
|
|
28
|
-
const TSCONFIG_PLUGIN_NAME = "sku-tsconfig-paths";
|
|
29
30
|
return {
|
|
30
31
|
resolve: {},
|
|
31
32
|
plugins: [
|
|
@@ -45,7 +46,7 @@ const createConfig = (skuContext, environment) => {
|
|
|
45
46
|
}),
|
|
46
47
|
react(),
|
|
47
48
|
babel({ plugins: [require.resolve("babel-plugin-macros"), ...isProductionBuild ? prodBabelPlugins : []] }),
|
|
48
|
-
vanillaExtractPlugin({ unstable_pluginFilter: ({ name }) => name
|
|
49
|
+
vanillaExtractPlugin({ unstable_pluginFilter: ({ name }) => vanillaExtractCompilerPluginAllowlist.includes(name) }),
|
|
49
50
|
skuPlugin({
|
|
50
51
|
skuContext,
|
|
51
52
|
environment
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { success } from "../../../../private/utils/src/console/styles.mjs";
|
|
2
|
+
import "../../../../private/utils/src/console/index.mjs";
|
|
1
3
|
import { getBuildRoutes } from "../../../webpack/config/plugins/createHtmlRenderPlugin.mjs";
|
|
2
4
|
import path from "node:path";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
3
6
|
import os from "node:os";
|
|
4
7
|
import { Worker } from "node:worker_threads";
|
|
5
8
|
//#region src/services/vite/helpers/prerender/prerenderConcurrently.ts
|
|
@@ -9,9 +12,12 @@ var PrerenderWorkerError = class extends Error {
|
|
|
9
12
|
this.name = "PrerenderWorkerError";
|
|
10
13
|
}
|
|
11
14
|
};
|
|
12
|
-
const runJobs = (jobs) => {
|
|
15
|
+
const runJobs = (jobs, sharedWorkerData) => {
|
|
13
16
|
const worker = new Worker(new URL(import.meta.resolve("#vite/prerender-worker")), {
|
|
14
|
-
workerData:
|
|
17
|
+
workerData: {
|
|
18
|
+
jobs,
|
|
19
|
+
sharedWorkerData
|
|
20
|
+
},
|
|
15
21
|
execArgv: ["--enable-source-maps"]
|
|
16
22
|
});
|
|
17
23
|
return new Promise((resolve, reject) => {
|
|
@@ -32,21 +38,28 @@ const getFileName = (skuContext, skuRoute) => {
|
|
|
32
38
|
return includesHtmlInFilePath ? path.join(renderDirectory, relativeFilePath) : path.join(renderDirectory, relativeFilePath, "index.html");
|
|
33
39
|
};
|
|
34
40
|
const prerenderConcurrently = async (skuContext) => {
|
|
35
|
-
const
|
|
41
|
+
const routes = getBuildRoutes(skuContext);
|
|
42
|
+
const targetPath = skuContext.paths.target;
|
|
43
|
+
const jobs = routes.map((route) => ({
|
|
36
44
|
route: route.route,
|
|
37
45
|
routeName: route.routeName,
|
|
38
46
|
site: route.site,
|
|
39
47
|
filePath: getFileName(skuContext, route),
|
|
40
|
-
publicPath: skuContext.publicPath,
|
|
41
48
|
environment: route.environment,
|
|
49
|
+
language: route.language
|
|
50
|
+
}));
|
|
51
|
+
const rawManifest = await readFile(path.resolve(path.join(targetPath, ".vite/manifest.json")), "utf-8");
|
|
52
|
+
const sharedWorkerData = {
|
|
53
|
+
publicPath: skuContext.publicPath,
|
|
42
54
|
cspEnabled: skuContext.cspEnabled,
|
|
43
55
|
cspExtraScriptSrcHosts: skuContext.cspExtraScriptSrcHosts,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
const
|
|
48
|
-
const chunkSize = Math.ceil(jobs.length /
|
|
49
|
-
await Promise.all(Array.from({ length:
|
|
56
|
+
targetPath,
|
|
57
|
+
manifest: JSON.parse(rawManifest)
|
|
58
|
+
};
|
|
59
|
+
const cores = Math.min(os.availableParallelism(), jobs.length);
|
|
60
|
+
const chunkSize = Math.ceil(jobs.length / cores);
|
|
61
|
+
await Promise.all(Array.from({ length: cores }, (_, i) => runJobs(jobs.slice(i * chunkSize, (i + 1) * chunkSize), sharedWorkerData)));
|
|
62
|
+
console.log(success(`Finished pre-rendering ${routes.length} pages`));
|
|
50
63
|
};
|
|
51
64
|
//#endregion
|
|
52
65
|
export { PrerenderWorkerError, prerenderConcurrently };
|
|
@@ -18,6 +18,7 @@ function renderToStringAsync(reactNode) {
|
|
|
18
18
|
onShellError(error) {
|
|
19
19
|
log("Shell Render Error:", error);
|
|
20
20
|
hasErrored = true;
|
|
21
|
+
clearTimeout(timeout);
|
|
21
22
|
reject(error);
|
|
22
23
|
},
|
|
23
24
|
onError(error) {
|
|
@@ -31,7 +32,7 @@ function renderToStringAsync(reactNode) {
|
|
|
31
32
|
startStreamToString();
|
|
32
33
|
}
|
|
33
34
|
});
|
|
34
|
-
setTimeout(() => {
|
|
35
|
+
const timeout = setTimeout(() => {
|
|
35
36
|
if (hasErrored || hasRendered) return;
|
|
36
37
|
log(`Timeout after having not errored or rendered in ${RENDER_TIMEOUT_MS}ms`);
|
|
37
38
|
abort("Timeout during Render. Render did not complete in time. You may may have a hanging promise or perpetually suspended component.");
|
|
@@ -48,6 +49,7 @@ function renderToStringAsync(reactNode) {
|
|
|
48
49
|
},
|
|
49
50
|
destroy(_error, callback) {
|
|
50
51
|
log("Stream ended. Returning HTML");
|
|
52
|
+
clearTimeout(timeout);
|
|
51
53
|
resolve(html);
|
|
52
54
|
callback();
|
|
53
55
|
}
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { copyFile, mkdir, readdir, stat } from "node:fs/promises";
|
|
1
|
+
import { hasErrorCode } from "./error-guards.mjs";
|
|
2
|
+
import { cp, stat } from "node:fs/promises";
|
|
4
3
|
//#region src/utils/copyDirContents.ts
|
|
5
4
|
const copyDirContents = async (srcPath, destPath) => {
|
|
6
5
|
if (!(await stat(srcPath)).isDirectory()) throw new Error(`Source ${srcPath} is not a directory`);
|
|
7
|
-
|
|
6
|
+
try {
|
|
8
7
|
if (!(await stat(destPath)).isDirectory()) throw new Error(`Destination ${destPath} is not a directory`);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
for (const srcItem of srcItems) {
|
|
12
|
-
const srcItemPath = resolve(srcPath, srcItem);
|
|
13
|
-
const srcItemStat = await stat(srcItemPath);
|
|
14
|
-
const destItemPath = resolve(destPath, srcItem);
|
|
15
|
-
if (srcItemStat.isFile()) await copyFile(srcItemPath, destItemPath);
|
|
16
|
-
else if (srcItemStat.isDirectory()) await copyDirContents(srcItemPath, destItemPath);
|
|
8
|
+
} catch (error) {
|
|
9
|
+
if (!hasErrorCode(error) || error.code !== "ENOENT") throw error;
|
|
17
10
|
}
|
|
11
|
+
await cp(srcPath, destPath, { recursive: true });
|
|
18
12
|
};
|
|
19
13
|
//#endregion
|
|
20
|
-
export { copyDirContents
|
|
14
|
+
export { copyDirContents };
|
|
@@ -20,12 +20,13 @@ const POLYFILL_REGISTRY = {
|
|
|
20
20
|
docsUrl: "https://babeljs.io/docs/en/babel-polyfill"
|
|
21
21
|
},
|
|
22
22
|
"regenerator-runtime": { reason: "async/await is well established and works across many devices and browser versions. It has been available across browsers since April 2017." },
|
|
23
|
-
"es6-promise": { reason: "
|
|
24
|
-
"es6-promise/auto": { reason: "
|
|
25
|
-
"promise-polyfill": { reason: "
|
|
26
|
-
"whatwg-fetch": { reason: "
|
|
27
|
-
"isomorphic-fetch": { reason: "
|
|
28
|
-
"node-fetch": { reason: "fetch is well established and works across many devices and browser versions. It has been available across browsers since March 2017." },
|
|
23
|
+
"es6-promise": { reason: "Promise is well established and works across many devices and browser versions. It has been available across browsers since July 2015." },
|
|
24
|
+
"es6-promise/auto": { reason: "Promise is well established and works across many devices and browser versions. It has been available across browsers since July 2015." },
|
|
25
|
+
"promise-polyfill": { reason: "Promise is well established and works across many devices and browser versions. It has been available across browsers since July 2015." },
|
|
26
|
+
"whatwg-fetch": { reason: "fetch is well established and works across many devices and browser versions. It has been available across browsers since March 2017 and Node.js since v18.0.0." },
|
|
27
|
+
"isomorphic-fetch": { reason: "fetch is well established and works across many devices and browser versions. It has been available across browsers since March 2017 and Node.js since v18.0.0." },
|
|
28
|
+
"node-fetch": { reason: "fetch is well established and works across many devices and browser versions. It has been available across browsers since March 2017 and Node.js since v18.0.0." },
|
|
29
|
+
"cross-fetch": { reason: "fetch is well established and works across many devices and browser versions. It has been available across browsers since March 2017 and Node.js since v18.0.0." },
|
|
29
30
|
"intersection-observer": { reason: "IntersectionObserver is well established and works across many devices and browser versions. It has been available across browsers since March 2019." },
|
|
30
31
|
raf: { reason: "requestAnimationFrame is well established and works across many devices and browser versions. It has been available across browsers since July 2015." },
|
|
31
32
|
"raf/polyfill": { reason: "requestAnimationFrame is well established and works across many devices and browser versions. It has been available across browsers since July 2015." },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { caution, critical, secondary, strong } from "../private/utils/src/console/styles.mjs";
|
|
2
2
|
import "../private/utils/src/console/index.mjs";
|
|
3
|
-
import
|
|
3
|
+
import telemetry_default from "../services/telemetry/index.mjs";
|
|
4
4
|
import { detectUnnecessaryPolyfills } from "./polyfillDetector.mjs";
|
|
5
5
|
//#region src/utils/polyfillWarnings.ts
|
|
6
6
|
/**
|
|
@@ -9,7 +9,7 @@ import { detectUnnecessaryPolyfills } from "./polyfillDetector.mjs";
|
|
|
9
9
|
const validatePolyfills = (polyfills) => {
|
|
10
10
|
const detectedPolyfills = detectUnnecessaryPolyfills(polyfills);
|
|
11
11
|
if (detectedPolyfills.length === 0) return;
|
|
12
|
-
|
|
12
|
+
telemetry_default.count("unnecessary_polyfill", void 0, detectedPolyfills.length);
|
|
13
13
|
console.log();
|
|
14
14
|
console.log(caution("⚠️ Unnecessary polyfills detected"));
|
|
15
15
|
console.log();
|
|
@@ -3,21 +3,24 @@ import createCSPHandler from "../services/webpack/entry/csp.mjs";
|
|
|
3
3
|
import { createOutDir, renderEntryChunkName } from "../services/vite/helpers/bundleConfig.mjs";
|
|
4
4
|
import { ensureTargetDirectory } from "../utils/buildFileUtils.mjs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
-
import {
|
|
6
|
+
import { writeFile } from "node:fs/promises";
|
|
7
7
|
import { createCollector } from "@sku-lib/vite/collector";
|
|
8
8
|
import { workerData } from "node:worker_threads";
|
|
9
9
|
import { mockAdapter, setAdapter } from "@vanilla-extract/css/adapter";
|
|
10
10
|
//#region src/services/vite/helpers/prerender/prerenderWorker.ts
|
|
11
11
|
setAdapter(mockAdapter);
|
|
12
|
-
const
|
|
13
|
-
if (!
|
|
14
|
-
const { targetPath } =
|
|
12
|
+
const typedWorkerData = workerData;
|
|
13
|
+
if (!typedWorkerData || typedWorkerData.jobs.length === 0) process.exit(0);
|
|
14
|
+
const { sharedWorkerData: { cspEnabled, cspExtraScriptSrcHosts, manifest, publicPath, targetPath }, jobs } = typedWorkerData;
|
|
15
15
|
if (!targetPath) throw new Error("targetPath is required in workerData");
|
|
16
16
|
const outDir = createOutDir(targetPath);
|
|
17
|
-
|
|
17
|
+
let render;
|
|
18
|
+
try {
|
|
19
|
+
render = (await import(path.join(outDir.ssg, renderEntryChunkName))).default;
|
|
20
|
+
} catch (e) {
|
|
18
21
|
throw new Error(`Error importing sku render entrypoint`, { cause: e });
|
|
19
|
-
}
|
|
20
|
-
await Promise.all(
|
|
22
|
+
}
|
|
23
|
+
await Promise.all(jobs.map(async ({ environment, filePath, site, route, routeName, language }) => {
|
|
21
24
|
const loadableCollector = createCollector({
|
|
22
25
|
manifest,
|
|
23
26
|
base: publicPath
|
|
@@ -47,7 +50,7 @@ await Promise.all(workerData.map(async ({ publicPath, environment, filePath, csp
|
|
|
47
50
|
const relativeOutputPath = path.relative(process.cwd(), filePath);
|
|
48
51
|
try {
|
|
49
52
|
console.log(`Writing HTML for route "${route}" to "${relativeOutputPath}"`);
|
|
50
|
-
await writeFile(
|
|
53
|
+
await writeFile(filePath, html);
|
|
51
54
|
} catch (e) {
|
|
52
55
|
throw new Error(`Error writing file to "${relativeOutputPath}"`, { cause: e });
|
|
53
56
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sku",
|
|
3
|
-
"version": "15.15.
|
|
3
|
+
"version": "15.15.4",
|
|
4
4
|
"description": "Front-end development toolkit, powered by Webpack, Babel, Vanilla Extract and Jest",
|
|
5
5
|
"types": "./dist/index.d.mts",
|
|
6
6
|
"bin": {
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"@vocab/core": "^1.6.2",
|
|
101
101
|
"@vocab/phrase": "^2.2.0",
|
|
102
102
|
"@vocab/pseudo-localize": "^1.0.1",
|
|
103
|
-
"@vocab/vite": "^1.0.
|
|
103
|
+
"@vocab/vite": "^1.0.4",
|
|
104
104
|
"@vocab/webpack": "^1.2.9",
|
|
105
105
|
"autoprefixer": "^10.3.1",
|
|
106
106
|
"babel-jest": "^30.0.0",
|
|
@@ -168,8 +168,8 @@
|
|
|
168
168
|
"webpack-dev-server": "<=5.2.0",
|
|
169
169
|
"webpack-merge": "^6.0.1",
|
|
170
170
|
"webpack-node-externals": "^3.0.0",
|
|
171
|
-
"@sku-lib/
|
|
172
|
-
"@sku-lib/
|
|
171
|
+
"@sku-lib/vite": "^2.0.1",
|
|
172
|
+
"@sku-lib/babel-plugin-display-name": "^0.0.2"
|
|
173
173
|
},
|
|
174
174
|
"devDependencies": {
|
|
175
175
|
"@types/babel__core": "^7.20.5",
|