sku 15.10.2 → 15.10.3

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/_virtual/rolldown_runtime.mjs +2 -1
  3. package/dist/config/storybook.cjs +2 -2
  4. package/dist/packages/sku/package.mjs +1 -1
  5. package/dist/program/commands/serve/serve.action.mjs +1 -1
  6. package/dist/program/commands/start/webpack-start-handler.mjs +1 -1
  7. package/dist/program/commands/test/vitest-test-handler.mjs +2 -2
  8. package/dist/services/vite/helpers/config/createConfig.mjs +44 -75
  9. package/dist/services/vite/helpers/makePluginName.mjs +5 -0
  10. package/dist/services/vite/plugins/build.mjs +48 -0
  11. package/dist/services/vite/plugins/bundleAnalyzer.mjs +9 -7
  12. package/dist/services/vite/plugins/config.mjs +36 -0
  13. package/dist/services/vite/plugins/dangerouslySetViteConfig.mjs +5 -3
  14. package/dist/services/vite/plugins/devServer.mjs +25 -0
  15. package/dist/services/vite/plugins/esbuild/fixViteVanillaExtractDepScanPlugin.mjs +2 -1
  16. package/dist/services/vite/plugins/{httpsDevServerPlugin.mjs → httpsDevServer.mjs} +1 -1
  17. package/dist/services/vite/plugins/{middlewarePlugin.mjs → middleware.mjs} +3 -2
  18. package/dist/services/vite/plugins/{polyfillsPlugin.mjs → polyfills.mjs} +3 -2
  19. package/dist/services/vite/plugins/preloadPlugin/preloadPlugin.mjs +3 -6
  20. package/dist/services/vite/plugins/setNoExternal.mjs +5 -3
  21. package/dist/services/vite/plugins/telemetry.mjs +93 -0
  22. package/dist/services/vite/skuPlugin.mjs +40 -0
  23. package/dist/services/webpack/config/plugins/metricsPlugin.mjs +2 -2
  24. package/dist/services/webpack/config/webpack.config.mjs +1 -1
  25. package/dist/services/webpack/config/webpack.config.ssr.mjs +1 -1
  26. package/dist/vite/client.mjs +5 -9
  27. package/dist/vite/prerender-worker.mjs +1 -1
  28. package/package.json +2 -2
  29. package/dist/services/vite/helpers/config/baseConfig.mjs +0 -94
  30. package/dist/services/vite/plugins/HMRTelemetry.mjs +0 -58
  31. package/dist/services/vite/plugins/startTelemetry.mjs +0 -41
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # sku
2
2
 
3
+ ## 15.10.3
4
+
5
+ ### Patch Changes
6
+
7
+ - start(vite): minimize reloads caused by dependency optimization on cold startup ([#1516](https://github.com/seek-oss/sku/pull/1516))
8
+
3
9
  ## 15.10.2
4
10
 
5
11
  ### Patch Changes
@@ -26,6 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  value: mod,
27
27
  enumerable: true
28
28
  }) : target, mod));
29
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
29
30
 
30
31
  //#endregion
31
- export { __commonJSMin, __toESM };
32
+ export { __commonJSMin, __require, __toESM };
@@ -1475,7 +1475,7 @@ var MetricsPlugin = class {
1475
1475
  compiler.hooks.done.tap(smp, () => {
1476
1476
  if (this.initial) {
1477
1477
  log$2("Initial \"%s\" build complete: %s", this.target, { toString: () => (0, pretty_ms.default)(node_perf_hooks.performance.now()) });
1478
- telemetry_default.timing("start.webpack.initial", node_perf_hooks.performance.now(), {
1478
+ telemetry_default.timing("start.initial", node_perf_hooks.performance.now(), {
1479
1479
  target: this.target,
1480
1480
  type: this.type
1481
1481
  });
@@ -1483,7 +1483,7 @@ var MetricsPlugin = class {
1483
1483
  } else {
1484
1484
  const rebuildTime = node_perf_hooks.performance.now() - this.startTime;
1485
1485
  log$2("Rebuild for \"%s\" complete: %s", this.target, { toString: () => (0, pretty_ms.default)(rebuildTime) });
1486
- telemetry_default.timing("start.webpack.rebuild", rebuildTime, {
1486
+ telemetry_default.timing("start.rebuild", rebuildTime, {
1487
1487
  target: this.target,
1488
1488
  type: this.type
1489
1489
  });
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "15.10.2";
2
+ var version = "15.10.3";
3
3
  var package_default = {
4
4
  name: "sku",
5
5
  version,
@@ -2,9 +2,9 @@ import { serverUrls } from "../../../private/utils/src/serverUrls.mjs";
2
2
  import "../../../private/utils/src/index.mjs";
3
3
  import telemetry_default from "../../../services/telemetry/index.mjs";
4
4
  import exists_default from "../../../utils/exists.mjs";
5
+ import { checkHosts, getAppHosts, withHostile } from "../../../context/hosts.mjs";
5
6
  import { getSiteForHost } from "../../../context/getSiteForHost.mjs";
6
7
  import { getRouteWithLanguage, getValidLanguagesForRoute } from "../../../utils/language-utils.mjs";
7
- import { checkHosts, getAppHosts, withHostile } from "../../../context/hosts.mjs";
8
8
  import allocatePort_default from "../../../utils/allocatePort.mjs";
9
9
  import { configureProject, validatePeerDeps } from "../../../utils/configure.mjs";
10
10
  import { openBrowser } from "../../../openBrowser.mjs";
@@ -1,10 +1,10 @@
1
1
  import { serverUrls } from "../../../private/utils/src/serverUrls.mjs";
2
2
  import "../../../private/utils/src/index.mjs";
3
3
  import certificate_default from "../../../utils/certificate.mjs";
4
+ import { getAppHosts } from "../../../context/hosts.mjs";
4
5
  import { getSiteForHost } from "../../../context/getSiteForHost.mjs";
5
6
  import { getMatchingRoute } from "../../../utils/routeMatcher.mjs";
6
7
  import { getLanguageFromRoute, getRouteWithLanguage } from "../../../utils/language-utils.mjs";
7
- import { getAppHosts } from "../../../context/hosts.mjs";
8
8
  import createHtmlRenderPlugin_default from "../../../services/webpack/config/plugins/createHtmlRenderPlugin.mjs";
9
9
  import allocatePort_default from "../../../utils/allocatePort.mjs";
10
10
  import statsConfig_default from "../../../services/webpack/config/statsConfig.mjs";
@@ -1,11 +1,11 @@
1
1
  import { hasErrorCode } from "../../../utils/error-guards.mjs";
2
- import { createSkuVitestConfig } from "../../../services/vite/helpers/config/baseConfig.mjs";
2
+ import { createConfig } from "../../../services/vite/helpers/config/createConfig.mjs";
3
3
  import { styleText } from "node:util";
4
4
 
5
5
  //#region src/program/commands/test/vitest-test-handler.ts
6
6
  const vitestHandler = async ({ skuContext, args }) => {
7
7
  const { parseCLI, startVitest } = await lazyLoadVitest();
8
- const viteConfigOverride = createSkuVitestConfig({}, skuContext);
8
+ const viteConfigOverride = createConfig(skuContext);
9
9
  const results = parseCLI(["vitest", ...args]);
10
10
  const overrideableOptions = skuContext.vitestDecorator({
11
11
  css: true,
@@ -1,81 +1,50 @@
1
- import { serverUrls } from "../../../../private/utils/src/serverUrls.mjs";
2
- import "../../../../private/utils/src/index.mjs";
3
- import isCI_default from "../../../../utils/isCI.mjs";
4
- import { createSkuViteConfig } from "./baseConfig.mjs";
5
- import { createOutDir, renderEntryChunkName } from "../bundleConfig.mjs";
6
- import { middlewarePlugin } from "../../plugins/middlewarePlugin.mjs";
7
- import { startTelemetryPlugin } from "../../plugins/startTelemetry.mjs";
8
- import { HMRTelemetryPlugin } from "../../plugins/HMRTelemetry.mjs";
9
- import { getAppHosts } from "../../../../context/hosts.mjs";
10
- import { httpsDevServerPlugin } from "../../plugins/httpsDevServerPlugin.mjs";
11
- import { bundleAnalyzerPlugin } from "../../plugins/bundleAnalyzer.mjs";
12
- import { vitePluginSsrCss } from "../../plugins/ssrCss/plugin.mjs";
1
+ import { getVocabConfig } from "../../../vocab/config.mjs";
2
+ import { skuPlugin } from "../../skuPlugin.mjs";
13
3
  import { createRequire } from "node:module";
4
+ import { vitePluginVocab } from "@vocab/vite";
5
+ import tsconfigPaths from "vite-tsconfig-paths";
6
+ import { cjsInterop } from "vite-plugin-cjs-interop";
7
+ import react from "@vitejs/plugin-react";
8
+ import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
14
9
 
15
10
  //#region src/services/vite/helpers/config/createConfig.ts
16
- const clientEntry = createRequire(import.meta.url).resolve("#entries/vite-client");
17
- const shouldOpenTab = process.env.OPEN_TAB !== "false" && !isCI_default;
18
- const createServerBuildConfig = (skuContext) => {
19
- return createSkuViteConfig({ build: {
20
- ssr: true,
21
- outDir: createOutDir(skuContext.paths.target).ssg,
22
- rollupOptions: {
23
- input: skuContext.paths.renderEntry,
24
- output: { entryFileNames: renderEntryChunkName }
25
- }
26
- } }, skuContext);
27
- };
28
- const createClientBuildConfig = (skuContext) => {
29
- const outDir = createOutDir(skuContext.paths.target);
30
- return createSkuViteConfig({
31
- plugins: [process.env.NODE_ENV === "production" ? bundleAnalyzerPlugin({ name: "client" }) : null],
32
- build: {
33
- ssr: false,
34
- outDir: outDir.client,
35
- manifest: true,
36
- sourcemap: skuContext.sourceMapsProd,
37
- rollupOptions: { input: clientEntry }
38
- }
39
- }, skuContext);
40
- };
41
- const createStartConfig = ({ skuContext, environment }) => {
42
- const outDir = createOutDir(skuContext.paths.target);
43
- return createSkuViteConfig({
44
- base: "/",
45
- plugins: [
46
- vitePluginSsrCss({ entries: [skuContext.paths.renderEntry] }),
47
- middlewarePlugin({
48
- skuContext,
49
- environment
50
- }),
51
- startTelemetryPlugin({
52
- target: "node",
53
- type: "static"
54
- }),
55
- HMRTelemetryPlugin({
56
- target: "node",
57
- type: "static"
58
- }),
59
- httpsDevServerPlugin(skuContext)
60
- ],
61
- build: {
62
- ssr: false,
63
- outDir: outDir.client,
64
- manifest: true,
65
- rollupOptions: { input: clientEntry }
66
- },
67
- server: {
68
- host: "localhost",
69
- allowedHosts: getAppHosts(skuContext).filter((host) => typeof host === "string"),
70
- open: shouldOpenTab && serverUrls({
71
- hosts: getAppHosts(skuContext),
72
- port: skuContext.port.client,
73
- initialPath: skuContext.initialPath,
74
- https: skuContext.httpsDevServer
75
- }).first()
76
- }
77
- }, skuContext);
11
+ const require = createRequire(import.meta.url);
12
+ const createConfig = (skuContext, environment) => {
13
+ const vocabConfig = getVocabConfig(skuContext);
14
+ const isProductionBuild = process.env.NODE_ENV === "production";
15
+ const prodBabelPlugins = [
16
+ require.resolve("babel-plugin-transform-react-remove-prop-types"),
17
+ require.resolve("@babel/plugin-transform-react-constant-elements"),
18
+ [require.resolve("babel-plugin-unassert"), {
19
+ variables: ["assert", "invariant"],
20
+ modules: [
21
+ "assert",
22
+ "node:assert",
23
+ "tiny-invariant"
24
+ ]
25
+ }]
26
+ ];
27
+ if (skuContext.displayNamesProd) prodBabelPlugins.push(require.resolve("@sku-lib/babel-plugin-display-name"));
28
+ return { plugins: [
29
+ skuContext.vitePlugins,
30
+ vocabConfig && vitePluginVocab({ vocabConfig }),
31
+ tsconfigPaths(),
32
+ cjsInterop({
33
+ dependencies: skuContext.serveCjsInteropDependencies,
34
+ apply: "serve"
35
+ }),
36
+ cjsInterop({
37
+ dependencies: skuContext.buildCjsInteropDependencies,
38
+ apply: "build"
39
+ }),
40
+ react({ babel: { plugins: [require.resolve("babel-plugin-macros"), ...isProductionBuild ? prodBabelPlugins : []] } }),
41
+ vanillaExtractPlugin(),
42
+ skuPlugin({
43
+ skuContext,
44
+ environment
45
+ })
46
+ ] };
78
47
  };
79
48
 
80
49
  //#endregion
81
- export { createClientBuildConfig, createServerBuildConfig, createStartConfig };
50
+ export { createConfig };
@@ -0,0 +1,5 @@
1
+ //#region src/services/vite/helpers/makePluginName.ts
2
+ const makePluginName = (name) => `sku:${name}`;
3
+
4
+ //#endregion
5
+ export { makePluginName };
@@ -0,0 +1,48 @@
1
+ import { __require } from "../../../_virtual/rolldown_runtime.mjs";
2
+ import { makePluginName } from "../helpers/makePluginName.mjs";
3
+ import { createOutDir, renderEntryChunkName } from "../helpers/bundleConfig.mjs";
4
+ import browserslistToEsbuild from "../helpers/browserslist-to-esbuild.mjs";
5
+ import { createVocabChunks } from "@vocab/vite/chunks";
6
+
7
+ //#region src/services/vite/plugins/build.ts
8
+ const clientEntry = __require.resolve("#entries/vite-client");
9
+ const buildPlugin = ({ skuContext }) => {
10
+ const outDir = createOutDir(skuContext.paths.target);
11
+ return {
12
+ name: makePluginName("build"),
13
+ apply: "build",
14
+ config: () => ({
15
+ base: skuContext.publicPath,
16
+ build: {
17
+ target: browserslistToEsbuild(skuContext.supportedBrowsers),
18
+ assetsDir: "",
19
+ rollupOptions: { output: {
20
+ experimentalMinChunkSize: void 0,
21
+ manualChunks: (id, ctx) => {
22
+ const languageChunkName = createVocabChunks(id, ctx);
23
+ if (languageChunkName) return languageChunkName;
24
+ }
25
+ } }
26
+ },
27
+ environments: {
28
+ client: { build: {
29
+ outDir: outDir.client,
30
+ manifest: true,
31
+ sourcemap: skuContext.sourceMapsProd,
32
+ rollupOptions: { input: clientEntry }
33
+ } },
34
+ ssr: { build: {
35
+ ssr: true,
36
+ outDir: outDir.ssg,
37
+ rollupOptions: {
38
+ input: skuContext.paths.renderEntry,
39
+ output: { entryFileNames: renderEntryChunkName }
40
+ }
41
+ } }
42
+ }
43
+ })
44
+ };
45
+ };
46
+
47
+ //#endregion
48
+ export { buildPlugin };
@@ -3,13 +3,15 @@ import "../../../private/utils/src/index.mjs";
3
3
  import { visualizer } from "rollup-plugin-visualizer";
4
4
 
5
5
  //#region src/services/vite/plugins/bundleAnalyzer.ts
6
- const bundleReportFolder = "report";
7
- const getProjectName = () => requireFromCwd("./package.json").name;
8
- const bundleAnalyzerPlugin = ({ name }) => visualizer({
9
- filename: getPathFromCwd(`${bundleReportFolder}/${name}.html`),
10
- template: "treemap",
11
- gzipSize: true,
12
- title: getProjectName() || "Vite Bundle Analyzer"
6
+ const bundleAnalyzerPlugin = () => ({
7
+ ...visualizer({
8
+ filename: getPathFromCwd("report/client.html"),
9
+ template: "treemap",
10
+ gzipSize: true,
11
+ title: requireFromCwd("./package.json").name || "Vite Bundle Analyzer"
12
+ }),
13
+ apply: "build",
14
+ applyToEnvironment: (environment) => environment.name === "client"
13
15
  });
14
16
 
15
17
  //#endregion
@@ -0,0 +1,36 @@
1
+ import { makePluginName } from "../helpers/makePluginName.mjs";
2
+ import { fixViteVanillaExtractDepScanPlugin } from "./esbuild/fixViteVanillaExtractDepScanPlugin.mjs";
3
+ import { createRequire } from "node:module";
4
+
5
+ //#region src/services/vite/plugins/config.ts
6
+ const require = createRequire(import.meta.url);
7
+ const renderEntry = require.resolve("#entries/vite-render");
8
+ const clientEntry = require.resolve("#entries/vite-client");
9
+ const configPlugin = ({ skuContext }) => ({
10
+ name: makePluginName("config"),
11
+ config: () => ({
12
+ publicDir: false,
13
+ root: process.cwd(),
14
+ resolve: { alias: {
15
+ __sku_alias__clientEntry: skuContext.paths.clientEntry,
16
+ __sku_alias__serverEntry: skuContext.paths.serverEntry,
17
+ __sku_alias__renderEntry: skuContext.paths.renderEntry
18
+ } },
19
+ define: { "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) },
20
+ optimizeDeps: {
21
+ entries: [
22
+ skuContext.paths.clientEntry,
23
+ skuContext.paths.serverEntry,
24
+ skuContext.paths.renderEntry,
25
+ renderEntry,
26
+ clientEntry
27
+ ],
28
+ esbuildOptions: { plugins: [fixViteVanillaExtractDepScanPlugin()] },
29
+ exclude: skuContext.skipPackageCompatibilityCompilation
30
+ },
31
+ ssr: { external: ["serialize-javascript", "@sku-lib/vite"] }
32
+ })
33
+ });
34
+
35
+ //#endregion
36
+ export { configPlugin };
@@ -1,10 +1,12 @@
1
+ import { makePluginName } from "../helpers/makePluginName.mjs";
2
+
1
3
  //#region src/services/vite/plugins/dangerouslySetViteConfig.ts
2
- function dangerouslySetViteConfig(skuContext) {
4
+ function dangerouslySetViteConfigPlugin(skuContext) {
3
5
  return {
4
- name: "vite-plugin-dangerously-set-config",
6
+ name: makePluginName("dangerously-set-vite-config"),
5
7
  config: skuContext.viteDecorator
6
8
  };
7
9
  }
8
10
 
9
11
  //#endregion
10
- export { dangerouslySetViteConfig };
12
+ export { dangerouslySetViteConfigPlugin };
@@ -0,0 +1,25 @@
1
+ import { serverUrls } from "../../../private/utils/src/serverUrls.mjs";
2
+ import isCI_default from "../../../utils/isCI.mjs";
3
+ import { getAppHosts } from "../../../context/hosts.mjs";
4
+ import { makePluginName } from "../helpers/makePluginName.mjs";
5
+
6
+ //#region src/services/vite/plugins/devServer.ts
7
+ const shouldOpenTab = process.env.OPEN_TAB !== "false" && !isCI_default;
8
+ const disableWatch = Boolean(process.env.SKU_VITE_DISABLE_WATCH);
9
+ const devServerPlugin = ({ skuContext }) => ({
10
+ name: makePluginName("dev-server"),
11
+ config: () => ({ server: {
12
+ watch: disableWatch ? null : {},
13
+ host: "localhost",
14
+ allowedHosts: getAppHosts(skuContext).filter((host) => typeof host === "string"),
15
+ open: shouldOpenTab && serverUrls({
16
+ hosts: getAppHosts(skuContext),
17
+ port: skuContext.port.client,
18
+ initialPath: skuContext.initialPath,
19
+ https: skuContext.httpsDevServer
20
+ }).first()
21
+ } })
22
+ });
23
+
24
+ //#endregion
25
+ export { devServerPlugin };
@@ -1,3 +1,4 @@
1
+ import { makePluginName } from "../../helpers/makePluginName.mjs";
1
2
  import { createRequire } from "node:module";
2
3
  import { dirname } from "node:path";
3
4
  import { cssFileFilter } from "@vanilla-extract/integration";
@@ -5,7 +6,7 @@ import { cssFileFilter } from "@vanilla-extract/integration";
5
6
  //#region src/services/vite/plugins/esbuild/fixViteVanillaExtractDepScanPlugin.ts
6
7
  const require = createRequire(import.meta.url);
7
8
  const fixViteVanillaExtractDepScanPlugin = () => ({
8
- name: "fix-vite-vanilla-extract-dep-scan",
9
+ name: makePluginName("fix-vanilla-extract-dep-scan"),
9
10
  setup(build) {
10
11
  build.onResolve({ filter: cssFileFilter }, ({ importer, path: path$1 }) => ({
11
12
  path: require.resolve(path$1, { paths: [dirname(importer)] }),
@@ -2,7 +2,7 @@ import { getAppHosts } from "../../../context/hosts.mjs";
2
2
  import path from "node:path";
3
3
  import basicSsl from "@vitejs/plugin-basic-ssl";
4
4
 
5
- //#region src/services/vite/plugins/httpsDevServerPlugin.ts
5
+ //#region src/services/vite/plugins/httpsDevServer.ts
6
6
  const httpsDevServerPlugin = (skuContext) => {
7
7
  if (!skuContext.httpsDevServer) return [];
8
8
  const certDir = path.join(process.cwd(), ".ssl");
@@ -2,16 +2,17 @@ import { getMatchingRoute } from "../../../utils/routeMatcher.mjs";
2
2
  import { getLanguageFromRoute, getRouteWithLanguage } from "../../../utils/language-utils.mjs";
3
3
  import { metricsMeasurers } from "../../telemetry/metricsMeasurers.mjs";
4
4
  import createCSPHandler from "../../webpack/entry/csp.mjs";
5
+ import { makePluginName } from "../helpers/makePluginName.mjs";
5
6
  import { createRequire } from "node:module";
6
7
  import debug from "debug";
7
8
 
8
- //#region src/services/vite/plugins/middlewarePlugin.ts
9
+ //#region src/services/vite/plugins/middleware.ts
9
10
  const log = debug("sku:middleware:vite");
10
11
  const require = createRequire(import.meta.url);
11
12
  const renderEntry = require.resolve("#entries/vite-render");
12
13
  const clientEntry = require.resolve("#entries/vite-client");
13
14
  const middlewarePlugin = ({ skuContext, environment }) => ({
14
- name: "vite-plugin-sku-server-middleware",
15
+ name: makePluginName("middleware"),
15
16
  async configureServer(server) {
16
17
  if (metricsMeasurers.initialPageLoad.isInitialPageLoad && metricsMeasurers.initialPageLoad.openTab) metricsMeasurers.initialPageLoad.mark();
17
18
  if (skuContext.paths.devServerMiddleware) {
@@ -1,12 +1,13 @@
1
+ import { makePluginName } from "../helpers/makePluginName.mjs";
1
2
  import { resolvePolyfills } from "../../../utils/resolvePolyfills.mjs";
2
3
 
3
- //#region src/services/vite/plugins/polyfillsPlugin.ts
4
+ //#region src/services/vite/plugins/polyfills.ts
4
5
  const polyfillsPlugin = (skuContext) => {
5
6
  const virtualModuleId = "virtual:sku/polyfills";
6
7
  const resolvedVirtualModuleId = `\0${virtualModuleId}`;
7
8
  const resolvedPolyfills = resolvePolyfills(skuContext.polyfills);
8
9
  return {
9
- name: "vite-plugin-sku-polyfills",
10
+ name: makePluginName("polyfills"),
10
11
  resolveId(id) {
11
12
  if (id === virtualModuleId) return resolvedVirtualModuleId;
12
13
  },
@@ -1,5 +1,6 @@
1
1
  import { getExecuteCommand } from "../../../../private/utils/src/packageManager/packageManager.mjs";
2
2
  import "../../../../private/utils/src/index.mjs";
3
+ import { makePluginName } from "../../helpers/makePluginName.mjs";
3
4
  import { VITE_LOADABLE_IMPORT, WEBPACK_LOADABLE_IMPORT } from "./helpers/constants.mjs";
4
5
  import { getViteLoadableSpecifierName } from "./helpers/getViteLoadableSpecifierName.mjs";
5
6
  import { getWebpackLoadableSpecifierName } from "./helpers/getWebpackLoadableSpecifierName.mjs";
@@ -18,14 +19,10 @@ function preloadPlugin({ debug, convertFromWebpack } = {}) {
18
19
  const lazyImportedModules = /* @__PURE__ */ new Set();
19
20
  const injectedModules = /* @__PURE__ */ new Set();
20
21
  let count = 0;
21
- let isSsr = false;
22
22
  return {
23
- name: "vite-plugin-sku-vite-preload",
24
- apply(config) {
25
- isSsr = Boolean(config.build?.ssr);
26
- return true;
27
- },
23
+ name: makePluginName("preload"),
28
24
  async transform(code, id) {
25
+ const isSsr = this.environment?.name === "ssr";
29
26
  if (!include.test(id)) return null;
30
27
  if (code.includes(WEBPACK_LOADABLE_IMPORT) && code.includes(VITE_LOADABLE_IMPORT)) throw new Error(`Both ${WEBPACK_LOADABLE_IMPORT} and ${VITE_LOADABLE_IMPORT} imports found in ${id}. Please remove one of them.`);
31
28
  let ast;
@@ -1,9 +1,11 @@
1
+ import { makePluginName } from "../helpers/makePluginName.mjs";
1
2
  import { extractDependencyGraph, getSsrExternalsForCompiledDependency } from "../helpers/config/dependencyGraph.mjs";
2
3
 
3
4
  //#region src/services/vite/plugins/setNoExternal.ts
4
- function setNoExternal(skuContext) {
5
+ function setNoExternalPlugin(skuContext) {
5
6
  return {
6
- name: "vite-plugin-set-no-external",
7
+ name: makePluginName("set-no-external"),
8
+ applyToEnvironment: (environment) => environment.name === "ssr",
7
9
  async config() {
8
10
  const ssrExternals = getSsrExternalsForCompiledDependency("@vanilla-extract/css", await extractDependencyGraph(process.cwd()));
9
11
  return { resolve: { noExternal: [...skuContext.paths.compilePackages, ...ssrExternals.noExternal] } };
@@ -12,4 +14,4 @@ function setNoExternal(skuContext) {
12
14
  }
13
15
 
14
16
  //#endregion
15
- export { setNoExternal };
17
+ export { setNoExternalPlugin };
@@ -0,0 +1,93 @@
1
+ import telemetry_default from "../../telemetry/index.mjs";
2
+ import { metricsMeasurers } from "../../telemetry/metricsMeasurers.mjs";
3
+ import { makePluginName } from "../helpers/makePluginName.mjs";
4
+ import debug from "debug";
5
+ import dedent from "dedent";
6
+
7
+ //#region src/services/vite/plugins/telemetry.ts
8
+ const log = debug("sku:metrics");
9
+ const customHmrEvent = "sku:vite-hmr";
10
+ const initialPageLoadEvent = "sku:initialPageLoad";
11
+ const telemetryPlugin = ({ target, type }) => {
12
+ const hmrUpdateTimestamps = /* @__PURE__ */ new Set();
13
+ return {
14
+ apply: "serve",
15
+ name: makePluginName("telemetry"),
16
+ transformIndexHtml: {
17
+ order: "pre",
18
+ handler: () => [{
19
+ tag: "script",
20
+ attrs: { type: "module" },
21
+ children: skuPageLoadTelemetryClient,
22
+ injectTo: "head"
23
+ }, {
24
+ tag: "script",
25
+ attrs: { type: "module" },
26
+ children: skuHmrTelemetryClient,
27
+ injectTo: "head"
28
+ }]
29
+ },
30
+ handleHotUpdate: {
31
+ order: "pre",
32
+ handler: (ctx) => {
33
+ hmrUpdateTimestamps.add(ctx.timestamp);
34
+ }
35
+ },
36
+ configureServer(server) {
37
+ server.ws.on(initialPageLoadEvent, handleInitialPageLoadEvent({
38
+ target,
39
+ type
40
+ }));
41
+ server.ws.on(customHmrEvent, handleCustomHmrEvent(hmrUpdateTimestamps, {
42
+ target,
43
+ type
44
+ }));
45
+ }
46
+ };
47
+ };
48
+ /**
49
+ * This client script is used to measure the initial page load time.
50
+ */
51
+ const skuPageLoadTelemetryClient = dedent`
52
+ addEventListener("load", () => {
53
+ if (import.meta.hot) {
54
+ import.meta.hot.send('${initialPageLoadEvent}');
55
+ }
56
+ })
57
+ `;
58
+ const handleInitialPageLoadEvent = (tags) => () => {
59
+ if (metricsMeasurers.initialPageLoad.isInitialPageLoad && metricsMeasurers.initialPageLoad.openTab) {
60
+ const { duration: skuStartDuration } = metricsMeasurers.skuStart.measure();
61
+ const { duration: initialLoadDuration } = metricsMeasurers.initialPageLoad.measure();
62
+ const initialStartTime = skuStartDuration + initialLoadDuration;
63
+ telemetry_default.timing("start.initial", initialStartTime, tags);
64
+ }
65
+ };
66
+ /**
67
+ * This client script is used to measure the HMR time.
68
+ */
69
+ const skuHmrTelemetryClient = dedent`
70
+ if (import.meta.hot) {
71
+ import.meta.hot.on('vite:beforeUpdate', () => {
72
+ performance.mark("vite-hmr");
73
+ })
74
+
75
+ import.meta.hot.on('vite:afterUpdate', (ctx) => {
76
+ const result = performance.measure("hmr-time", "vite-hmr");
77
+ const timestamp = ctx.updates[0].timestamp;
78
+
79
+ import.meta.hot.send('${customHmrEvent}', { durationInMs: result.duration, timestamp });
80
+ })
81
+ }
82
+ `;
83
+ const handleCustomHmrEvent = (timestamps, tags) => (data) => {
84
+ const { durationInMs, timestamp } = data;
85
+ if (timestamps.has(timestamp)) {
86
+ timestamps.delete(timestamp);
87
+ log("HMR update completed in %dms", durationInMs);
88
+ telemetry_default.timing("start.rebuild", durationInMs, tags);
89
+ }
90
+ };
91
+
92
+ //#endregion
93
+ export { telemetryPlugin };
@@ -0,0 +1,40 @@
1
+ import { httpsDevServerPlugin } from "./plugins/httpsDevServer.mjs";
2
+ import { middlewarePlugin } from "./plugins/middleware.mjs";
3
+ import { vitePluginSsrCss } from "./plugins/ssrCss/plugin.mjs";
4
+ import { preloadPlugin } from "./plugins/preloadPlugin/preloadPlugin.mjs";
5
+ import { setNoExternalPlugin } from "./plugins/setNoExternal.mjs";
6
+ import { polyfillsPlugin } from "./plugins/polyfills.mjs";
7
+ import { dangerouslySetViteConfigPlugin } from "./plugins/dangerouslySetViteConfig.mjs";
8
+ import { telemetryPlugin } from "./plugins/telemetry.mjs";
9
+ import { configPlugin } from "./plugins/config.mjs";
10
+ import { buildPlugin } from "./plugins/build.mjs";
11
+ import { devServerPlugin } from "./plugins/devServer.mjs";
12
+ import { bundleAnalyzerPlugin } from "./plugins/bundleAnalyzer.mjs";
13
+
14
+ //#region src/services/vite/skuPlugin.ts
15
+ /**
16
+ * All sku related functionality and customization as a vite plugin.
17
+ */
18
+ const skuPlugin = ({ skuContext, environment }) => [
19
+ configPlugin({ skuContext }),
20
+ dangerouslySetViteConfigPlugin(skuContext),
21
+ setNoExternalPlugin(skuContext),
22
+ buildPlugin({ skuContext }),
23
+ devServerPlugin({ skuContext }),
24
+ httpsDevServerPlugin(skuContext),
25
+ preloadPlugin({ convertFromWebpack: skuContext.convertLoadable }),
26
+ polyfillsPlugin(skuContext),
27
+ vitePluginSsrCss({ entries: [skuContext.paths.renderEntry] }),
28
+ environment !== void 0 && middlewarePlugin({
29
+ skuContext,
30
+ environment
31
+ }),
32
+ telemetryPlugin({
33
+ target: "node",
34
+ type: "static"
35
+ }),
36
+ bundleAnalyzerPlugin()
37
+ ];
38
+
39
+ //#endregion
40
+ export { skuPlugin };
@@ -24,7 +24,7 @@ var MetricsPlugin = class {
24
24
  compiler.hooks.done.tap(smp, () => {
25
25
  if (this.initial) {
26
26
  log("Initial \"%s\" build complete: %s", this.target, { toString: () => prettyMilliseconds(performance.now()) });
27
- telemetry_default.timing("start.webpack.initial", performance.now(), {
27
+ telemetry_default.timing("start.initial", performance.now(), {
28
28
  target: this.target,
29
29
  type: this.type
30
30
  });
@@ -32,7 +32,7 @@ var MetricsPlugin = class {
32
32
  } else {
33
33
  const rebuildTime = performance.now() - this.startTime;
34
34
  log("Rebuild for \"%s\" complete: %s", this.target, { toString: () => prettyMilliseconds(rebuildTime) });
35
- telemetry_default.timing("start.webpack.rebuild", rebuildTime, {
35
+ telemetry_default.timing("start.rebuild", rebuildTime, {
36
36
  target: this.target,
37
37
  type: this.type
38
38
  });
@@ -2,8 +2,8 @@ import { cwd } from "../../../private/utils/src/filesystem/cwd.mjs";
2
2
  import "../../../private/utils/src/index.mjs";
3
3
  import { browserslistNodeTarget } from "../../../config/targets.mjs";
4
4
  import { bundleAnalyzerPlugin } from "./plugins/bundleAnalyzer.mjs";
5
- import { resolvePolyfills } from "../../../utils/resolvePolyfills.mjs";
6
5
  import { getVocabConfig } from "../../vocab/config.mjs";
6
+ import { resolvePolyfills } from "../../../utils/resolvePolyfills.mjs";
7
7
  import { resolvePackage } from "./utils/resolvePackage.mjs";
8
8
  import { JAVASCRIPT } from "./utils/index.mjs";
9
9
  import { SkuWebpackPlugin } from "../../../webpack-plugin.mjs";
@@ -2,8 +2,8 @@ import { requireFromCwd } from "../../../private/utils/src/filesystem/cwd.mjs";
2
2
  import "../../../private/utils/src/index.mjs";
3
3
  import { browserslistNodeTarget } from "../../../config/targets.mjs";
4
4
  import { bundleAnalyzerPlugin } from "./plugins/bundleAnalyzer.mjs";
5
- import { resolvePolyfills } from "../../../utils/resolvePolyfills.mjs";
6
5
  import { getVocabConfig } from "../../vocab/config.mjs";
6
+ import { resolvePolyfills } from "../../../utils/resolvePolyfills.mjs";
7
7
  import { resolvePackage } from "./utils/resolvePackage.mjs";
8
8
  import { JAVASCRIPT } from "./utils/index.mjs";
9
9
  import { SkuWebpackPlugin } from "../../../webpack-plugin.mjs";
@@ -1,28 +1,24 @@
1
1
  import { serverUrls } from "../private/utils/src/serverUrls.mjs";
2
2
  import "../private/utils/src/index.mjs";
3
- import { createOutDir } from "../services/vite/helpers/bundleConfig.mjs";
4
3
  import { getAppHosts } from "../context/hosts.mjs";
5
- import { createClientBuildConfig, createServerBuildConfig, createStartConfig } from "../services/vite/helpers/config/createConfig.mjs";
4
+ import { createOutDir } from "../services/vite/helpers/bundleConfig.mjs";
5
+ import { createConfig } from "../services/vite/helpers/config/createConfig.mjs";
6
6
  import { cleanTargetDirectory } from "../utils/buildFileUtils.mjs";
7
7
  import { prerenderConcurrently } from "../services/vite/helpers/prerender/prerenderConcurrently.mjs";
8
8
  import allocatePort_default from "../utils/allocatePort.mjs";
9
- import { build, createServer } from "vite";
9
+ import { createBuilder, createServer } from "vite";
10
10
 
11
11
  //#region src/services/vite/index.ts
12
12
  const viteService = {
13
13
  build: async (skuContext) => {
14
14
  const outDir = createOutDir(skuContext.paths.target);
15
- await build(createClientBuildConfig(skuContext));
16
- await build(createServerBuildConfig(skuContext));
15
+ await (await createBuilder(createConfig(skuContext))).buildApp();
17
16
  if (skuContext.routes) await prerenderConcurrently(skuContext);
18
17
  await cleanTargetDirectory(outDir.ssg, true);
19
18
  await cleanTargetDirectory(outDir.join(".vite"), true);
20
19
  },
21
20
  start: async ({ skuContext, environment }) => {
22
- const server = await createServer(createStartConfig({
23
- skuContext,
24
- environment
25
- }));
21
+ const server = await createServer(createConfig(skuContext, environment));
26
22
  const availablePort = await allocatePort_default({
27
23
  port: skuContext.port.client,
28
24
  strictPort: skuContext.port.strictPort
@@ -1,6 +1,6 @@
1
1
  import { createPreRenderedHtml } from "../services/vite/helpers/html/createPreRenderedHtml.mjs";
2
- import { createOutDir, renderEntryChunkName } from "../services/vite/helpers/bundleConfig.mjs";
3
2
  import createCSPHandler from "../services/webpack/entry/csp.mjs";
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
6
  import { readFile, writeFile } from "node:fs/promises";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sku",
3
- "version": "15.10.2",
3
+ "version": "15.10.3",
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": "^0.3.1",
103
+ "@vocab/vite": "^1.0.0",
104
104
  "@vocab/webpack": "^1.2.9",
105
105
  "autoprefixer": "^10.3.1",
106
106
  "babel-jest": "^30.0.0",
@@ -1,94 +0,0 @@
1
- import { polyfillsPlugin } from "../../plugins/polyfillsPlugin.mjs";
2
- import { preloadPlugin } from "../../plugins/preloadPlugin/preloadPlugin.mjs";
3
- import { fixViteVanillaExtractDepScanPlugin } from "../../plugins/esbuild/fixViteVanillaExtractDepScanPlugin.mjs";
4
- import { getVocabConfig } from "../../../vocab/config.mjs";
5
- import { dangerouslySetViteConfig } from "../../plugins/dangerouslySetViteConfig.mjs";
6
- import { setNoExternal } from "../../plugins/setNoExternal.mjs";
7
- import browserslistToEsbuild from "../browserslist-to-esbuild.mjs";
8
- import { createRequire } from "node:module";
9
- import { createVocabChunks } from "@vocab/vite/chunks";
10
- import { mergeConfig } from "vite";
11
- import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
12
- import react from "@vitejs/plugin-react";
13
- import tsconfigPaths from "vite-tsconfig-paths";
14
- import { vitePluginVocab } from "@vocab/vite";
15
- import { cjsInterop } from "vite-plugin-cjs-interop";
16
-
17
- //#region src/services/vite/helpers/config/baseConfig.ts
18
- const require = createRequire(import.meta.url);
19
- const getBaseConfig = (skuContext) => {
20
- const vocabConfig = getVocabConfig(skuContext);
21
- const isProductionBuild = process.env.NODE_ENV === "production";
22
- const prodBabelPlugins = [
23
- require.resolve("babel-plugin-transform-react-remove-prop-types"),
24
- require.resolve("@babel/plugin-transform-react-constant-elements"),
25
- [require.resolve("babel-plugin-unassert"), {
26
- variables: ["assert", "invariant"],
27
- modules: [
28
- "assert",
29
- "node:assert",
30
- "tiny-invariant"
31
- ]
32
- }]
33
- ];
34
- if (skuContext.displayNamesProd) prodBabelPlugins.push(require.resolve("@sku-lib/babel-plugin-display-name"));
35
- return {
36
- base: skuContext.publicPath,
37
- publicDir: false,
38
- root: process.cwd(),
39
- plugins: [
40
- dangerouslySetViteConfig(skuContext),
41
- skuContext.vitePlugins,
42
- vocabConfig && vitePluginVocab({ vocabConfig }),
43
- tsconfigPaths(),
44
- cjsInterop({
45
- dependencies: skuContext.serveCjsInteropDependencies,
46
- apply: "serve"
47
- }),
48
- cjsInterop({
49
- dependencies: skuContext.buildCjsInteropDependencies,
50
- apply: "build"
51
- }),
52
- react({ babel: { plugins: [require.resolve("babel-plugin-macros"), ...isProductionBuild ? prodBabelPlugins : []] } }),
53
- vanillaExtractPlugin(),
54
- preloadPlugin({ convertFromWebpack: skuContext.convertLoadable }),
55
- polyfillsPlugin(skuContext),
56
- setNoExternal(skuContext)
57
- ],
58
- resolve: { alias: {
59
- __sku_alias__clientEntry: skuContext.paths.clientEntry,
60
- __sku_alias__serverEntry: skuContext.paths.serverEntry,
61
- __sku_alias__renderEntry: skuContext.paths.renderEntry
62
- } },
63
- define: { "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) },
64
- build: {
65
- target: browserslistToEsbuild(skuContext.supportedBrowsers),
66
- emptyOutDir: true,
67
- ssrManifest: false,
68
- assetsDir: "",
69
- rollupOptions: { output: {
70
- experimentalMinChunkSize: void 0,
71
- manualChunks: (id, ctx) => {
72
- const languageChunkName = createVocabChunks(id, ctx);
73
- if (languageChunkName) return languageChunkName;
74
- }
75
- } }
76
- },
77
- optimizeDeps: {
78
- esbuildOptions: { plugins: [fixViteVanillaExtractDepScanPlugin()] },
79
- exclude: skuContext.skipPackageCompatibilityCompilation
80
- },
81
- ssr: { external: ["serialize-javascript", "@sku-lib/vite"] }
82
- };
83
- };
84
- const getVitestBaseConfig = (skuContext) => ({ plugins: [
85
- tsconfigPaths(),
86
- react(),
87
- setNoExternal(skuContext),
88
- vanillaExtractPlugin()
89
- ] });
90
- const createSkuViteConfig = (config, skuContext) => mergeConfig(getBaseConfig(skuContext), config);
91
- const createSkuVitestConfig = (config, skuContext) => mergeConfig(getVitestBaseConfig(skuContext), config);
92
-
93
- //#endregion
94
- export { createSkuViteConfig, createSkuVitestConfig };
@@ -1,58 +0,0 @@
1
- import telemetry_default from "../../telemetry/index.mjs";
2
- import debug from "debug";
3
- import dedent from "dedent";
4
-
5
- //#region src/services/vite/plugins/HMRTelemetry.ts
6
- const log = debug("sku:metrics");
7
- const customHmrEvent = "sku:vite-hmr";
8
- function HMRTelemetryPlugin({ target, type }) {
9
- const hmrUpdateTimestamps = /* @__PURE__ */ new Set();
10
- return {
11
- name: "vite-plugin-sku-hmr-telemetry",
12
- transformIndexHtml: {
13
- order: "pre",
14
- handler: () => [{
15
- tag: "script",
16
- attrs: { type: "module" },
17
- children: skuHmrTelemetryClient,
18
- injectTo: "head"
19
- }]
20
- },
21
- handleHotUpdate: {
22
- order: "pre",
23
- handler: (ctx) => {
24
- hmrUpdateTimestamps.add(ctx.timestamp);
25
- }
26
- },
27
- configureServer: (server) => {
28
- server.ws.on(customHmrEvent, (data) => {
29
- const { durationInMs, timestamp } = data;
30
- if (hmrUpdateTimestamps.has(timestamp)) {
31
- hmrUpdateTimestamps.delete(timestamp);
32
- log("HMR update completed in %dms", durationInMs);
33
- telemetry_default.timing("start.webpack.rebuild", durationInMs, {
34
- target,
35
- type
36
- });
37
- }
38
- });
39
- }
40
- };
41
- }
42
- const skuHmrTelemetryClient = dedent`
43
- if (import.meta.hot) {
44
- import.meta.hot.on('vite:beforeUpdate', () => {
45
- performance.mark("vite-hmr");
46
- })
47
-
48
- import.meta.hot.on('vite:afterUpdate', (ctx) => {
49
- const result = performance.measure("hmr-time", "vite-hmr");
50
- const timestamp = ctx.updates[0].timestamp;
51
-
52
- import.meta.hot.send('${customHmrEvent}', { durationInMs: result.duration, timestamp });
53
- })
54
- }
55
- `;
56
-
57
- //#endregion
58
- export { HMRTelemetryPlugin };
@@ -1,41 +0,0 @@
1
- import telemetry_default from "../../telemetry/index.mjs";
2
- import { metricsMeasurers } from "../../telemetry/metricsMeasurers.mjs";
3
- import dedent from "dedent";
4
-
5
- //#region src/services/vite/plugins/startTelemetry.ts
6
- const initialPageLoadEventName = "sku:initialPageLoad";
7
- const startTelemetryPlugin = ({ target, type }) => ({
8
- name: "vite-plugin-sku-server-middleware",
9
- transformIndexHtml: {
10
- order: "pre",
11
- handler: () => [{
12
- tag: "script",
13
- attrs: { type: "module" },
14
- children: skuPageLoadTelemetryClient,
15
- injectTo: "head"
16
- }]
17
- },
18
- configureServer(server) {
19
- server.ws.on(initialPageLoadEventName, () => {
20
- if (metricsMeasurers.initialPageLoad.isInitialPageLoad && metricsMeasurers.initialPageLoad.openTab) {
21
- const { duration: skuStartDuration } = metricsMeasurers.skuStart.measure();
22
- const { duration: initialLoadDuration } = metricsMeasurers.initialPageLoad.measure();
23
- const initialStartTime = skuStartDuration + initialLoadDuration;
24
- telemetry_default.timing("start.webpack.initial", initialStartTime, {
25
- target,
26
- type
27
- });
28
- }
29
- });
30
- }
31
- });
32
- const skuPageLoadTelemetryClient = dedent`
33
- addEventListener("load", () => {
34
- if (import.meta.hot) {
35
- import.meta.hot.send('${initialPageLoadEventName}');
36
- }
37
- })
38
- `;
39
-
40
- //#endregion
41
- export { startTelemetryPlugin };