@nuxt/vite-builder-nightly 4.2.0-29334960.22f4693a → 4.2.0-29335187.d989fb8b

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/dist/index.mjs CHANGED
@@ -2,34 +2,35 @@ import fs, { existsSync, readFileSync } from 'node:fs';
2
2
  import * as vite from 'vite';
3
3
  import { isCSSRequest, createLogger } from 'vite';
4
4
  import { dirname, normalize, resolve, join, relative, basename, isAbsolute } from 'pathe';
5
- import { useNitro, logger, useNuxt, resolvePath, getLayerDirectories, createIsIgnored, addVitePlugin } from '@nuxt/kit';
6
- import replacePlugin from '@rollup/plugin-replace';
5
+ import { useNitro, logger, useNuxt, resolvePath, getLayerDirectories, createIsIgnored } from '@nuxt/kit';
7
6
  import { findStaticImports, sanitizeFilePath } from 'mlly';
8
7
  import { parseURL, parseQuery, joinURL, getQuery, withLeadingSlash, withTrailingSlash, withoutLeadingSlash, withoutBase } from 'ufo';
9
8
  import { filename as filename$1 } from 'pathe/utils';
10
- import { resolveTSConfig, readTSConfig } from 'pkg-types';
11
9
  import { resolveModulePath } from 'exsolve';
12
10
  import vuePlugin from '@vitejs/plugin-vue';
13
11
  import viteJsxPlugin from '@vitejs/plugin-vue-jsx';
14
- import { getPort } from 'get-port-please';
15
- import defu$1, { defu } from 'defu';
16
12
  import { defineEnv } from 'unenv';
17
- import { createError, defineEventHandler, handleCors, setHeader } from 'h3';
18
13
  import { pathToFileURL, fileURLToPath } from 'node:url';
19
14
  import MagicString from 'magic-string';
20
15
  import { unlink, mkdir, writeFile, rm, readFile } from 'node:fs/promises';
21
16
  import net from 'node:net';
22
17
  import os from 'node:os';
23
18
  import { Buffer } from 'node:buffer';
19
+ import { createError, defineEventHandler, handleCors, setHeader } from 'h3';
24
20
  import { ViteNodeServer } from 'vite-node/server';
25
21
  import { normalizeViteManifest, precomputeDependencies } from 'vue-bundle-renderer';
26
22
  import { provider, hasTTY, isCI } from 'std-env';
27
23
  import { colorize } from 'consola/utils';
28
24
  import escapeStringRegexp from 'escape-string-regexp';
25
+ import { transform } from 'esbuild';
26
+ import defu from 'defu';
27
+ import { getPort } from 'get-port-please';
28
+ import { resolveTSConfig, readTSConfig } from 'pkg-types';
29
29
  import { serialize } from 'seroval';
30
30
  import { isBuiltin } from 'node:module';
31
31
  import { createJiti } from 'jiti';
32
32
  import { genImport, genArrayFromRaw, genObjectFromRawEntries } from 'knitwork';
33
+ import replacePlugin from '@rollup/plugin-replace';
33
34
 
34
35
  function isVue(id, opts = {}) {
35
36
  const { search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
@@ -787,18 +788,18 @@ function StableEntryPlugin(nuxt) {
787
788
  configResolved(config) {
788
789
  sourcemap = !!config.build.sourcemap;
789
790
  },
790
- applyToEnvironment: (environment) => environment.name === "client",
791
- apply(config) {
792
- if (nuxt.options.dev || !nuxt.options.experimental.entryImportMap) {
791
+ apply: () => !nuxt.options.dev && nuxt.options.experimental.entryImportMap,
792
+ applyToEnvironment(environment) {
793
+ if (environment.name !== "client") {
793
794
  return false;
794
795
  }
795
- if (config.build?.target) {
796
- const targets = toArray(config.build.target);
796
+ if (environment.config.build.target) {
797
+ const targets = toArray(environment.config.build.target);
797
798
  if (!targets.every(isSupported)) {
798
799
  return false;
799
800
  }
800
801
  }
801
- return toArray(config.build?.rollupOptions?.output).some((output) => typeof output?.entryFileNames === "string" && output?.entryFileNames.includes("[hash]"));
802
+ return toArray(environment.config.build.rollupOptions?.output).some((output) => typeof output?.entryFileNames === "string" && output?.entryFileNames.includes("[hash]"));
802
803
  },
803
804
  renderChunk(code, chunk, _options, meta) {
804
805
  const entry = Object.values(meta.chunks).find((chunk2) => chunk2.isEntry && chunk2.name === "entry")?.fileName;
@@ -844,11 +845,191 @@ function isSupported(target) {
844
845
  return Number.isNaN(version) || Number(version) >= constraint;
845
846
  }
846
847
 
848
+ async function AnalyzePlugin(nuxt) {
849
+ if (nuxt.options.test) {
850
+ return;
851
+ }
852
+ const analyzeOptions = defu({}, nuxt.options.build.analyze);
853
+ if (!analyzeOptions.enabled) {
854
+ return;
855
+ }
856
+ const { visualizer } = await import('rollup-plugin-visualizer');
857
+ return {
858
+ name: "nuxt:analyze",
859
+ applyToEnvironment(environment) {
860
+ if (environment.name !== "client") {
861
+ return false;
862
+ }
863
+ return [
864
+ {
865
+ name: "nuxt:analyze-minify",
866
+ async generateBundle(_opts, outputBundle) {
867
+ for (const _bundleId in outputBundle) {
868
+ const bundle = outputBundle[_bundleId];
869
+ if (!bundle || bundle.type !== "chunk") {
870
+ continue;
871
+ }
872
+ const minifiedModuleEntryPromises = [];
873
+ for (const [moduleId, module] of Object.entries(bundle.modules)) {
874
+ minifiedModuleEntryPromises.push(
875
+ transform(module.code || "", { minify: true }).then((result) => [moduleId, { ...module, code: result.code }])
876
+ );
877
+ }
878
+ bundle.modules = Object.fromEntries(await Promise.all(minifiedModuleEntryPromises));
879
+ }
880
+ }
881
+ },
882
+ visualizer({
883
+ ...analyzeOptions,
884
+ filename: "filename" in analyzeOptions && analyzeOptions.filename ? analyzeOptions.filename.replace("{name}", "client") : void 0,
885
+ title: "Client bundle stats",
886
+ gzipSize: true,
887
+ brotliSize: true
888
+ })
889
+ ];
890
+ }
891
+ };
892
+ }
893
+
894
+ function DevServerPlugin(nuxt) {
895
+ let useViteCors = false;
896
+ const nitro = useNitro();
897
+ return {
898
+ name: "nuxt:dev-server",
899
+ async config(config) {
900
+ for (const item of [config.optimizeDeps, config.environments?.client?.optimizeDeps, config.environments?.ssr?.optimizeDeps]) {
901
+ if (!item) {
902
+ continue;
903
+ }
904
+ const exclude = new Set(item.exclude ?? []);
905
+ item.include = item.include?.filter((dep) => !exclude.has(dep));
906
+ }
907
+ if (!nuxt.options.dev && config.server) {
908
+ config.server.hmr = false;
909
+ }
910
+ useViteCors = config.server?.cors !== void 0;
911
+ if (!useViteCors) {
912
+ config.server ??= {};
913
+ config.server.cors = false;
914
+ }
915
+ if (config.server && config.server.hmr !== false) {
916
+ const serverDefaults = {
917
+ hmr: {
918
+ protocol: nuxt.options.devServer.https ? "wss" : void 0
919
+ }
920
+ };
921
+ if (typeof config.server.hmr !== "object" || !config.server.hmr.server) {
922
+ serverDefaults.hmr ??= {};
923
+ const hmrPortDefault = 24678;
924
+ serverDefaults.hmr.port = await getPort({
925
+ port: hmrPortDefault,
926
+ ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i)
927
+ });
928
+ }
929
+ if (nuxt.options.devServer.https) {
930
+ serverDefaults.https = nuxt.options.devServer.https === true ? {} : nuxt.options.devServer.https;
931
+ }
932
+ config.server = defu(config.server, serverDefaults);
933
+ }
934
+ },
935
+ async configureServer(viteServer) {
936
+ nuxt.hook("app:templatesGenerated", async (_app, changedTemplates) => {
937
+ await Promise.all(changedTemplates.map(async (template) => {
938
+ for (const mod of viteServer.moduleGraph.getModulesByFile(`virtual:nuxt:${encodeURIComponent(template.dst)}`) || []) {
939
+ viteServer.moduleGraph.invalidateModule(mod);
940
+ await viteServer.reloadModule(mod);
941
+ }
942
+ }));
943
+ });
944
+ const mw = {
945
+ route: "",
946
+ handle: (req, res, next) => {
947
+ if (req._skip_transform && req.url) {
948
+ req.url = joinURL("/__skip_vite", req.url.replace(/\?.*/, ""));
949
+ }
950
+ next();
951
+ }
952
+ };
953
+ const transformHandler = viteServer.middlewares.stack.findIndex((m) => m.handle instanceof Function && m.handle.name === "viteTransformMiddleware");
954
+ if (transformHandler === -1) {
955
+ viteServer.middlewares.stack.push(mw);
956
+ } else {
957
+ viteServer.middlewares.stack.splice(transformHandler, 0, mw);
958
+ }
959
+ const staticBases = [];
960
+ for (const folder of nitro.options.publicAssets) {
961
+ if (folder.baseURL && folder.baseURL !== "/" && folder.baseURL.startsWith(nuxt.options.app.buildAssetsDir)) {
962
+ staticBases.push(folder.baseURL.replace(/\/?$/, "/"));
963
+ }
964
+ }
965
+ const devHandlerRegexes = [];
966
+ for (const handler of nuxt.options.devServerHandlers) {
967
+ if (handler.route && handler.route !== "/" && handler.route.startsWith(nuxt.options.app.buildAssetsDir)) {
968
+ devHandlerRegexes.push(new RegExp(
969
+ `^${handler.route.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/:[^/]+/g, "[^/]+").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")}$`
970
+ // single wildcard (*) to match any segment
971
+ ));
972
+ }
973
+ }
974
+ const viteMiddleware = defineEventHandler(async (event) => {
975
+ const viteRoutes = [];
976
+ for (const viteRoute of viteServer.middlewares.stack) {
977
+ const m = viteRoute.route;
978
+ if (m.length > 1) {
979
+ viteRoutes.push(m);
980
+ }
981
+ }
982
+ if (!event.path.startsWith(viteServer.config.base) && !viteRoutes.some((route) => event.path.startsWith(route))) {
983
+ event.node.req._skip_transform = true;
984
+ } else if (!useViteCors) {
985
+ const isPreflight = handleCors(event, nuxt.options.devServer.cors);
986
+ if (isPreflight) {
987
+ return null;
988
+ }
989
+ setHeader(event, "Vary", "Origin");
990
+ }
991
+ const _originalPath = event.node.req.url;
992
+ await new Promise((resolve, reject) => {
993
+ viteServer.middlewares.handle(event.node.req, event.node.res, (err) => {
994
+ event.node.req.url = _originalPath;
995
+ return err ? reject(err) : resolve(null);
996
+ });
997
+ });
998
+ const ended = event.node.res.writableEnded || event.handled;
999
+ if (!ended && event.path.startsWith(nuxt.options.app.buildAssetsDir) && !staticBases.some((baseURL) => event.path.startsWith(baseURL)) && !devHandlerRegexes.some((regex) => regex.test(event.path))) {
1000
+ throw createError({ statusCode: 404 });
1001
+ }
1002
+ });
1003
+ await nuxt.callHook("server:devHandler", viteMiddleware);
1004
+ }
1005
+ };
1006
+ }
1007
+
1008
+ async function VitePluginCheckerPlugin(nuxt, environment) {
1009
+ if (!nuxt.options.test && (nuxt.options.typescript.typeCheck === true || nuxt.options.typescript.typeCheck === "build" && !nuxt.options.dev)) {
1010
+ const [checker, tsconfigPath] = await Promise.all([
1011
+ import('vite-plugin-checker').then((r) => r.default),
1012
+ resolveTSConfig(nuxt.options.rootDir)
1013
+ ]);
1014
+ const supportsProjects = await readTSConfig(tsconfigPath).then((r) => !!r.references?.length);
1015
+ const environments = ["client", nuxt.options.ssr ? "ssr" : void 0].filter((name) => name === environment);
1016
+ return environments.map((envName) => ({
1017
+ applyToEnvironment: (environment2) => environment2.name === envName,
1018
+ ...checker({
1019
+ vueTsc: {
1020
+ tsconfigPath,
1021
+ buildMode: supportsProjects
1022
+ }
1023
+ })
1024
+ }));
1025
+ }
1026
+ }
1027
+
847
1028
  async function buildClient(nuxt, ctx) {
848
1029
  const nodeCompat = nuxt.options.experimental.clientNodeCompat ? {
849
1030
  alias: defineEnv({ nodeCompat: true, resolve: true }).env.alias,
850
1031
  define: { global: "globalThis" }
851
- } : { alias: {}, define: {} };
1032
+ } : { define: {} };
852
1033
  const clientConfig = vite.mergeConfig(ctx.config, vite.mergeConfig({
853
1034
  configFile: false,
854
1035
  base: nuxt.options.dev ? joinURL(nuxt.options.app.baseURL.replace(/^\.\//, "/") || "/", nuxt.options.app.buildAssetsDir) : "./",
@@ -915,19 +1096,6 @@ async function buildClient(nuxt, ctx) {
915
1096
  "#app-manifest"
916
1097
  ]
917
1098
  },
918
- resolve: {
919
- alias: {
920
- // user aliases
921
- ...nodeCompat.alias,
922
- ...ctx.config.resolve?.alias,
923
- "nitro/runtime": join(nuxt.options.buildDir, "nitro.client.mjs"),
924
- // TODO: remove in v5
925
- "#internal/nitro": join(ctx.nuxt.options.buildDir, "nitro.client.mjs"),
926
- "nitropack/runtime": join(ctx.nuxt.options.buildDir, "nitro.client.mjs"),
927
- // work around vite optimizer bug
928
- "#app-manifest": resolveModulePath("mocked-exports/empty", { from: import.meta.url })
929
- }
930
- },
931
1099
  cacheDir: resolve(nuxt.options.rootDir, ctx.config.cacheDir ?? "node_modules/.cache/vite", "client"),
932
1100
  build: {
933
1101
  sourcemap: nuxt.options.sourcemap.client ? ctx.config.build?.sourcemap ?? nuxt.options.sourcemap.client : false,
@@ -948,7 +1116,10 @@ async function buildClient(nuxt, ctx) {
948
1116
  TypeCheckPlugin(nuxt),
949
1117
  ModulePreloadPolyfillPlugin(),
950
1118
  // ensure changes in chunks do not invalidate whole build
951
- StableEntryPlugin(nuxt)
1119
+ StableEntryPlugin(nuxt),
1120
+ AnalyzePlugin(nuxt),
1121
+ DevServerPlugin(nuxt),
1122
+ VitePluginCheckerPlugin(nuxt, "client")
952
1123
  ],
953
1124
  appType: "custom",
954
1125
  server: {
@@ -959,118 +1130,17 @@ async function buildClient(nuxt, ctx) {
959
1130
  }
960
1131
  }, nuxt.options.vite.$client || {}));
961
1132
  clientConfig.customLogger = createViteLogger(clientConfig);
962
- if (!nuxt.options.dev) {
963
- clientConfig.server.hmr = false;
964
- }
965
- const useViteCors = clientConfig.server?.cors !== void 0;
966
- if (!useViteCors) {
967
- clientConfig.server.cors = false;
968
- }
969
- const fileNames = withoutLeadingSlash(join(nuxt.options.app.buildAssetsDir, "[hash].js"));
970
- const clientOutputDir = join(useNitro().options.output.publicDir, nuxt.options.app.buildAssetsDir);
971
- clientConfig.build.rollupOptions = defu(clientConfig.build.rollupOptions, {
972
- output: {
973
- chunkFileNames: nuxt.options.dev ? void 0 : fileNames,
974
- entryFileNames: nuxt.options.dev ? "entry.js" : fileNames,
975
- sourcemapPathTransform(relativeSourcePath, sourcemapPath) {
976
- if (!isAbsolute(relativeSourcePath)) {
977
- const absoluteSourcePath = resolve(dirname(sourcemapPath), relativeSourcePath);
978
- return relative(clientOutputDir, absoluteSourcePath);
979
- }
980
- return relativeSourcePath;
981
- }
982
- }
983
- });
984
- if (clientConfig.server && clientConfig.server.hmr !== false) {
985
- const serverDefaults = {
986
- hmr: {
987
- protocol: nuxt.options.devServer.https ? "wss" : void 0
988
- }
989
- };
990
- if (typeof clientConfig.server.hmr !== "object" || !clientConfig.server.hmr.server) {
991
- const hmrPortDefault = 24678;
992
- serverDefaults.hmr.port = await getPort({
993
- port: hmrPortDefault,
994
- ports: Array.from({ length: 20 }, (_, i) => hmrPortDefault + 1 + i)
995
- });
996
- }
997
- if (nuxt.options.devServer.https) {
998
- serverDefaults.https = nuxt.options.devServer.https === true ? {} : nuxt.options.devServer.https;
999
- }
1000
- clientConfig.server = defu(clientConfig.server, serverDefaults);
1001
- }
1002
- if (!nuxt.options.test && nuxt.options.build.analyze && (nuxt.options.build.analyze === true || nuxt.options.build.analyze.enabled)) {
1003
- clientConfig.plugins.push(...await import('./chunks/analyze.mjs').then((r) => r.AnalyzePlugin(nuxt)));
1004
- }
1005
1133
  await nuxt.callHook("vite:extendConfig", clientConfig, { isClient: true, isServer: false });
1006
1134
  clientConfig.plugins.unshift(
1007
1135
  vuePlugin(clientConfig.vue),
1008
1136
  viteJsxPlugin(clientConfig.vueJsx)
1009
1137
  );
1010
1138
  await nuxt.callHook("vite:configResolved", clientConfig, { isClient: true, isServer: false });
1011
- const exclude = new Set(clientConfig.optimizeDeps.exclude);
1012
- clientConfig.optimizeDeps.include = clientConfig.optimizeDeps.include.filter((dep) => !exclude.has(dep));
1013
1139
  if (nuxt.options.dev) {
1014
1140
  const viteServer = await vite.createServer(clientConfig);
1015
1141
  ctx.clientServer = viteServer;
1016
1142
  nuxt.hook("close", () => viteServer.close());
1017
1143
  await nuxt.callHook("vite:serverCreated", viteServer, { isClient: true, isServer: false });
1018
- const transformHandler = viteServer.middlewares.stack.findIndex((m) => m.handle instanceof Function && m.handle.name === "viteTransformMiddleware");
1019
- viteServer.middlewares.stack.splice(transformHandler, 0, {
1020
- route: "",
1021
- handle: (req, res, next) => {
1022
- if (req._skip_transform) {
1023
- req.url = joinURL("/__skip_vite", req.url.replace(/\?.*/, ""));
1024
- }
1025
- next();
1026
- }
1027
- });
1028
- const staticBases = [];
1029
- for (const folder of useNitro().options.publicAssets) {
1030
- if (folder.baseURL && folder.baseURL !== "/" && folder.baseURL.startsWith(nuxt.options.app.buildAssetsDir)) {
1031
- staticBases.push(folder.baseURL.replace(/\/?$/, "/"));
1032
- }
1033
- }
1034
- const devHandlerRegexes = [];
1035
- for (const handler of nuxt.options.devServerHandlers) {
1036
- if (handler.route && handler.route !== "/" && handler.route.startsWith(nuxt.options.app.buildAssetsDir)) {
1037
- devHandlerRegexes.push(new RegExp(
1038
- `^${handler.route.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/:[^/]+/g, "[^/]+").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")}$`
1039
- // single wildcard (*) to match any segment
1040
- ));
1041
- }
1042
- }
1043
- const viteMiddleware = defineEventHandler(async (event) => {
1044
- const viteRoutes = [];
1045
- for (const viteRoute of viteServer.middlewares.stack) {
1046
- const m = viteRoute.route;
1047
- if (m.length > 1) {
1048
- viteRoutes.push(m);
1049
- }
1050
- }
1051
- if (!event.path.startsWith(clientConfig.base) && !viteRoutes.some((route) => event.path.startsWith(route))) {
1052
- event.node.req._skip_transform = true;
1053
- } else if (!useViteCors) {
1054
- const isPreflight = handleCors(event, nuxt.options.devServer.cors);
1055
- if (isPreflight) {
1056
- return null;
1057
- }
1058
- setHeader(event, "Vary", "Origin");
1059
- }
1060
- const _originalPath = event.node.req.url;
1061
- await new Promise((resolve2, reject) => {
1062
- viteServer.middlewares.handle(event.node.req, event.node.res, (err) => {
1063
- event.node.req.url = _originalPath;
1064
- return err ? reject(err) : resolve2(null);
1065
- });
1066
- });
1067
- if (!event.handled && event.path.startsWith(nuxt.options.app.buildAssetsDir) && !staticBases.some((baseURL) => event.path.startsWith(baseURL)) && !devHandlerRegexes.some((regex) => regex.test(event.path))) {
1068
- throw createError({
1069
- statusCode: 404
1070
- });
1071
- }
1072
- });
1073
- await nuxt.callHook("server:devHandler", viteMiddleware);
1074
1144
  } else {
1075
1145
  logger.info("Building client...");
1076
1146
  const start = Date.now();
@@ -1182,7 +1252,7 @@ const SourcemapPreserverPlugin = (nuxt) => {
1182
1252
  }
1183
1253
  };
1184
1254
  nuxt.hook("nitro:build:before", (nitro) => {
1185
- nitro.options.rollupConfig = defu$1(nitro.options.rollupConfig, {
1255
+ nitro.options.rollupConfig = defu(nitro.options.rollupConfig, {
1186
1256
  plugins: [nitroPlugin]
1187
1257
  });
1188
1258
  });
@@ -1244,7 +1314,8 @@ async function buildServer(nuxt, ctx) {
1244
1314
  plugins: [
1245
1315
  VueFeatureFlagsPlugin(nuxt),
1246
1316
  // tell rollup's nitro build about the original sources of the generated vite server build
1247
- SourcemapPreserverPlugin(nuxt)
1317
+ SourcemapPreserverPlugin(nuxt),
1318
+ VitePluginCheckerPlugin(nuxt, "ssr")
1248
1319
  ],
1249
1320
  define: {
1250
1321
  "process.server": true,
@@ -1339,12 +1410,6 @@ async function buildServer(nuxt, ctx) {
1339
1410
  hmr: false
1340
1411
  }
1341
1412
  }, nuxt.options.vite.$server || {}));
1342
- if (serverConfig.build?.rollupOptions?.output && !Array.isArray(serverConfig.build.rollupOptions.output)) {
1343
- serverConfig.build.rollupOptions.output.manualChunks = void 0;
1344
- if (vite.rolldownVersion) {
1345
- serverConfig.build.rollupOptions.output.advancedChunks = void 0;
1346
- }
1347
- }
1348
1413
  serverConfig.customLogger = createViteLogger(serverConfig, { hideOutput: !nuxt.options.dev });
1349
1414
  await nuxt.callHook("vite:extendConfig", serverConfig, { isClient: false, isServer: true });
1350
1415
  serverConfig.plugins.unshift(
@@ -1372,6 +1437,14 @@ async function buildServer(nuxt, ctx) {
1372
1437
  ctx.ssrServer = ssrServer;
1373
1438
  nuxt.hook("close", () => ssrServer.close());
1374
1439
  await nuxt.callHook("vite:serverCreated", ssrServer, { isClient: false, isServer: true });
1440
+ nuxt.hook("app:templatesGenerated", async (_app, changedTemplates) => {
1441
+ await Promise.all(changedTemplates.map(async (template) => {
1442
+ for (const mod of ssrServer.moduleGraph.getModulesByFile(`virtual:nuxt:${encodeURIComponent(template.dst)}`) || []) {
1443
+ ssrServer.moduleGraph.invalidateModule(mod);
1444
+ await ssrServer.reloadModule(mod);
1445
+ }
1446
+ }));
1447
+ });
1375
1448
  await ssrServer.pluginContainer.buildStart({});
1376
1449
  await writeDevServer(nuxt);
1377
1450
  }
@@ -1458,129 +1531,208 @@ async function resolveCSSOptions(nuxt) {
1458
1531
  }
1459
1532
 
1460
1533
  const SUPPORTED_FILES_RE = /\.(?:vue|(?:[cm]?j|t)sx?)$/;
1461
- function SSRStylesPlugin(options) {
1534
+ function SSRStylesPlugin(nuxt) {
1535
+ if (nuxt.options.dev) {
1536
+ return;
1537
+ }
1538
+ const chunksWithInlinedCSS = /* @__PURE__ */ new Set();
1539
+ const clientCSSMap = {};
1540
+ const nitro = useNitro();
1541
+ nuxt.hook("build:manifest", (manifest) => {
1542
+ const entryIds = /* @__PURE__ */ new Set();
1543
+ for (const id of chunksWithInlinedCSS) {
1544
+ const chunk = manifest[id];
1545
+ if (!chunk) {
1546
+ continue;
1547
+ }
1548
+ if (chunk.isEntry && chunk.src) {
1549
+ entryIds.add(chunk.src);
1550
+ } else {
1551
+ chunk.css &&= [];
1552
+ }
1553
+ }
1554
+ nitro.options.virtual["#internal/nuxt/entry-ids.mjs"] = () => `export default ${JSON.stringify(Array.from(entryIds))}`;
1555
+ nitro.options._config.virtual ||= {};
1556
+ nitro.options._config.virtual["#internal/nuxt/entry-ids.mjs"] = nitro.options.virtual["#internal/nuxt/entry-ids.mjs"];
1557
+ });
1462
1558
  const cssMap = {};
1463
1559
  const idRefMap = {};
1464
- const relativeToSrcDir = (path) => relative(options.srcDir, path);
1560
+ const options = {
1561
+ shouldInline: nuxt.options.features.inlineStyles,
1562
+ globalCSS: nuxt.options.css
1563
+ };
1564
+ const relativeToSrcDir = (path) => relative(nuxt.options.srcDir, path);
1465
1565
  const warnCache = /* @__PURE__ */ new Set();
1466
- const islands = options.components.filter(
1566
+ const components = nuxt.apps.default.components || [];
1567
+ const islands = components.filter(
1467
1568
  (component) => component.island || // .server components without a corresponding .client component will need to be rendered as an island
1468
- component.mode === "server" && !options.components.some((c) => c.pascalName === component.pascalName && c.mode === "client")
1569
+ component.mode === "server" && !components.some((c) => c.pascalName === component.pascalName && c.mode === "client")
1469
1570
  );
1571
+ let entry;
1470
1572
  return {
1471
1573
  name: "ssr-styles",
1472
- resolveId: {
1473
- order: "pre",
1474
- async handler(id, importer, _options) {
1475
- if (options.shouldInline === false || typeof options.shouldInline === "function" && !options.shouldInline(importer)) {
1476
- return;
1477
- }
1478
- if (id === "#build/css" || id.endsWith(".vue") || isCSS(id)) {
1479
- const res = await this.resolve(id, importer, { ..._options, skipSelf: true });
1480
- if (res) {
1481
- return {
1482
- ...res,
1483
- moduleSideEffects: false
1484
- };
1485
- }
1486
- }
1574
+ configResolved(config) {
1575
+ if (!config.build.ssr) {
1576
+ entry = resolveClientEntry(config);
1487
1577
  }
1488
1578
  },
1489
- generateBundle(outputOptions) {
1490
- if (options.mode === "client") {
1491
- return;
1492
- }
1493
- const emitted = {};
1494
- for (const [file, { files, inBundle }] of Object.entries(cssMap)) {
1495
- if (!files.length || !inBundle) {
1496
- continue;
1497
- }
1498
- const fileName = filename(file);
1499
- const base = typeof outputOptions.assetFileNames === "string" ? outputOptions.assetFileNames : outputOptions.assetFileNames({
1500
- type: "asset",
1501
- name: `${fileName}-styles.mjs`,
1502
- names: [`${fileName}-styles.mjs`],
1503
- originalFileName: `${fileName}-styles.mjs`,
1504
- originalFileNames: [`${fileName}-styles.mjs`],
1505
- source: ""
1506
- });
1507
- const baseDir = dirname(base);
1508
- const cssImports = /* @__PURE__ */ new Set();
1509
- const exportNames = /* @__PURE__ */ new Set();
1510
- const importStatements = /* @__PURE__ */ new Set();
1511
- let i = 0;
1512
- for (const css of files) {
1513
- const file2 = this.getFileName(css);
1514
- if (cssImports.has(file2)) {
1515
- continue;
1579
+ applyToEnvironment(environment) {
1580
+ return {
1581
+ name: `nuxt:ssr-styles:${environment.name}`,
1582
+ enforce: "pre",
1583
+ resolveId: {
1584
+ order: "pre",
1585
+ async handler(id, importer, _options) {
1586
+ if (options.shouldInline === false || typeof options.shouldInline === "function" && !options.shouldInline(importer)) {
1587
+ return;
1588
+ }
1589
+ if (id === "#build/css" || id.endsWith(".vue") || isCSS(id)) {
1590
+ const res = await this.resolve(id, importer, { ..._options, skipSelf: true });
1591
+ if (res) {
1592
+ return {
1593
+ ...res,
1594
+ moduleSideEffects: false
1595
+ };
1596
+ }
1597
+ }
1516
1598
  }
1517
- cssImports.add(file2);
1518
- const name = `style_${i++}`;
1519
- importStatements.add(genImport(`./${relative(baseDir, file2)}`, name));
1520
- exportNames.add(name);
1521
- }
1522
- emitted[file] = this.emitFile({
1523
- type: "asset",
1524
- name: `${fileName}-styles.mjs`,
1525
- source: [
1526
- ...importStatements,
1527
- `export default ${genArrayFromRaw([...exportNames])}`
1528
- ].join("\n")
1529
- });
1530
- }
1531
- for (const key in emitted) {
1532
- options.chunksWithInlinedCSS.add(key);
1533
- }
1534
- this.emitFile({
1535
- type: "asset",
1536
- fileName: "styles.mjs",
1537
- originalFileName: "styles.mjs",
1538
- source: [
1539
- "const interopDefault = r => r.default || r || []",
1540
- `export default ${genObjectFromRawEntries(
1541
- Object.entries(emitted).map(([key, value]) => [key, `() => import('./${this.getFileName(value)}').then(interopDefault)`])
1542
- )}`
1543
- ].join("\n")
1544
- });
1545
- },
1546
- renderChunk(_code, chunk) {
1547
- const isEntry = chunk.facadeModuleId === options.entry;
1548
- if (isEntry) {
1549
- options.clientCSSMap[chunk.facadeModuleId] ||= /* @__PURE__ */ new Set();
1550
- }
1551
- for (const moduleId of [chunk.facadeModuleId, ...chunk.moduleIds].filter(Boolean)) {
1552
- if (options.mode === "client") {
1553
- const moduleMap = options.clientCSSMap[moduleId] ||= /* @__PURE__ */ new Set();
1554
- if (isCSS(moduleId)) {
1555
- if (isVue(moduleId)) {
1556
- moduleMap.add(moduleId);
1557
- const parent = moduleId.replace(/\?.+$/, "");
1558
- const parentMap = options.clientCSSMap[parent] ||= /* @__PURE__ */ new Set();
1559
- parentMap.add(moduleId);
1599
+ },
1600
+ generateBundle(outputOptions) {
1601
+ if (environment.name === "client") {
1602
+ return;
1603
+ }
1604
+ const emitted = {};
1605
+ for (const [file, { files, inBundle }] of Object.entries(cssMap)) {
1606
+ if (!files.length || !inBundle) {
1607
+ continue;
1560
1608
  }
1561
- if (isEntry && chunk.facadeModuleId) {
1562
- const facadeMap = options.clientCSSMap[chunk.facadeModuleId] ||= /* @__PURE__ */ new Set();
1563
- facadeMap.add(moduleId);
1609
+ const fileName = filename(file);
1610
+ const base = typeof outputOptions.assetFileNames === "string" ? outputOptions.assetFileNames : outputOptions.assetFileNames({
1611
+ type: "asset",
1612
+ name: `${fileName}-styles.mjs`,
1613
+ names: [`${fileName}-styles.mjs`],
1614
+ originalFileName: `${fileName}-styles.mjs`,
1615
+ originalFileNames: [`${fileName}-styles.mjs`],
1616
+ source: ""
1617
+ });
1618
+ const baseDir = dirname(base);
1619
+ const cssImports = /* @__PURE__ */ new Set();
1620
+ const exportNames = /* @__PURE__ */ new Set();
1621
+ const importStatements = /* @__PURE__ */ new Set();
1622
+ let i = 0;
1623
+ for (const css of files) {
1624
+ const file2 = this.getFileName(css);
1625
+ if (cssImports.has(file2)) {
1626
+ continue;
1627
+ }
1628
+ cssImports.add(file2);
1629
+ const name = `style_${i++}`;
1630
+ importStatements.add(genImport(`./${relative(baseDir, file2)}`, name));
1631
+ exportNames.add(name);
1564
1632
  }
1633
+ emitted[file] = this.emitFile({
1634
+ type: "asset",
1635
+ name: `${fileName}-styles.mjs`,
1636
+ source: [
1637
+ ...importStatements,
1638
+ `export default ${genArrayFromRaw([...exportNames])}`
1639
+ ].join("\n")
1640
+ });
1565
1641
  }
1566
- continue;
1567
- }
1568
- const relativePath = relativeToSrcDir(moduleId);
1569
- if (relativePath in cssMap) {
1570
- cssMap[relativePath].inBundle = cssMap[relativePath].inBundle ?? (isVue(moduleId) && !!relativeToSrcDir(moduleId) || isEntry);
1571
- }
1572
- }
1573
- return null;
1574
- },
1575
- async transform(code, id) {
1576
- if (options.mode === "client") {
1577
- if (id === options.entry && (options.shouldInline === true || typeof options.shouldInline === "function" && options.shouldInline(id))) {
1578
- const s = new MagicString(code);
1579
- const idClientCSSMap = options.clientCSSMap[id] ||= /* @__PURE__ */ new Set();
1580
- if (!options.globalCSS.length) {
1642
+ for (const key in emitted) {
1643
+ chunksWithInlinedCSS.add(key);
1644
+ }
1645
+ this.emitFile({
1646
+ type: "asset",
1647
+ fileName: "styles.mjs",
1648
+ originalFileName: "styles.mjs",
1649
+ source: [
1650
+ "const interopDefault = r => r.default || r || []",
1651
+ `export default ${genObjectFromRawEntries(
1652
+ Object.entries(emitted).map(([key, value]) => [key, `() => import('./${this.getFileName(value)}').then(interopDefault)`])
1653
+ )}`
1654
+ ].join("\n")
1655
+ });
1656
+ },
1657
+ renderChunk(_code, chunk) {
1658
+ const isEntry = chunk.facadeModuleId === entry;
1659
+ if (isEntry) {
1660
+ clientCSSMap[chunk.facadeModuleId] ||= /* @__PURE__ */ new Set();
1661
+ }
1662
+ for (const moduleId of [chunk.facadeModuleId, ...chunk.moduleIds].filter(Boolean)) {
1663
+ if (environment.name === "client") {
1664
+ const moduleMap = clientCSSMap[moduleId] ||= /* @__PURE__ */ new Set();
1665
+ if (isCSS(moduleId)) {
1666
+ if (isVue(moduleId)) {
1667
+ moduleMap.add(moduleId);
1668
+ const parent = moduleId.replace(/\?.+$/, "");
1669
+ const parentMap = clientCSSMap[parent] ||= /* @__PURE__ */ new Set();
1670
+ parentMap.add(moduleId);
1671
+ }
1672
+ if (isEntry && chunk.facadeModuleId) {
1673
+ const facadeMap = clientCSSMap[chunk.facadeModuleId] ||= /* @__PURE__ */ new Set();
1674
+ facadeMap.add(moduleId);
1675
+ }
1676
+ }
1677
+ continue;
1678
+ }
1679
+ const relativePath = relativeToSrcDir(moduleId);
1680
+ if (relativePath in cssMap) {
1681
+ cssMap[relativePath].inBundle = cssMap[relativePath].inBundle ?? (isVue(moduleId) && !!relativeToSrcDir(moduleId) || isEntry);
1682
+ }
1683
+ }
1684
+ return null;
1685
+ },
1686
+ async transform(code, id) {
1687
+ if (environment.name === "client") {
1688
+ if (id === entry && (options.shouldInline === true || typeof options.shouldInline === "function" && options.shouldInline(id))) {
1689
+ const s = new MagicString(code);
1690
+ const idClientCSSMap = clientCSSMap[id] ||= /* @__PURE__ */ new Set();
1691
+ if (!options.globalCSS.length) {
1692
+ return;
1693
+ }
1694
+ for (const file of options.globalCSS) {
1695
+ const resolved = await this.resolve(file) ?? await this.resolve(file, id);
1696
+ const res = await this.resolve(file + "?inline&used") ?? await this.resolve(file + "?inline&used", id);
1697
+ if (!resolved || !res) {
1698
+ if (!warnCache.has(file)) {
1699
+ warnCache.add(file);
1700
+ this.warn(`[nuxt] Cannot extract styles for \`${file}\`. Its styles will not be inlined when server-rendering.`);
1701
+ }
1702
+ s.prepend(`${genImport(file)}
1703
+ `);
1704
+ continue;
1705
+ }
1706
+ idClientCSSMap.add(resolved.id);
1707
+ }
1708
+ if (s.hasChanged()) {
1709
+ return {
1710
+ code: s.toString(),
1711
+ map: s.generateMap({ hires: true })
1712
+ };
1713
+ }
1714
+ }
1715
+ return;
1716
+ }
1717
+ const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
1718
+ if (!(id in clientCSSMap) && !islands.some((c) => c.filePath === pathname)) {
1719
+ return;
1720
+ }
1721
+ const query = parseQuery(search);
1722
+ if (query.macro || query.nuxt_component) {
1581
1723
  return;
1582
1724
  }
1583
- for (const file of options.globalCSS) {
1725
+ if (!islands.some((c) => c.filePath === pathname)) {
1726
+ if (options.shouldInline === false || typeof options.shouldInline === "function" && !options.shouldInline(id)) {
1727
+ return;
1728
+ }
1729
+ }
1730
+ const relativeId = relativeToSrcDir(id);
1731
+ const idMap = cssMap[relativeId] ||= { files: [] };
1732
+ const emittedIds = /* @__PURE__ */ new Set();
1733
+ let styleCtr = 0;
1734
+ const ids = clientCSSMap[id] || [];
1735
+ for (const file of ids) {
1584
1736
  const resolved = await this.resolve(file) ?? await this.resolve(file, id);
1585
1737
  const res = await this.resolve(file + "?inline&used") ?? await this.resolve(file + "?inline&used", id);
1586
1738
  if (!resolved || !res) {
@@ -1588,95 +1740,192 @@ function SSRStylesPlugin(options) {
1588
1740
  warnCache.add(file);
1589
1741
  this.warn(`[nuxt] Cannot extract styles for \`${file}\`. Its styles will not be inlined when server-rendering.`);
1590
1742
  }
1591
- s.prepend(`${genImport(file)}
1592
- `);
1593
1743
  continue;
1594
1744
  }
1595
- idClientCSSMap.add(resolved.id);
1745
+ if (emittedIds.has(file)) {
1746
+ continue;
1747
+ }
1748
+ const ref = this.emitFile({
1749
+ type: "chunk",
1750
+ name: `${filename(id)}-styles-${++styleCtr}.mjs`,
1751
+ id: file + "?inline&used"
1752
+ });
1753
+ idRefMap[relativeToSrcDir(file)] = ref;
1754
+ idMap.files.push(ref);
1755
+ }
1756
+ if (!SUPPORTED_FILES_RE.test(pathname)) {
1757
+ return;
1758
+ }
1759
+ for (const i of findStaticImports(code)) {
1760
+ const { type } = parseQuery(i.specifier);
1761
+ if (type !== "style" && !i.specifier.endsWith(".css")) {
1762
+ continue;
1763
+ }
1764
+ const resolved = await this.resolve(i.specifier, id);
1765
+ if (!resolved) {
1766
+ continue;
1767
+ }
1768
+ if (!await this.resolve(resolved.id + "?inline&used")) {
1769
+ if (!warnCache.has(resolved.id)) {
1770
+ warnCache.add(resolved.id);
1771
+ this.warn(`[nuxt] Cannot extract styles for \`${i.specifier}\`. Its styles will not be inlined when server-rendering.`);
1772
+ }
1773
+ continue;
1774
+ }
1775
+ if (emittedIds.has(resolved.id)) {
1776
+ continue;
1777
+ }
1778
+ const ref = this.emitFile({
1779
+ type: "chunk",
1780
+ name: `${filename(id)}-styles-${++styleCtr}.mjs`,
1781
+ id: resolved.id + "?inline&used"
1782
+ });
1783
+ idRefMap[relativeToSrcDir(resolved.id)] = ref;
1784
+ idMap.files.push(ref);
1596
1785
  }
1597
- if (s.hasChanged()) {
1598
- return {
1599
- code: s.toString(),
1600
- map: s.generateMap({ hires: true })
1601
- };
1786
+ }
1787
+ };
1788
+ }
1789
+ };
1790
+ }
1791
+ function filename(name) {
1792
+ return filename$1(name.replace(/\?.+$/, ""));
1793
+ }
1794
+
1795
+ function ReplacePlugin() {
1796
+ return {
1797
+ name: "nuxt:replace",
1798
+ enforce: "post",
1799
+ async applyToEnvironment(environment) {
1800
+ const config = environment.getTopLevelConfig();
1801
+ const replaceOptions = /* @__PURE__ */ Object.create(null);
1802
+ for (const define of [config.define || {}, environment.config.define || {}]) {
1803
+ for (const key in define) {
1804
+ if (key.startsWith("import.meta.")) {
1805
+ replaceOptions[key] = define[key];
1602
1806
  }
1603
1807
  }
1604
- return;
1605
1808
  }
1606
- const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
1607
- if (!(id in options.clientCSSMap) && !islands.some((c) => c.filePath === pathname)) {
1608
- return;
1609
- }
1610
- const query = parseQuery(search);
1611
- if (query.macro || query.nuxt_component) {
1612
- return;
1809
+ if (vite.rolldownVersion) {
1810
+ const { replacePlugin: replacePlugin2 } = await import('rolldown/experimental');
1811
+ return replacePlugin2(replaceOptions);
1812
+ } else {
1813
+ return replacePlugin({ ...replaceOptions, preventAssignment: true });
1613
1814
  }
1614
- if (!islands.some((c) => c.filePath === pathname)) {
1615
- if (options.shouldInline === false || typeof options.shouldInline === "function" && !options.shouldInline(id)) {
1815
+ }
1816
+ };
1817
+ }
1818
+
1819
+ function LayerDepOptimizePlugin(nuxt) {
1820
+ if (!nuxt.options.dev) {
1821
+ return;
1822
+ }
1823
+ const layerDirs = [];
1824
+ const delimitedRootDir = nuxt.options.rootDir + "/";
1825
+ for (const dirs of getLayerDirectories(nuxt)) {
1826
+ if (dirs.app !== nuxt.options.srcDir && !dirs.app.startsWith(delimitedRootDir)) {
1827
+ layerDirs.push(dirs.app);
1828
+ }
1829
+ }
1830
+ if (layerDirs.length > 0) {
1831
+ layerDirs.sort().reverse();
1832
+ const dirs = [...layerDirs];
1833
+ return {
1834
+ name: "nuxt:optimize-layer-deps",
1835
+ enforce: "pre",
1836
+ async resolveId(source, _importer) {
1837
+ if (!_importer || !dirs.length) {
1616
1838
  return;
1617
1839
  }
1618
- }
1619
- const relativeId = relativeToSrcDir(id);
1620
- const idMap = cssMap[relativeId] ||= { files: [] };
1621
- const emittedIds = /* @__PURE__ */ new Set();
1622
- let styleCtr = 0;
1623
- const ids = options.clientCSSMap[id] || [];
1624
- for (const file of ids) {
1625
- const resolved = await this.resolve(file) ?? await this.resolve(file, id);
1626
- const res = await this.resolve(file + "?inline&used") ?? await this.resolve(file + "?inline&used", id);
1627
- if (!resolved || !res) {
1628
- if (!warnCache.has(file)) {
1629
- warnCache.add(file);
1630
- this.warn(`[nuxt] Cannot extract styles for \`${file}\`. Its styles will not be inlined when server-rendering.`);
1631
- }
1632
- continue;
1840
+ const importer = normalize(_importer);
1841
+ const layerIndex = dirs.findIndex((dir) => importer.startsWith(dir));
1842
+ if (layerIndex !== -1) {
1843
+ dirs.splice(layerIndex, 1);
1844
+ await this.resolve(source, join(nuxt.options.srcDir, "index.html"), { skipSelf: true }).catch(() => null);
1633
1845
  }
1634
- if (emittedIds.has(file)) {
1635
- continue;
1636
- }
1637
- const ref = this.emitFile({
1638
- type: "chunk",
1639
- name: `${filename(id)}-styles-${++styleCtr}.mjs`,
1640
- id: file + "?inline&used"
1641
- });
1642
- idRefMap[relativeToSrcDir(file)] = ref;
1643
- idMap.files.push(ref);
1644
1846
  }
1645
- if (!SUPPORTED_FILES_RE.test(pathname)) {
1646
- return;
1847
+ };
1848
+ }
1849
+ }
1850
+
1851
+ function EnvironmentsPlugin(nuxt) {
1852
+ const fileNames = withoutLeadingSlash(join(nuxt.options.app.buildAssetsDir, "[hash].js"));
1853
+ const clientOutputDir = join(useNitro().options.output.publicDir, nuxt.options.app.buildAssetsDir);
1854
+ const clientAliases = {
1855
+ "nitro/runtime": join(nuxt.options.buildDir, "nitro.client.mjs"),
1856
+ // TODO: remove in v5
1857
+ "#internal/nitro": join(nuxt.options.buildDir, "nitro.client.mjs"),
1858
+ "nitropack/runtime": join(nuxt.options.buildDir, "nitro.client.mjs"),
1859
+ // work around vite optimizer bug
1860
+ "#app-manifest": resolveModulePath("mocked-exports/empty", { from: import.meta.url })
1861
+ };
1862
+ return {
1863
+ name: "nuxt:environments",
1864
+ config() {
1865
+ if (!nuxt.options.dev) {
1866
+ return {
1867
+ base: "./"
1868
+ };
1647
1869
  }
1648
- for (const i of findStaticImports(code)) {
1649
- const { type } = parseQuery(i.specifier);
1650
- if (type !== "style" && !i.specifier.endsWith(".css")) {
1651
- continue;
1652
- }
1653
- const resolved = await this.resolve(i.specifier, id);
1654
- if (!resolved) {
1655
- continue;
1656
- }
1657
- if (!await this.resolve(resolved.id + "?inline&used")) {
1658
- if (!warnCache.has(resolved.id)) {
1659
- warnCache.add(resolved.id);
1660
- this.warn(`[nuxt] Cannot extract styles for \`${i.specifier}\`. Its styles will not be inlined when server-rendering.`);
1870
+ },
1871
+ configEnvironment(name, config) {
1872
+ if (name === "client") {
1873
+ const outputConfig = config.build?.rollupOptions?.output;
1874
+ return {
1875
+ build: {
1876
+ rollupOptions: {
1877
+ output: {
1878
+ chunkFileNames: outputConfig?.chunkFileNames ?? (nuxt.options.dev ? void 0 : fileNames),
1879
+ entryFileNames: outputConfig?.entryFileNames ?? (nuxt.options.dev ? "entry.js" : fileNames),
1880
+ sourcemapPathTransform: outputConfig?.sourcemapPathTransform ?? ((relativeSourcePath, sourcemapPath) => {
1881
+ if (!isAbsolute(relativeSourcePath)) {
1882
+ const absoluteSourcePath = resolve(dirname(sourcemapPath), relativeSourcePath);
1883
+ return relative(clientOutputDir, absoluteSourcePath);
1884
+ }
1885
+ return relativeSourcePath;
1886
+ })
1887
+ }
1888
+ }
1889
+ }
1890
+ };
1891
+ }
1892
+ if (name === "ssr") {
1893
+ if (config.build?.rollupOptions?.output && !Array.isArray(config.build.rollupOptions.output)) {
1894
+ config.build.rollupOptions.output.manualChunks = void 0;
1895
+ if (vite.rolldownVersion) {
1896
+ config.build.rollupOptions.output.advancedChunks = void 0;
1661
1897
  }
1662
- continue;
1663
- }
1664
- if (emittedIds.has(resolved.id)) {
1665
- continue;
1666
1898
  }
1667
- const ref = this.emitFile({
1668
- type: "chunk",
1669
- name: `${filename(id)}-styles-${++styleCtr}.mjs`,
1670
- id: resolved.id + "?inline&used"
1671
- });
1672
- idRefMap[relativeToSrcDir(resolved.id)] = ref;
1673
- idMap.files.push(ref);
1674
1899
  }
1900
+ },
1901
+ applyToEnvironment(environment) {
1902
+ if (environment.name === "client") {
1903
+ return [
1904
+ ...nuxt.options.experimental.clientNodeCompat ? [NodeCompatAliasPlugin()] : [],
1905
+ {
1906
+ name: "nuxt:client:aliases",
1907
+ enforce: "post",
1908
+ resolveId: (source) => clientAliases[source]
1909
+ }
1910
+ ];
1911
+ } else if (environment.name === "ssr") ;
1912
+ return false;
1675
1913
  }
1676
1914
  };
1677
1915
  }
1678
- function filename(name) {
1679
- return filename$1(name.replace(/\?.+$/, ""));
1916
+ function NodeCompatAliasPlugin() {
1917
+ const nodeCompatAlias = defineEnv({ nodeCompat: true, resolve: true }).env.alias;
1918
+ return {
1919
+ name: "nuxt:client:node-compat-aliases",
1920
+ resolveId: {
1921
+ order: "pre",
1922
+ handler(source) {
1923
+ if (source in nodeCompatAlias) {
1924
+ return nodeCompatAlias[source];
1925
+ }
1926
+ }
1927
+ }
1928
+ };
1680
1929
  }
1681
1930
 
1682
1931
  const bundle = async (nuxt) => {
@@ -1779,7 +2028,11 @@ const bundle = async (nuxt) => {
1779
2028
  PublicDirsPlugin({
1780
2029
  dev: nuxt.options.dev,
1781
2030
  baseURL: nuxt.options.app.baseURL
1782
- })
2031
+ }),
2032
+ ReplacePlugin(),
2033
+ LayerDepOptimizePlugin(nuxt),
2034
+ SSRStylesPlugin(nuxt),
2035
+ EnvironmentsPlugin(nuxt)
1783
2036
  ],
1784
2037
  server: {
1785
2038
  watch: { ...nuxt.options.watchers.chokidar, ignored: [isIgnored, /[\\/]node_modules[\\/]/] },
@@ -1795,105 +2048,8 @@ const bundle = async (nuxt) => {
1795
2048
  ctx.config.server.watch = void 0;
1796
2049
  ctx.config.build.watch = void 0;
1797
2050
  }
1798
- if (nuxt.options.dev) {
1799
- const layerDirs = [];
1800
- const delimitedRootDir = nuxt.options.rootDir + "/";
1801
- for (const dirs of getLayerDirectories(nuxt)) {
1802
- if (dirs.app !== nuxt.options.srcDir && !dirs.app.startsWith(delimitedRootDir)) {
1803
- layerDirs.push(dirs.app);
1804
- }
1805
- }
1806
- if (layerDirs.length > 0) {
1807
- layerDirs.sort().reverse();
1808
- nuxt.hook("vite:extendConfig", (config) => {
1809
- const dirs = [...layerDirs];
1810
- config.plugins.push({
1811
- name: "nuxt:optimize-layer-deps",
1812
- enforce: "pre",
1813
- async resolveId(source, _importer) {
1814
- if (!_importer || !dirs.length) {
1815
- return;
1816
- }
1817
- const importer = normalize(_importer);
1818
- const layerIndex = dirs.findIndex((dir) => importer.startsWith(dir));
1819
- if (layerIndex !== -1) {
1820
- dirs.splice(layerIndex, 1);
1821
- await this.resolve(source, join(nuxt.options.srcDir, "index.html"), { skipSelf: true }).catch(() => null);
1822
- }
1823
- }
1824
- });
1825
- });
1826
- }
1827
- }
1828
- if (!nuxt.options.test && (nuxt.options.typescript.typeCheck === true || nuxt.options.typescript.typeCheck === "build" && !nuxt.options.dev)) {
1829
- const tsconfigPath = await resolveTSConfig(nuxt.options.rootDir);
1830
- const supportsProjects = await readTSConfig(tsconfigPath).then((r) => !!r.references?.length);
1831
- const checker = await import('vite-plugin-checker').then((r) => r.default);
1832
- addVitePlugin(checker({
1833
- vueTsc: {
1834
- tsconfigPath,
1835
- buildMode: supportsProjects
1836
- }
1837
- }), { server: nuxt.options.ssr });
1838
- }
1839
2051
  await nuxt.callHook("vite:extend", ctx);
1840
- nuxt.hook("vite:extendConfig", async (config) => {
1841
- const replaceOptions = /* @__PURE__ */ Object.create(null);
1842
- for (const key in config.define) {
1843
- if (key.startsWith("import.meta.")) {
1844
- replaceOptions[key] = config.define[key];
1845
- }
1846
- }
1847
- if (vite.rolldownVersion) {
1848
- const { replacePlugin: replacePlugin2 } = await import('rolldown/experimental');
1849
- config.plugins.push(replacePlugin2(replaceOptions));
1850
- } else {
1851
- config.plugins.push(replacePlugin({ ...replaceOptions, preventAssignment: true }));
1852
- }
1853
- });
1854
- if (!nuxt.options.dev) {
1855
- const chunksWithInlinedCSS = /* @__PURE__ */ new Set();
1856
- const clientCSSMap = {};
1857
- nuxt.hook("vite:extendConfig", (config, { isServer }) => {
1858
- config.plugins.unshift(SSRStylesPlugin({
1859
- srcDir: nuxt.options.srcDir,
1860
- clientCSSMap,
1861
- chunksWithInlinedCSS,
1862
- shouldInline: nuxt.options.features.inlineStyles,
1863
- components: nuxt.apps.default.components || [],
1864
- globalCSS: nuxt.options.css,
1865
- mode: isServer ? "server" : "client",
1866
- entry: ctx.entry
1867
- }));
1868
- });
1869
- const nitro = useNitro();
1870
- nuxt.hook("build:manifest", (manifest) => {
1871
- const entryIds = /* @__PURE__ */ new Set();
1872
- for (const id of chunksWithInlinedCSS) {
1873
- const chunk = manifest[id];
1874
- if (!chunk) {
1875
- continue;
1876
- }
1877
- if (chunk.isEntry && chunk.src) {
1878
- entryIds.add(chunk.src);
1879
- } else {
1880
- chunk.css &&= [];
1881
- }
1882
- }
1883
- nitro.options.virtual["#internal/nuxt/entry-ids.mjs"] = () => `export default ${JSON.stringify(Array.from(entryIds))}`;
1884
- nitro.options._config.virtual ||= {};
1885
- nitro.options._config.virtual["#internal/nuxt/entry-ids.mjs"] = nitro.options.virtual["#internal/nuxt/entry-ids.mjs"];
1886
- });
1887
- }
1888
2052
  nuxt.hook("vite:serverCreated", (server, env) => {
1889
- nuxt.hook("app:templatesGenerated", async (_app, changedTemplates) => {
1890
- await Promise.all(changedTemplates.map(async (template) => {
1891
- for (const mod of server.moduleGraph.getModulesByFile(`virtual:nuxt:${encodeURIComponent(template.dst)}`) || []) {
1892
- server.moduleGraph.invalidateModule(mod);
1893
- await server.reloadModule(mod);
1894
- }
1895
- }));
1896
- });
1897
2053
  if (nuxt.options.vite.warmupEntry !== false) {
1898
2054
  useNitro().hooks.hookOnce("compiled", () => {
1899
2055
  const start = Date.now();
@@ -1,10 +1,10 @@
1
1
  /** @typedef {import('node:net').Socket} Socket */
2
- /** @typedef {import('../vite-node').ViteNodeFetch} ViteNodeFetch */
3
- /** @type {import('../vite-node').ViteNodeServerOptions} */
4
- export const viteNodeOptions: import("../vite-node").ViteNodeServerOptions;
2
+ /** @typedef {import('../plugins/vite-node').ViteNodeFetch} ViteNodeFetch */
3
+ /** @type {import('../plugins/vite-node').ViteNodeServerOptions} */
4
+ export const viteNodeOptions: import("../plugins/vite-node").ViteNodeServerOptions;
5
5
  /**
6
6
  * @type {ViteNodeFetch}
7
7
  */
8
8
  export const viteNodeFetch: ViteNodeFetch;
9
9
  export type Socket = import("node:net").Socket;
10
- export type ViteNodeFetch = import("../vite-node").ViteNodeFetch;
10
+ export type ViteNodeFetch = import("../plugins/vite-node").ViteNodeFetch;
@@ -4,9 +4,9 @@ import { Buffer } from 'node:buffer'
4
4
  import { isTest } from 'std-env'
5
5
 
6
6
  /** @typedef {import('node:net').Socket} Socket */
7
- /** @typedef {import('../vite-node').ViteNodeFetch} ViteNodeFetch */
7
+ /** @typedef {import('../plugins/vite-node').ViteNodeFetch} ViteNodeFetch */
8
8
 
9
- /** @type {import('../vite-node').ViteNodeServerOptions} */
9
+ /** @type {import('../plugins/vite-node').ViteNodeServerOptions} */
10
10
  export const viteNodeOptions = JSON.parse(process.env.NUXT_VITE_NODE_OPTIONS || '{}')
11
11
 
12
12
  /** @type {Map<number, { resolve: (value: any) => void, reject: (reason?: any) => void }>} */
@@ -218,10 +218,10 @@ function connectSocket () {
218
218
 
219
219
  /**
220
220
  * Sends a request over the IPC socket with automatic reconnection.
221
- * @template {keyof import('../vite-node').ViteNodeRequestMap} T
221
+ * @template {keyof import('../plugins/vite-node').ViteNodeRequestMap} T
222
222
  * @param {T} type - The type of the request.
223
- * @param {import('../vite-node').ViteNodeRequestMap[T]['request']} [payload] - The payload for the request.
224
- * @returns {Promise<import('../vite-node').ViteNodeRequestMap[T]['response']>} A promise that resolves with the response data.
223
+ * @param {import('../plugins/vite-node').ViteNodeRequestMap[T]['request']} [payload] - The payload for the request.
224
+ * @returns {Promise<import('../plugins/vite-node').ViteNodeRequestMap[T]['response']>} A promise that resolves with the response data.
225
225
  */
226
226
  async function sendRequest (type, payload) {
227
227
  const requestId = requestIdCounter++
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/vite-builder-nightly",
3
- "version": "4.2.0-29334960.22f4693a",
3
+ "version": "4.2.0-29335187.d989fb8b",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/nuxt.git",
@@ -21,15 +21,15 @@
21
21
  "dist"
22
22
  ],
23
23
  "devDependencies": {
24
- "@nuxt/schema": "npm:@nuxt/schema-nightly@4.2.0-29334960.22f4693a",
25
- "nitropack": "2.12.6",
24
+ "@nuxt/schema": "npm:@nuxt/schema-nightly@4.2.0-29335187.d989fb8b",
25
+ "nitropack": "2.12.7",
26
26
  "rolldown": "1.0.0-beta.42",
27
27
  "rollup": "4.52.4",
28
28
  "unbuild": "3.6.1",
29
29
  "vue": "3.5.22"
30
30
  },
31
31
  "dependencies": {
32
- "@nuxt/kit": "npm:@nuxt/kit-nightly@4.2.0-29334960.22f4693a",
32
+ "@nuxt/kit": "npm:@nuxt/kit-nightly@4.2.0-29335187.d989fb8b",
33
33
  "@rollup/plugin-replace": "^6.0.2",
34
34
  "@vitejs/plugin-vue": "^6.0.1",
35
35
  "@vitejs/plugin-vue-jsx": "^5.1.1",
@@ -61,7 +61,7 @@
61
61
  "vue-bundle-renderer": "^2.2.0"
62
62
  },
63
63
  "peerDependencies": {
64
- "nuxt": "npm:nuxt-nightly@4.2.0-29334960.22f4693a",
64
+ "nuxt": "npm:nuxt-nightly@4.2.0-29335187.d989fb8b",
65
65
  "rolldown": "^1.0.0-beta.38",
66
66
  "vue": "^3.3.4"
67
67
  },
@@ -1,39 +0,0 @@
1
- import { transform } from 'esbuild';
2
- import { visualizer } from 'rollup-plugin-visualizer';
3
- import defu from 'defu';
4
-
5
- function AnalyzePlugin(nuxt) {
6
- const analyzeOptions = defu({}, nuxt.options.build.analyze);
7
- if (!analyzeOptions.enabled) {
8
- return [];
9
- }
10
- return [
11
- {
12
- name: "nuxt:analyze-minify",
13
- async generateBundle(_opts, outputBundle) {
14
- for (const _bundleId in outputBundle) {
15
- const bundle = outputBundle[_bundleId];
16
- if (!bundle || bundle.type !== "chunk") {
17
- continue;
18
- }
19
- const minifiedModuleEntryPromises = [];
20
- for (const [moduleId, module] of Object.entries(bundle.modules)) {
21
- minifiedModuleEntryPromises.push(
22
- transform(module.code || "", { minify: true }).then((result) => [moduleId, { ...module, code: result.code }])
23
- );
24
- }
25
- bundle.modules = Object.fromEntries(await Promise.all(minifiedModuleEntryPromises));
26
- }
27
- }
28
- },
29
- visualizer({
30
- ...analyzeOptions,
31
- filename: "filename" in analyzeOptions ? analyzeOptions.filename.replace("{name}", "client") : void 0,
32
- title: "Client bundle stats",
33
- gzipSize: true,
34
- brotliSize: true
35
- })
36
- ];
37
- }
38
-
39
- export { AnalyzePlugin };