@sebbro/paraglide-lite 0.1.0 → 0.1.2
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/bundler-plugins/per-locale-build/index.js +5 -3
- package/dist/bundler-plugins/per-locale-build/index.js.map +1 -1
- package/dist/bundler-plugins/per-locale-build/vite-environments.js +12 -7
- package/dist/bundler-plugins/per-locale-build/vite-environments.js.map +1 -1
- package/dist/bundler-plugins/plugin-core.d.ts +38 -2
- package/dist/bundler-plugins/plugin-core.js +198 -11
- package/dist/bundler-plugins/plugin-core.js.map +1 -1
- package/dist/bundler-plugins/rolldown.test.js +15 -6
- package/dist/bundler-plugins/rolldown.test.js.map +1 -1
- package/dist/bundler-plugins/unplugin.js +5 -0
- package/dist/bundler-plugins/unplugin.js.map +1 -1
- package/dist/bundler-plugins/unplugin.test.js +67 -0
- package/dist/bundler-plugins/unplugin.test.js.map +1 -1
- package/dist/bundler-plugins/virtual-modules.test.js +64 -1
- package/dist/bundler-plugins/virtual-modules.test.js.map +1 -1
- package/dist/cli/commands/compile/command.js +8 -1
- package/dist/cli/commands/compile/command.js.map +1 -1
- package/dist/cli/commands/compile/command.test.js +51 -0
- package/dist/cli/commands/compile/command.test.js.map +1 -1
- package/dist/compiler/compile-annotation.d.ts +2 -2
- package/dist/compiler/compile-annotation.js +9 -9
- package/dist/compiler/compile-annotation.js.map +1 -1
- package/dist/compiler/compile-local-variable.d.ts +2 -1
- package/dist/compiler/compile-local-variable.js +4 -4
- package/dist/compiler/compile-local-variable.js.map +1 -1
- package/dist/compiler/compile-local-variable.test.js +82 -0
- package/dist/compiler/compile-local-variable.test.js.map +1 -1
- package/dist/compiler/compile-message.js +10 -2
- package/dist/compiler/compile-message.js.map +1 -1
- package/dist/compiler/compile-message.test.js +132 -2
- package/dist/compiler/compile-message.test.js.map +1 -1
- package/dist/compiler/compile-pattern.js +4 -2
- package/dist/compiler/compile-pattern.js.map +1 -1
- package/dist/compiler/compile-pattern.test.js +31 -0
- package/dist/compiler/compile-pattern.test.js.map +1 -1
- package/dist/compiler/compile.bench.js +1 -1
- package/dist/compiler/compile.bench.js.map +1 -1
- package/dist/compiler/compile.test.js +14 -0
- package/dist/compiler/compile.test.js.map +1 -1
- package/dist/compiler/compiler-options.d.ts +9 -1
- package/dist/compiler/compiler-options.js.map +1 -1
- package/dist/compiler/emit-message-dts.d.ts +18 -0
- package/dist/compiler/emit-message-dts.js +166 -0
- package/dist/compiler/emit-message-dts.js.map +1 -0
- package/dist/compiler/emit-message-dts.test.d.ts +1 -0
- package/dist/compiler/emit-message-dts.test.js +283 -0
- package/dist/compiler/emit-message-dts.test.js.map +1 -0
- package/dist/compiler/runtime/create-runtime.d.ts +1 -0
- package/dist/compiler/runtime/create-runtime.js +11 -0
- package/dist/compiler/runtime/create-runtime.js.map +1 -1
- package/dist/compiler/runtime/exec-url-pattern.d.ts +9 -0
- package/dist/compiler/runtime/exec-url-pattern.js +31 -0
- package/dist/compiler/runtime/exec-url-pattern.js.map +1 -0
- package/dist/compiler/runtime/extract-locale-from-url.js +9 -4
- package/dist/compiler/runtime/extract-locale-from-url.js.map +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.js +13 -6
- package/dist/compiler/runtime/generate-static-localized-urls.js.map +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.test.js +38 -0
- package/dist/compiler/runtime/generate-static-localized-urls.test.js.map +1 -1
- package/dist/compiler/runtime/host-routing.d.ts +3 -3
- package/dist/compiler/runtime/host-routing.js +2 -2
- package/dist/compiler/runtime/host-routing.js.map +1 -1
- package/dist/compiler/runtime/host-routing.test.js +79 -0
- package/dist/compiler/runtime/host-routing.test.js.map +1 -1
- package/dist/compiler/runtime/localize-href.bench.d.ts +1 -0
- package/dist/compiler/runtime/localize-href.bench.js +68 -0
- package/dist/compiler/runtime/localize-href.bench.js.map +1 -0
- package/dist/compiler/runtime/localize-href.test.js +35 -0
- package/dist/compiler/runtime/localize-href.test.js.map +1 -1
- package/dist/compiler/runtime/localize-url.d.ts +14 -0
- package/dist/compiler/runtime/localize-url.js +338 -19
- package/dist/compiler/runtime/localize-url.js.map +1 -1
- package/dist/compiler/runtime/localize-url.test.js +139 -0
- package/dist/compiler/runtime/localize-url.test.js.map +1 -1
- package/dist/compiler/runtime/normalize-trailing-slash.d.ts +10 -0
- package/dist/compiler/runtime/normalize-trailing-slash.js +23 -0
- package/dist/compiler/runtime/normalize-trailing-slash.js.map +1 -0
- package/dist/compiler/runtime/route-strategy.js +4 -2
- package/dist/compiler/runtime/route-strategy.js.map +1 -1
- package/dist/compiler/runtime/should-redirect.js +4 -1
- package/dist/compiler/runtime/should-redirect.js.map +1 -1
- package/dist/compiler/runtime/should-redirect.test.js +26 -2
- package/dist/compiler/runtime/should-redirect.test.js.map +1 -1
- package/dist/compiler/runtime/type.d.ts +1 -0
- package/dist/compiler/runtime/type.js.map +1 -1
- package/dist/compiler/runtime/url-pattern.d.ts +11 -0
- package/dist/compiler/runtime/url-pattern.js +39 -1
- package/dist/compiler/runtime/url-pattern.js.map +1 -1
- package/dist/compiler/runtime/variables.d.ts +9 -3
- package/dist/compiler/runtime/variables.js +7 -1
- package/dist/compiler/runtime/variables.js.map +1 -1
- package/dist/compiler/server/create-server-file.js +18 -4
- package/dist/compiler/server/create-server-file.js.map +1 -1
- package/dist/compiler/server/create-server-file.test.js +76 -0
- package/dist/compiler/server/create-server-file.test.js.map +1 -1
- package/dist/compiler/server/middleware.js +6 -2
- package/dist/compiler/server/middleware.js.map +1 -1
- package/dist/compiler/server/middleware.test.js +30 -0
- package/dist/compiler/server/middleware.test.js.map +1 -1
- package/dist/compiler/strip-jsdoc.d.ts +9 -0
- package/dist/compiler/strip-jsdoc.js +19 -0
- package/dist/compiler/strip-jsdoc.js.map +1 -0
- package/dist/compiler/strip-jsdoc.test.d.ts +1 -0
- package/dist/compiler/strip-jsdoc.test.js +95 -0
- package/dist/compiler/strip-jsdoc.test.js.map +1 -0
- package/dist/compiler/variable-access.d.ts +2 -0
- package/dist/compiler/variable-access.js +6 -0
- package/dist/compiler/variable-access.js.map +1 -1
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +9 -0
- package/dist/index.test.js.map +1 -0
- package/dist/messages/load-messages.js +4 -5
- package/dist/messages/load-messages.js.map +1 -1
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/env-variables/index.js.map +1 -1
- package/dist/services/file-handling/write-output.bench.d.ts +1 -0
- package/dist/services/file-handling/write-output.bench.js +24 -0
- package/dist/services/file-handling/write-output.bench.js.map +1 -0
- package/dist/services/file-handling/write-output.d.ts +5 -0
- package/dist/services/file-handling/write-output.js +54 -9
- package/dist/services/file-handling/write-output.js.map +1 -1
- package/dist/services/file-handling/write-output.test.js +27 -0
- package/dist/services/file-handling/write-output.test.js.map +1 -1
- package/dist/services/logger/index.js +2 -0
- package/dist/services/logger/index.js.map +1 -1
- package/package.json +86 -86
|
@@ -17,9 +17,11 @@ function createPerLocaleCompilerOptions(compilerOptions) {
|
|
|
17
17
|
emitFiles: true,
|
|
18
18
|
outputStructure: compilerOptions.outputStructure ?? "locale-modules",
|
|
19
19
|
experimentalStaticLocale: perLocaleBuildStaticLocaleExpression,
|
|
20
|
-
additionalFiles
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
// Only forward additionalFiles when explicitly supplied — an empty
|
|
21
|
+
// object would override files provided elsewhere.
|
|
22
|
+
...(compilerOptions.additionalFiles !== undefined
|
|
23
|
+
? { additionalFiles: { ...compilerOptions.additionalFiles } }
|
|
24
|
+
: {}),
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
27
|
function validateCompilerOptions(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bundler-plugins/per-locale-build/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oCAAoC,EAAE,MAAM,oCAAoC,CAAC;AAE1F,OAAO,EAAE,iCAAiC,EAAE,MAAM,wBAAwB,CAAC;AAE3E,MAAM,UAAU,2BAA2B,CAAC,IAG3C;IACA,uBAAuB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,8BAA8B,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7E,OAAO;QACN,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC;QAC1C,iCAAiC,CAAC;YACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;SAC9D,CAAC;KACF,CAAC;AACH,CAAC;AAED,SAAS,8BAA8B,CACtC,eAAgC;IAEhC,OAAO;QACN,GAAG,eAAe;QAClB,8DAA8D;QAC9D,SAAS,EAAE,IAAI;QACf,eAAe,EAAE,eAAe,CAAC,eAAe,IAAI,gBAAgB;QACpE,wBAAwB,EAAE,oCAAoC;QAC9D,eAAe,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bundler-plugins/per-locale-build/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oCAAoC,EAAE,MAAM,oCAAoC,CAAC;AAE1F,OAAO,EAAE,iCAAiC,EAAE,MAAM,wBAAwB,CAAC;AAE3E,MAAM,UAAU,2BAA2B,CAAC,IAG3C;IACA,uBAAuB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,8BAA8B,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7E,OAAO;QACN,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC;QAC1C,iCAAiC,CAAC;YACjC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;SAC9D,CAAC;KACF,CAAC;AACH,CAAC;AAED,SAAS,8BAA8B,CACtC,eAAgC;IAEhC,OAAO;QACN,GAAG,eAAe;QAClB,8DAA8D;QAC9D,SAAS,EAAE,IAAI;QACf,eAAe,EAAE,eAAe,CAAC,eAAe,IAAI,gBAAgB;QACpE,wBAAwB,EAAE,oCAAoC;QAC9D,mEAAmE;QACnE,kDAAkD;QAClD,GAAG,CAAC,eAAe,CAAC,eAAe,KAAK,SAAS;YAChD,CAAC,CAAC,EAAE,eAAe,EAAE,EAAE,GAAG,eAAe,CAAC,eAAe,EAAE,EAAE;YAC7D,CAAC,CAAC,EAAE,CAAC;KACN,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,OAAwB;IACxD,IAAI,OAAO,CAAC,wBAAwB,KAAK,SAAS,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACd,0IAA0I,CAC1I,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,qCAAqC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CACd,2FAA2F,CAC3F,CAAC;IACH,CAAC;IACD,IACC,OAAO,CAAC,eAAe,KAAK,SAAS;QACrC,OAAO,CAAC,eAAe,KAAK,gBAAgB,EAC3C,CAAC;QACF,MAAM,IAAI,KAAK,CACd,wEAAwE,CACxE,CAAC;IACH,CAAC;AACF,CAAC;AAED,SAAS,YAAY,CACpB,OAAwD;IAExD,OAAO;QACN,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;KAC7B,CAAC;AACH,CAAC","sourcesContent":["import type { Plugin } from \"vite\";\nimport type { CompilerOptions } from \"../../compiler/compiler-options.js\";\nimport { perLocaleBuildStaticLocaleExpression } from \"../../compiler/per-locale-build.js\";\nimport type { PerLocaleBuildSettings } from \"./types.js\";\nimport { createViteLocaleEnvironmentPlugin } from \"./vite-environments.js\";\n\nexport function createPerLocaleBuildPlugins(args: {\n\tcompilerOptions: CompilerOptions;\n\tcreateCompilerPlugin: (options: CompilerOptions) => Plugin;\n}): Plugin[] {\n\tvalidateCompilerOptions(args.compilerOptions);\n\tconst compilerOptions = createPerLocaleCompilerOptions(args.compilerOptions);\n\treturn [\n\t\targs.createCompilerPlugin(compilerOptions),\n\t\tcreateViteLocaleEnvironmentPlugin({\n\t\t\tsettings: () => Promise.resolve(loadSettings(compilerOptions)),\n\t\t}),\n\t];\n}\n\nfunction createPerLocaleCompilerOptions(\n\tcompilerOptions: CompilerOptions\n): CompilerOptions {\n\treturn {\n\t\t...compilerOptions,\n\t\t// Per-locale environments read specialized sources from disk.\n\t\temitFiles: true,\n\t\toutputStructure: compilerOptions.outputStructure ?? \"locale-modules\",\n\t\texperimentalStaticLocale: perLocaleBuildStaticLocaleExpression,\n\t\t// Only forward additionalFiles when explicitly supplied — an empty\n\t\t// object would override files provided elsewhere.\n\t\t...(compilerOptions.additionalFiles !== undefined\n\t\t\t? { additionalFiles: { ...compilerOptions.additionalFiles } }\n\t\t\t: {}),\n\t};\n}\n\nfunction validateCompilerOptions(options: CompilerOptions): void {\n\tif (options.experimentalStaticLocale !== undefined) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild cannot be combined with experimentalStaticLocale because it controls the compiler's static locale expression.\"\n\t\t);\n\t}\n\tif (options.experimentalMiddlewareLocaleSplitting) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild cannot be combined with experimentalMiddlewareLocaleSplitting.\"\n\t\t);\n\t}\n\tif (\n\t\toptions.outputStructure !== undefined &&\n\t\toptions.outputStructure !== \"locale-modules\"\n\t) {\n\t\tthrow new Error(\n\t\t\t'experimentalPerLocaleBuild requires outputStructure: \"locale-modules\".'\n\t\t);\n\t}\n}\n\nfunction loadSettings(\n\toptions: Pick<CompilerOptions, \"baseLocale\" | \"locales\">\n): PerLocaleBuildSettings {\n\treturn {\n\t\tbaseLocale: options.baseLocale,\n\t\tlocales: [...options.locales],\n\t};\n}\n"]}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import nodeFs from "node:fs/promises";
|
|
2
2
|
import nodePath from "node:path";
|
|
3
|
-
import * as vite from "vite";
|
|
4
3
|
import { PER_LOCALE_BUILD_DEFINE } from "./constants.js";
|
|
5
4
|
import { getPerLocaleBuildLocaleId } from "./locale-id.js";
|
|
6
5
|
export const VITE_LOCALE_BUILD_MANIFEST = "paraglide-vite-locales.json";
|
|
7
6
|
export const VITE_LOCALE_ENVIRONMENT_PREFIX = "paraglide_client_";
|
|
8
|
-
const viteVersion = vite.version;
|
|
9
|
-
const detectedRolldownVersion = vite.rolldownVersion;
|
|
10
7
|
export function createViteLocaleBuildPlan(args) {
|
|
11
8
|
const outputDirectory = normalizeOutputDirectory(args.outputDirectory ?? "dist");
|
|
12
9
|
return {
|
|
@@ -42,6 +39,12 @@ export function createViteLocaleEnvironmentPlugin(args) {
|
|
|
42
39
|
async config(config, env) {
|
|
43
40
|
if (env.command !== "build")
|
|
44
41
|
return;
|
|
42
|
+
// Vite is an optional peer dependency. Only resolve it when this
|
|
43
|
+
// experimental Vite-specific build path is actually used so importing
|
|
44
|
+
// the package's compiler API does not require Vite to be installed.
|
|
45
|
+
const vite = await import("vite");
|
|
46
|
+
const viteVersion = vite.version;
|
|
47
|
+
const detectedRolldownVersion = vite.rolldownVersion;
|
|
45
48
|
if (Number.parseInt(viteVersion, 10) < 8) {
|
|
46
49
|
throw new Error(`experimentalPerLocaleBuild Vite environments require Vite 8 or newer; found ${viteVersion}.`);
|
|
47
50
|
}
|
|
@@ -64,6 +67,10 @@ export function createViteLocaleEnvironmentPlugin(args) {
|
|
|
64
67
|
builder,
|
|
65
68
|
plan: plan,
|
|
66
69
|
settings: settings,
|
|
70
|
+
viteVersion,
|
|
71
|
+
rolldownVersion: typeof detectedRolldownVersion === "string"
|
|
72
|
+
? detectedRolldownVersion
|
|
73
|
+
: "unknown",
|
|
67
74
|
});
|
|
68
75
|
};
|
|
69
76
|
return {
|
|
@@ -128,10 +135,8 @@ async function buildViteLocaleEnvironments(args) {
|
|
|
128
135
|
const manifest = {
|
|
129
136
|
version: 1,
|
|
130
137
|
backend: "vite-rolldown-environments",
|
|
131
|
-
viteVersion,
|
|
132
|
-
rolldownVersion:
|
|
133
|
-
? detectedRolldownVersion
|
|
134
|
-
: "unknown",
|
|
138
|
+
viteVersion: args.viteVersion,
|
|
139
|
+
rolldownVersion: args.rolldownVersion,
|
|
135
140
|
baseLocale: args.settings.baseLocale,
|
|
136
141
|
locales: {},
|
|
137
142
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-environments.js","sourceRoot":"","sources":["../../../src/bundler-plugins/per-locale-build/vite-environments.ts"],"names":[],"mappings":"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","sourcesContent":["import nodeFs from \"node:fs/promises\";\nimport nodePath from \"node:path\";\nimport type { EnvironmentOptions, Plugin, UserConfig, ViteBuilder } from \"vite\";\nimport * as vite from \"vite\";\nimport { PER_LOCALE_BUILD_DEFINE } from \"./constants.js\";\nimport { getPerLocaleBuildLocaleId } from \"./locale-id.js\";\nimport type { PerLocaleBuildSettings } from \"./types.js\";\n\nexport const VITE_LOCALE_BUILD_MANIFEST = \"paraglide-vite-locales.json\";\nexport const VITE_LOCALE_ENVIRONMENT_PREFIX = \"paraglide_client_\";\nconst viteVersion = vite.version;\nconst detectedRolldownVersion = (\n\tvite as unknown as { rolldownVersion?: unknown }\n).rolldownVersion;\n\nexport type ViteLocaleBuildPlan = {\n\toutputDirectory: string;\n\tvariants: Array<{\n\t\tlocale: string;\n\t\tenvironmentName: string;\n\t\tdirectory: string;\n\t\toutputDirectory: string;\n\t\tdefine: Record<string, string>;\n\t}>;\n};\n\nexport type ViteLocaleBuildManifest = {\n\tversion: 1;\n\tbackend: \"vite-rolldown-environments\";\n\tviteVersion: string;\n\trolldownVersion: string;\n\tbaseLocale: string;\n\tlocales: Record<\n\t\tstring,\n\t\t{\n\t\t\tenvironment: string;\n\t\t\tdirectory: string;\n\t\t\tentries: Record<string, string>;\n\t\t\tfiles: Array<{\n\t\t\t\tfileName: string;\n\t\t\t\ttype: \"asset\" | \"chunk\";\n\t\t\t\tbytes: number;\n\t\t\t\tentry?: boolean;\n\t\t\t\tdynamicEntry?: boolean;\n\t\t\t\timports?: string[];\n\t\t\t\tdynamicImports?: string[];\n\t\t\t\texternalImports?: string[];\n\t\t\t\texternalDynamicImports?: string[];\n\t\t\t}>;\n\t\t}\n\t>;\n};\n\ntype ViteBuildResult = Awaited<ReturnType<ViteBuilder[\"build\"]>>;\ntype ViteRolldownOutput = Extract<\n\tViteBuildResult extends Array<infer Item> ? Item : ViteBuildResult,\n\t{ output: unknown[] }\n>;\n\nexport function createViteLocaleBuildPlan(args: {\n\tsettings: PerLocaleBuildSettings;\n\toutputDirectory?: string;\n}): ViteLocaleBuildPlan {\n\tconst outputDirectory = normalizeOutputDirectory(\n\t\targs.outputDirectory ?? \"dist\"\n\t);\n\treturn {\n\t\toutputDirectory,\n\t\tvariants: args.settings.locales.map((locale) => {\n\t\t\tconst localeId = getPerLocaleBuildLocaleId(locale);\n\t\t\tconst directory = nodePath.posix.join(\"__paraglide\", localeId);\n\t\t\treturn {\n\t\t\t\tlocale,\n\t\t\t\tenvironmentName: `${VITE_LOCALE_ENVIRONMENT_PREFIX}${localeId.replaceAll(/[^a-zA-Z0-9_$]/g, \"_\")}`,\n\t\t\t\tdirectory,\n\t\t\t\toutputDirectory: nodePath.posix.join(outputDirectory, directory),\n\t\t\t\tdefine: {\n\t\t\t\t\t[PER_LOCALE_BUILD_DEFINE]: JSON.stringify(locale),\n\t\t\t\t},\n\t\t\t};\n\t\t}),\n\t};\n}\n\n/**\n * Build one untouched Rolldown client graph per locale.\n *\n * This plugin owns app-build orchestration. It deliberately rejects another\n * custom buildApp orchestrator rather than guessing how a framework builds.\n */\nexport function createViteLocaleEnvironmentPlugin(args: {\n\tsettings: () => Promise<PerLocaleBuildSettings>;\n\toutputDirectory?: string;\n}): Plugin {\n\tlet plan: ViteLocaleBuildPlan | undefined;\n\tlet settings: PerLocaleBuildSettings | undefined;\n\tlet buildApp:\n\t\t| NonNullable<NonNullable<UserConfig[\"builder\"]>[\"buildApp\"]>\n\t\t| undefined;\n\n\treturn {\n\t\tname: \"paraglide-vite-locale-environments\",\n\t\tenforce: \"post\",\n\t\tasync config(config, env) {\n\t\t\tif (env.command !== \"build\") return;\n\t\t\tif (Number.parseInt(viteVersion, 10) < 8) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`experimentalPerLocaleBuild Vite environments require Vite 8 or newer; found ${viteVersion}.`\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (config.builder?.buildApp !== undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"experimentalPerLocaleBuild Vite environments cannot compose with an existing builder.buildApp orchestrator. A framework must expose a public client-variant API before using this backend.\"\n\t\t\t\t);\n\t\t\t}\n\t\t\tsettings = await args.settings();\n\t\t\tvalidateViteLocaleBuildSettings(settings);\n\t\t\tplan = createViteLocaleBuildPlan({\n\t\t\t\tsettings,\n\t\t\t\toutputDirectory: args.outputDirectory ?? config.build?.outDir,\n\t\t\t});\n\t\t\tfor (const variant of plan.variants) {\n\t\t\t\tif (config.environments?.[variant.environmentName] !== undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`experimentalPerLocaleBuild cannot create Vite environment ${JSON.stringify(variant.environmentName)} because the application already defines it.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuildApp = async (builder) => {\n\t\t\t\tawait buildViteLocaleEnvironments({\n\t\t\t\t\tbuilder,\n\t\t\t\t\tplan: plan!,\n\t\t\t\t\tsettings: settings!,\n\t\t\t\t});\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tbuilder: {\n\t\t\t\t\t...config.builder,\n\t\t\t\t\tbuildApp,\n\t\t\t\t},\n\t\t\t\tenvironments: Object.fromEntries(\n\t\t\t\t\tplan.variants.map((variant) => [\n\t\t\t\t\t\tvariant.environmentName,\n\t\t\t\t\t\tcreateLocaleEnvironment(variant),\n\t\t\t\t\t])\n\t\t\t\t),\n\t\t\t} satisfies UserConfig;\n\t\t},\n\t\tconfigResolved(config) {\n\t\t\tif (config.command !== \"build\") return;\n\t\t\tif (config.builder?.buildApp !== buildApp) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"experimentalPerLocaleBuild Vite environments must own builder.buildApp. Another plugin replaced the locale build orchestrator.\"\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tbuildStart() {\n\t\t\tif (!this.meta.rolldownVersion) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"experimentalPerLocaleBuild Vite environments require a Rolldown-powered Vite build (Vite 8 or newer).\"\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction createLocaleEnvironment(\n\tvariant: ViteLocaleBuildPlan[\"variants\"][number]\n): EnvironmentOptions {\n\treturn {\n\t\tconsumer: \"client\",\n\t\tdefine: variant.define,\n\t\tbuild: {\n\t\t\toutDir: variant.outputDirectory,\n\t\t\temptyOutDir: true,\n\t\t\tmanifest: true,\n\t\t},\n\t};\n}\n\nasync function buildViteLocaleEnvironments(args: {\n\tbuilder: ViteBuilder;\n\tplan: ViteLocaleBuildPlan;\n\tsettings: PerLocaleBuildSettings;\n}): Promise<void> {\n\tconst outputRoot = nodePath.resolve(\n\t\targs.builder.config.root,\n\t\targs.plan.outputDirectory\n\t);\n\tawait Promise.all([\n\t\tnodeFs.rm(nodePath.join(outputRoot, \"__paraglide\"), {\n\t\t\trecursive: true,\n\t\t\tforce: true,\n\t\t}),\n\t\tnodeFs.rm(nodePath.join(outputRoot, VITE_LOCALE_BUILD_MANIFEST), {\n\t\t\tforce: true,\n\t\t}),\n\t]);\n\n\tconst results: Array<{\n\t\tvariant: ViteLocaleBuildPlan[\"variants\"][number];\n\t\toutputs: ViteRolldownOutput[];\n\t}> = [];\n\tfor (const variant of args.plan.variants) {\n\t\tconst environment = args.builder.environments[variant.environmentName];\n\t\tif (!environment) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vite did not create the locale environment ${JSON.stringify(variant.environmentName)}.`\n\t\t\t);\n\t\t}\n\t\tconst result = await args.builder.build(environment);\n\t\tresults.push({\n\t\t\tvariant,\n\t\t\toutputs: getRolldownOutputs(result),\n\t\t});\n\t}\n\n\tconst manifest: ViteLocaleBuildManifest = {\n\t\tversion: 1,\n\t\tbackend: \"vite-rolldown-environments\",\n\t\tviteVersion,\n\t\trolldownVersion:\n\t\t\ttypeof detectedRolldownVersion === \"string\"\n\t\t\t\t? detectedRolldownVersion\n\t\t\t\t: \"unknown\",\n\t\tbaseLocale: args.settings.baseLocale,\n\t\tlocales: {},\n\t};\n\tfor (const { variant, outputs } of results) {\n\t\tmanifest.locales[variant.locale] = createLocaleManifest({\n\t\t\tvariant,\n\t\t\toutputs,\n\t\t});\n\t}\n\n\tawait nodeFs.mkdir(outputRoot, { recursive: true });\n\tawait nodeFs.writeFile(\n\t\tnodePath.join(outputRoot, VITE_LOCALE_BUILD_MANIFEST),\n\t\tJSON.stringify(manifest, undefined, \"\\t\") + \"\\n\"\n\t);\n}\n\nfunction getRolldownOutputs(result: ViteBuildResult): ViteRolldownOutput[] {\n\tif (Array.isArray(result)) {\n\t\treturn result.filter(\n\t\t\t(item): item is ViteRolldownOutput => \"output\" in item\n\t\t);\n\t}\n\tif (\"output\" in result) return [result as ViteRolldownOutput];\n\tthrow new Error(\n\t\t\"experimentalPerLocaleBuild Vite environments do not support watch-mode Rolldown output.\"\n\t);\n}\n\nfunction createLocaleManifest(args: {\n\tvariant: ViteLocaleBuildPlan[\"variants\"][number];\n\toutputs: ViteRolldownOutput[];\n}): ViteLocaleBuildManifest[\"locales\"][string] {\n\tconst outputFiles = args.outputs.flatMap((output) => output.output);\n\tconst emittedFileNames = new Set(\n\t\toutputFiles.map((output) => output.fileName)\n\t);\n\tconst files: ViteLocaleBuildManifest[\"locales\"][string][\"files\"] = outputFiles\n\t\t.map((output) => {\n\t\t\tif (output.type === \"asset\") {\n\t\t\t\treturn {\n\t\t\t\t\tfileName: output.fileName,\n\t\t\t\t\ttype: \"asset\" as const,\n\t\t\t\t\tbytes: getByteLength(output.source),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst staticImports = partitionImports(output.imports, emittedFileNames);\n\t\t\tconst dynamicImports = partitionImports(\n\t\t\t\toutput.dynamicImports,\n\t\t\t\temittedFileNames\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tfileName: output.fileName,\n\t\t\t\ttype: \"chunk\" as const,\n\t\t\t\tbytes: getByteLength(output.code),\n\t\t\t\t...(output.isEntry ? { entry: true } : {}),\n\t\t\t\t...(output.isDynamicEntry ? { dynamicEntry: true } : {}),\n\t\t\t\t...(staticImports.internal.length > 0\n\t\t\t\t\t? { imports: staticImports.internal }\n\t\t\t\t\t: {}),\n\t\t\t\t...(dynamicImports.internal.length > 0\n\t\t\t\t\t? { dynamicImports: dynamicImports.internal }\n\t\t\t\t\t: {}),\n\t\t\t\t...(staticImports.external.length > 0\n\t\t\t\t\t? { externalImports: staticImports.external }\n\t\t\t\t\t: {}),\n\t\t\t\t...(dynamicImports.external.length > 0\n\t\t\t\t\t? {\n\t\t\t\t\t\t\texternalDynamicImports: dynamicImports.external,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t};\n\t\t})\n\t\t.sort((left, right) => left.fileName.localeCompare(right.fileName));\n\tconst fileNames = new Set(files.map((file) => file.fileName));\n\tfor (const file of files) {\n\t\tfor (const imported of [\n\t\t\t...(file.imports ?? []),\n\t\t\t...(file.dynamicImports ?? []),\n\t\t]) {\n\t\t\tif (!fileNames.has(imported)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Vite emitted an open locale graph for ${JSON.stringify(args.variant.locale)}: ${file.fileName} imports missing ${imported}.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\tconst entryPairs: Array<[string, string]> = [];\n\tfor (const output of args.outputs.flatMap((result) => result.output)) {\n\t\tif (output.type === \"chunk\" && output.isEntry) {\n\t\t\tentryPairs.push([output.facadeModuleId ?? output.name, output.fileName]);\n\t\t}\n\t}\n\tconst entries = Object.fromEntries(\n\t\tentryPairs.sort(([left], [right]) => left.localeCompare(right))\n\t);\n\treturn {\n\t\tenvironment: args.variant.environmentName,\n\t\tdirectory: args.variant.directory,\n\t\tentries,\n\t\tfiles,\n\t};\n}\n\nfunction partitionImports(\n\timports: string[],\n\temittedFileNames: ReadonlySet<string>\n): { internal: string[]; external: string[] } {\n\tconst internal: string[] = [];\n\tconst external: string[] = [];\n\tfor (const imported of imports) {\n\t\t(emittedFileNames.has(imported) ? internal : external).push(imported);\n\t}\n\treturn { internal, external };\n}\n\nfunction getByteLength(source: string | Uint8Array): number {\n\treturn typeof source === \"string\"\n\t\t? new TextEncoder().encode(source).byteLength\n\t\t: source.byteLength;\n}\n\nfunction normalizeOutputDirectory(directory: string): string {\n\tconst normalized = directory.replaceAll(\"\\\\\", \"/\").replace(/\\/+$/, \"\");\n\tif (\n\t\tnormalized === \"\" ||\n\t\tnormalized === \".\" ||\n\t\tnormalized.startsWith(\"/\") ||\n\t\tnormalized === \"..\" ||\n\t\tnormalized.startsWith(\"../\")\n\t) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild Vite environment outputDirectory must be a project-relative directory.\"\n\t\t);\n\t}\n\treturn normalized;\n}\n\nfunction validateViteLocaleBuildSettings(\n\tsettings: PerLocaleBuildSettings\n): void {\n\tif (!settings.baseLocale || !settings.locales.includes(settings.baseLocale)) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild Vite environments require baseLocale to be present in locales.\"\n\t\t);\n\t}\n\tif (\n\t\tsettings.locales.length === 0 ||\n\t\tnew Set(settings.locales).size !== settings.locales.length\n\t) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild Vite environments require at least one unique locale.\"\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"vite-environments.js","sourceRoot":"","sources":["../../../src/bundler-plugins/per-locale-build/vite-environments.ts"],"names":[],"mappings":"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","sourcesContent":["import nodeFs from \"node:fs/promises\";\nimport nodePath from \"node:path\";\nimport type { EnvironmentOptions, Plugin, UserConfig, ViteBuilder } from \"vite\";\nimport { PER_LOCALE_BUILD_DEFINE } from \"./constants.js\";\nimport { getPerLocaleBuildLocaleId } from \"./locale-id.js\";\nimport type { PerLocaleBuildSettings } from \"./types.js\";\n\nexport const VITE_LOCALE_BUILD_MANIFEST = \"paraglide-vite-locales.json\";\nexport const VITE_LOCALE_ENVIRONMENT_PREFIX = \"paraglide_client_\";\n\nexport type ViteLocaleBuildPlan = {\n\toutputDirectory: string;\n\tvariants: Array<{\n\t\tlocale: string;\n\t\tenvironmentName: string;\n\t\tdirectory: string;\n\t\toutputDirectory: string;\n\t\tdefine: Record<string, string>;\n\t}>;\n};\n\nexport type ViteLocaleBuildManifest = {\n\tversion: 1;\n\tbackend: \"vite-rolldown-environments\";\n\tviteVersion: string;\n\trolldownVersion: string;\n\tbaseLocale: string;\n\tlocales: Record<\n\t\tstring,\n\t\t{\n\t\t\tenvironment: string;\n\t\t\tdirectory: string;\n\t\t\tentries: Record<string, string>;\n\t\t\tfiles: Array<{\n\t\t\t\tfileName: string;\n\t\t\t\ttype: \"asset\" | \"chunk\";\n\t\t\t\tbytes: number;\n\t\t\t\tentry?: boolean;\n\t\t\t\tdynamicEntry?: boolean;\n\t\t\t\timports?: string[];\n\t\t\t\tdynamicImports?: string[];\n\t\t\t\texternalImports?: string[];\n\t\t\t\texternalDynamicImports?: string[];\n\t\t\t}>;\n\t\t}\n\t>;\n};\n\ntype ViteBuildResult = Awaited<ReturnType<ViteBuilder[\"build\"]>>;\ntype ViteRolldownOutput = Extract<\n\tViteBuildResult extends Array<infer Item> ? Item : ViteBuildResult,\n\t{ output: unknown[] }\n>;\n\nexport function createViteLocaleBuildPlan(args: {\n\tsettings: PerLocaleBuildSettings;\n\toutputDirectory?: string;\n}): ViteLocaleBuildPlan {\n\tconst outputDirectory = normalizeOutputDirectory(\n\t\targs.outputDirectory ?? \"dist\"\n\t);\n\treturn {\n\t\toutputDirectory,\n\t\tvariants: args.settings.locales.map((locale) => {\n\t\t\tconst localeId = getPerLocaleBuildLocaleId(locale);\n\t\t\tconst directory = nodePath.posix.join(\"__paraglide\", localeId);\n\t\t\treturn {\n\t\t\t\tlocale,\n\t\t\t\tenvironmentName: `${VITE_LOCALE_ENVIRONMENT_PREFIX}${localeId.replaceAll(/[^a-zA-Z0-9_$]/g, \"_\")}`,\n\t\t\t\tdirectory,\n\t\t\t\toutputDirectory: nodePath.posix.join(outputDirectory, directory),\n\t\t\t\tdefine: {\n\t\t\t\t\t[PER_LOCALE_BUILD_DEFINE]: JSON.stringify(locale),\n\t\t\t\t},\n\t\t\t};\n\t\t}),\n\t};\n}\n\n/**\n * Build one untouched Rolldown client graph per locale.\n *\n * This plugin owns app-build orchestration. It deliberately rejects another\n * custom buildApp orchestrator rather than guessing how a framework builds.\n */\nexport function createViteLocaleEnvironmentPlugin(args: {\n\tsettings: () => Promise<PerLocaleBuildSettings>;\n\toutputDirectory?: string;\n}): Plugin {\n\tlet plan: ViteLocaleBuildPlan | undefined;\n\tlet settings: PerLocaleBuildSettings | undefined;\n\tlet buildApp:\n\t\t| NonNullable<NonNullable<UserConfig[\"builder\"]>[\"buildApp\"]>\n\t\t| undefined;\n\n\treturn {\n\t\tname: \"paraglide-vite-locale-environments\",\n\t\tenforce: \"post\",\n\t\tasync config(config, env) {\n\t\t\tif (env.command !== \"build\") return;\n\t\t\t// Vite is an optional peer dependency. Only resolve it when this\n\t\t\t// experimental Vite-specific build path is actually used so importing\n\t\t\t// the package's compiler API does not require Vite to be installed.\n\t\t\tconst vite = await import(\"vite\");\n\t\t\tconst viteVersion = vite.version;\n\t\t\tconst detectedRolldownVersion = (\n\t\t\t\tvite as unknown as { rolldownVersion?: unknown }\n\t\t\t).rolldownVersion;\n\t\t\tif (Number.parseInt(viteVersion, 10) < 8) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`experimentalPerLocaleBuild Vite environments require Vite 8 or newer; found ${viteVersion}.`\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (config.builder?.buildApp !== undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"experimentalPerLocaleBuild Vite environments cannot compose with an existing builder.buildApp orchestrator. A framework must expose a public client-variant API before using this backend.\"\n\t\t\t\t);\n\t\t\t}\n\t\t\tsettings = await args.settings();\n\t\t\tvalidateViteLocaleBuildSettings(settings);\n\t\t\tplan = createViteLocaleBuildPlan({\n\t\t\t\tsettings,\n\t\t\t\toutputDirectory: args.outputDirectory ?? config.build?.outDir,\n\t\t\t});\n\t\t\tfor (const variant of plan.variants) {\n\t\t\t\tif (config.environments?.[variant.environmentName] !== undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`experimentalPerLocaleBuild cannot create Vite environment ${JSON.stringify(variant.environmentName)} because the application already defines it.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuildApp = async (builder) => {\n\t\t\t\tawait buildViteLocaleEnvironments({\n\t\t\t\t\tbuilder,\n\t\t\t\t\tplan: plan!,\n\t\t\t\t\tsettings: settings!,\n\t\t\t\t\tviteVersion,\n\t\t\t\t\trolldownVersion:\n\t\t\t\t\t\ttypeof detectedRolldownVersion === \"string\"\n\t\t\t\t\t\t\t? detectedRolldownVersion\n\t\t\t\t\t\t\t: \"unknown\",\n\t\t\t\t});\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tbuilder: {\n\t\t\t\t\t...config.builder,\n\t\t\t\t\tbuildApp,\n\t\t\t\t},\n\t\t\t\tenvironments: Object.fromEntries(\n\t\t\t\t\tplan.variants.map((variant) => [\n\t\t\t\t\t\tvariant.environmentName,\n\t\t\t\t\t\tcreateLocaleEnvironment(variant),\n\t\t\t\t\t])\n\t\t\t\t),\n\t\t\t} satisfies UserConfig;\n\t\t},\n\t\tconfigResolved(config) {\n\t\t\tif (config.command !== \"build\") return;\n\t\t\tif (config.builder?.buildApp !== buildApp) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"experimentalPerLocaleBuild Vite environments must own builder.buildApp. Another plugin replaced the locale build orchestrator.\"\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tbuildStart() {\n\t\t\tif (!this.meta.rolldownVersion) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"experimentalPerLocaleBuild Vite environments require a Rolldown-powered Vite build (Vite 8 or newer).\"\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction createLocaleEnvironment(\n\tvariant: ViteLocaleBuildPlan[\"variants\"][number]\n): EnvironmentOptions {\n\treturn {\n\t\tconsumer: \"client\",\n\t\tdefine: variant.define,\n\t\tbuild: {\n\t\t\toutDir: variant.outputDirectory,\n\t\t\temptyOutDir: true,\n\t\t\tmanifest: true,\n\t\t},\n\t};\n}\n\nasync function buildViteLocaleEnvironments(args: {\n\tbuilder: ViteBuilder;\n\tplan: ViteLocaleBuildPlan;\n\tsettings: PerLocaleBuildSettings;\n\tviteVersion: string;\n\trolldownVersion: string;\n}): Promise<void> {\n\tconst outputRoot = nodePath.resolve(\n\t\targs.builder.config.root,\n\t\targs.plan.outputDirectory\n\t);\n\tawait Promise.all([\n\t\tnodeFs.rm(nodePath.join(outputRoot, \"__paraglide\"), {\n\t\t\trecursive: true,\n\t\t\tforce: true,\n\t\t}),\n\t\tnodeFs.rm(nodePath.join(outputRoot, VITE_LOCALE_BUILD_MANIFEST), {\n\t\t\tforce: true,\n\t\t}),\n\t]);\n\n\tconst results: Array<{\n\t\tvariant: ViteLocaleBuildPlan[\"variants\"][number];\n\t\toutputs: ViteRolldownOutput[];\n\t}> = [];\n\tfor (const variant of args.plan.variants) {\n\t\tconst environment = args.builder.environments[variant.environmentName];\n\t\tif (!environment) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vite did not create the locale environment ${JSON.stringify(variant.environmentName)}.`\n\t\t\t);\n\t\t}\n\t\tconst result = await args.builder.build(environment);\n\t\tresults.push({\n\t\t\tvariant,\n\t\t\toutputs: getRolldownOutputs(result),\n\t\t});\n\t}\n\n\tconst manifest: ViteLocaleBuildManifest = {\n\t\tversion: 1,\n\t\tbackend: \"vite-rolldown-environments\",\n\t\tviteVersion: args.viteVersion,\n\t\trolldownVersion: args.rolldownVersion,\n\t\tbaseLocale: args.settings.baseLocale,\n\t\tlocales: {},\n\t};\n\tfor (const { variant, outputs } of results) {\n\t\tmanifest.locales[variant.locale] = createLocaleManifest({\n\t\t\tvariant,\n\t\t\toutputs,\n\t\t});\n\t}\n\n\tawait nodeFs.mkdir(outputRoot, { recursive: true });\n\tawait nodeFs.writeFile(\n\t\tnodePath.join(outputRoot, VITE_LOCALE_BUILD_MANIFEST),\n\t\tJSON.stringify(manifest, undefined, \"\\t\") + \"\\n\"\n\t);\n}\n\nfunction getRolldownOutputs(result: ViteBuildResult): ViteRolldownOutput[] {\n\tif (Array.isArray(result)) {\n\t\treturn result.filter(\n\t\t\t(item): item is ViteRolldownOutput => \"output\" in item\n\t\t);\n\t}\n\tif (\"output\" in result) return [result as ViteRolldownOutput];\n\tthrow new Error(\n\t\t\"experimentalPerLocaleBuild Vite environments do not support watch-mode Rolldown output.\"\n\t);\n}\n\nfunction createLocaleManifest(args: {\n\tvariant: ViteLocaleBuildPlan[\"variants\"][number];\n\toutputs: ViteRolldownOutput[];\n}): ViteLocaleBuildManifest[\"locales\"][string] {\n\tconst outputFiles = args.outputs.flatMap((output) => output.output);\n\tconst emittedFileNames = new Set(\n\t\toutputFiles.map((output) => output.fileName)\n\t);\n\tconst files: ViteLocaleBuildManifest[\"locales\"][string][\"files\"] = outputFiles\n\t\t.map((output) => {\n\t\t\tif (output.type === \"asset\") {\n\t\t\t\treturn {\n\t\t\t\t\tfileName: output.fileName,\n\t\t\t\t\ttype: \"asset\" as const,\n\t\t\t\t\tbytes: getByteLength(output.source),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst staticImports = partitionImports(output.imports, emittedFileNames);\n\t\t\tconst dynamicImports = partitionImports(\n\t\t\t\toutput.dynamicImports,\n\t\t\t\temittedFileNames\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tfileName: output.fileName,\n\t\t\t\ttype: \"chunk\" as const,\n\t\t\t\tbytes: getByteLength(output.code),\n\t\t\t\t...(output.isEntry ? { entry: true } : {}),\n\t\t\t\t...(output.isDynamicEntry ? { dynamicEntry: true } : {}),\n\t\t\t\t...(staticImports.internal.length > 0\n\t\t\t\t\t? { imports: staticImports.internal }\n\t\t\t\t\t: {}),\n\t\t\t\t...(dynamicImports.internal.length > 0\n\t\t\t\t\t? { dynamicImports: dynamicImports.internal }\n\t\t\t\t\t: {}),\n\t\t\t\t...(staticImports.external.length > 0\n\t\t\t\t\t? { externalImports: staticImports.external }\n\t\t\t\t\t: {}),\n\t\t\t\t...(dynamicImports.external.length > 0\n\t\t\t\t\t? {\n\t\t\t\t\t\t\texternalDynamicImports: dynamicImports.external,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t};\n\t\t})\n\t\t.sort((left, right) => left.fileName.localeCompare(right.fileName));\n\tconst fileNames = new Set(files.map((file) => file.fileName));\n\tfor (const file of files) {\n\t\tfor (const imported of [\n\t\t\t...(file.imports ?? []),\n\t\t\t...(file.dynamicImports ?? []),\n\t\t]) {\n\t\t\tif (!fileNames.has(imported)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Vite emitted an open locale graph for ${JSON.stringify(args.variant.locale)}: ${file.fileName} imports missing ${imported}.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\tconst entryPairs: Array<[string, string]> = [];\n\tfor (const output of args.outputs.flatMap((result) => result.output)) {\n\t\tif (output.type === \"chunk\" && output.isEntry) {\n\t\t\tentryPairs.push([output.facadeModuleId ?? output.name, output.fileName]);\n\t\t}\n\t}\n\tconst entries = Object.fromEntries(\n\t\tentryPairs.sort(([left], [right]) => left.localeCompare(right))\n\t);\n\treturn {\n\t\tenvironment: args.variant.environmentName,\n\t\tdirectory: args.variant.directory,\n\t\tentries,\n\t\tfiles,\n\t};\n}\n\nfunction partitionImports(\n\timports: string[],\n\temittedFileNames: ReadonlySet<string>\n): { internal: string[]; external: string[] } {\n\tconst internal: string[] = [];\n\tconst external: string[] = [];\n\tfor (const imported of imports) {\n\t\t(emittedFileNames.has(imported) ? internal : external).push(imported);\n\t}\n\treturn { internal, external };\n}\n\nfunction getByteLength(source: string | Uint8Array): number {\n\treturn typeof source === \"string\"\n\t\t? new TextEncoder().encode(source).byteLength\n\t\t: source.byteLength;\n}\n\nfunction normalizeOutputDirectory(directory: string): string {\n\tconst normalized = directory.replaceAll(\"\\\\\", \"/\").replace(/\\/+$/, \"\");\n\tif (\n\t\tnormalized === \"\" ||\n\t\tnormalized === \".\" ||\n\t\tnormalized.startsWith(\"/\") ||\n\t\tnormalized === \"..\" ||\n\t\tnormalized.startsWith(\"../\")\n\t) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild Vite environment outputDirectory must be a project-relative directory.\"\n\t\t);\n\t}\n\treturn normalized;\n}\n\nfunction validateViteLocaleBuildSettings(\n\tsettings: PerLocaleBuildSettings\n): void {\n\tif (!settings.baseLocale || !settings.locales.includes(settings.baseLocale)) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild Vite environments require baseLocale to be present in locales.\"\n\t\t);\n\t}\n\tif (\n\t\tsettings.locales.length === 0 ||\n\t\tnew Set(settings.locales).size !== settings.locales.length\n\t) {\n\t\tthrow new Error(\n\t\t\t\"experimentalPerLocaleBuild Vite environments require at least one unique locale.\"\n\t\t);\n\t}\n}\n"]}
|
|
@@ -59,16 +59,52 @@ export declare function compileFromWatchChange(args: {
|
|
|
59
59
|
addWatchFile: AddWatchFile;
|
|
60
60
|
forceEmitFiles?: true;
|
|
61
61
|
}): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Whether a generated paraglide module is side-effect-free and safe to
|
|
64
|
+
* tree-shake per entry.
|
|
65
|
+
*
|
|
66
|
+
* With `outputStructure: "message-modules"` each key is its own file and
|
|
67
|
+
* `messages.js` re-exports them as the `m` barrel. Rolldown can only drop
|
|
68
|
+
* unused barrel re-exports when the modules are known to be pure. Each
|
|
69
|
+
* message file imports `runtime.js`, which has real top-level side effects
|
|
70
|
+
* (`globalThis.__paraglide = …`), so without a purity signal Rolldown packs
|
|
71
|
+
* every message used anywhere in the app into one shared chunk.
|
|
72
|
+
*
|
|
73
|
+
* The compiler emits `messages/package.json` with `sideEffects: false`, but
|
|
74
|
+
* Vite only reads `sideEffects` from package.json on bare package resolves.
|
|
75
|
+
* For `src/paraglide/messages/*.js` resolved by this plugin that walk never
|
|
76
|
+
* happens, and `load()` serves source from memory — so the hook must return
|
|
77
|
+
* `moduleSideEffects: false` explicitly.
|
|
78
|
+
*
|
|
79
|
+
* Scoped to `messages.js` and `messages/` so `runtime.js` (which has real
|
|
80
|
+
* side effects) is unaffected.
|
|
81
|
+
*
|
|
82
|
+
* See https://github.com/opral/paraglide-js/issues/668
|
|
83
|
+
*/
|
|
84
|
+
export declare function isSideEffectFreeParaglideModule(absolutePath: string, absoluteOutdir: string): boolean;
|
|
85
|
+
export type VirtualModuleResolution = string | {
|
|
86
|
+
id: string;
|
|
87
|
+
moduleSideEffects: false;
|
|
88
|
+
} | undefined;
|
|
89
|
+
export type VirtualModuleLoad = string | {
|
|
90
|
+
code: string;
|
|
91
|
+
moduleSideEffects: false;
|
|
92
|
+
} | undefined;
|
|
62
93
|
/**
|
|
63
94
|
* Resolves an import to a generated paraglide module when present in memory.
|
|
64
95
|
*
|
|
65
96
|
* Only claims ids that resolve to a path under `outdir`. Relative imports from
|
|
66
97
|
* outside outdir (e.g. Svelte's own `./runtime.js`) must not be rewritten.
|
|
98
|
+
*
|
|
99
|
+
* Side-effect-free message modules (`messages.js`, `messages/*.js`) resolve
|
|
100
|
+
* to `{ id, moduleSideEffects: false }` so Rolldown/Vite can tree-shake
|
|
101
|
+
* unused barrel re-exports per entry. `runtime.js` and other generated
|
|
102
|
+
* modules keep default side-effect handling.
|
|
67
103
|
*/
|
|
68
104
|
export declare function resolveVirtualModuleId(args: {
|
|
69
105
|
id: string;
|
|
70
106
|
importer: string | undefined;
|
|
71
107
|
state: PluginState;
|
|
72
|
-
}):
|
|
73
|
-
export declare function loadVirtualModule(id: string, state: PluginState):
|
|
108
|
+
}): VirtualModuleResolution;
|
|
109
|
+
export declare function loadVirtualModule(id: string, state: PluginState): VirtualModuleLoad;
|
|
74
110
|
export { logger };
|
|
@@ -5,11 +5,20 @@ import { relative } from "node:path";
|
|
|
5
5
|
import { compile } from "../compiler/compile.js";
|
|
6
6
|
import { buildVirtualModules } from "../compiler/emit-files.js";
|
|
7
7
|
import { seedPreviousCompilationFromOutdir } from "../compiler/seed-previous-compilation.js";
|
|
8
|
+
import { ENV_VARIABLES } from "../services/env-variables/index.js";
|
|
8
9
|
import { Logger } from "../services/logger/index.js";
|
|
10
|
+
import { readDirectoryOutput } from "../services/file-handling/write-output.js";
|
|
9
11
|
import { createTrackedFs, getWatchTargets, isPathWithinDirectories, } from "../services/file-watching/tracked-fs.js";
|
|
10
12
|
import { nodeNormalizePath } from "../utilities/node-normalize-path.js";
|
|
11
13
|
export const PLUGIN_NAME = "unplugin-paraglide-lite";
|
|
12
14
|
const logger = new Logger();
|
|
15
|
+
const PERSISTENT_CACHE_VERSION = 1;
|
|
16
|
+
function isStringRecord(value) {
|
|
17
|
+
return (typeof value === "object" &&
|
|
18
|
+
value !== null &&
|
|
19
|
+
!Array.isArray(value) &&
|
|
20
|
+
Object.values(value).every((entry) => typeof entry === "string"));
|
|
21
|
+
}
|
|
13
22
|
// Module-scoped so the warm state survives plugin re-instantiation within
|
|
14
23
|
// one process (e.g. a vite config reload), but recreated when a different
|
|
15
24
|
// fs is passed — the tracked wrapper, read set, and cached compilation are
|
|
@@ -53,6 +62,124 @@ export function resolveOutputStructure(args) {
|
|
|
53
62
|
return (args.outputStructure ??
|
|
54
63
|
(isProduction ? "message-modules" : "locale-modules"));
|
|
55
64
|
}
|
|
65
|
+
function getCompilerConfig(args, outputStructure) {
|
|
66
|
+
const { fs: _fs, ...serializableArgs } = args;
|
|
67
|
+
void _fs;
|
|
68
|
+
return {
|
|
69
|
+
...serializableArgs,
|
|
70
|
+
outputStructure,
|
|
71
|
+
isServer: isServerExpression,
|
|
72
|
+
compilerVersion: ENV_VARIABLES.PARJS_PACKAGE_VERSION,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function getPersistentCachePath(args, outputStructure) {
|
|
76
|
+
const absoluteOutdir = path.resolve(process.cwd(), args.outdir);
|
|
77
|
+
const cacheKey = createHash("sha256")
|
|
78
|
+
.update(JSON.stringify({
|
|
79
|
+
absoluteOutdir,
|
|
80
|
+
compilerConfig: getCompilerConfig(args, outputStructure),
|
|
81
|
+
}))
|
|
82
|
+
.digest("hex")
|
|
83
|
+
.slice(0, 16);
|
|
84
|
+
return path.resolve(process.cwd(), ".paraglide-lite", "cache", `${cacheKey}.json`);
|
|
85
|
+
}
|
|
86
|
+
async function readPersistentCache(args, outputStructure) {
|
|
87
|
+
const fsp = (args.fs ?? nodeFs).promises;
|
|
88
|
+
try {
|
|
89
|
+
const parsed = JSON.parse(await fsp.readFile(getPersistentCachePath(args, outputStructure), "utf8"));
|
|
90
|
+
if (parsed.version !== PERSISTENT_CACHE_VERSION ||
|
|
91
|
+
parsed.compilerVersion !== ENV_VARIABLES.PARJS_PACKAGE_VERSION ||
|
|
92
|
+
typeof parsed.inputsDigest !== "string" ||
|
|
93
|
+
!Array.isArray(parsed.readFiles) ||
|
|
94
|
+
parsed.readFiles.some((file) => typeof file !== "string") ||
|
|
95
|
+
!isStringRecord(parsed.outputHashes)) {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
return parsed;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function preparePersistentCacheDirectory(args, outputStructure) {
|
|
105
|
+
try {
|
|
106
|
+
await (args.fs ?? nodeFs).promises.mkdir(path.dirname(getPersistentCachePath(args, outputStructure)), { recursive: true });
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// The cache is an optimization. Read-only projects must still compile.
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function writePersistentCache(state, args, outputStructure) {
|
|
113
|
+
if (state.previousInputsDigest === undefined ||
|
|
114
|
+
state.previousCompilation?.outputHashes === undefined) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const cachePath = getPersistentCachePath(args, outputStructure);
|
|
118
|
+
const cache = {
|
|
119
|
+
version: PERSISTENT_CACHE_VERSION,
|
|
120
|
+
compilerVersion: ENV_VARIABLES.PARJS_PACKAGE_VERSION,
|
|
121
|
+
inputsDigest: state.previousInputsDigest,
|
|
122
|
+
readFiles: [...state.readFiles].sort(),
|
|
123
|
+
outputHashes: state.previousCompilation.outputHashes,
|
|
124
|
+
};
|
|
125
|
+
const fsp = (args.fs ?? nodeFs).promises;
|
|
126
|
+
try {
|
|
127
|
+
await fsp.mkdir(path.dirname(cachePath), { recursive: true });
|
|
128
|
+
await fsp.writeFile(cachePath, JSON.stringify(cache));
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// The cache is an optimization. Read-only projects must still compile.
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function outputHashesMatch(left, right) {
|
|
135
|
+
if (left === undefined)
|
|
136
|
+
return false;
|
|
137
|
+
const leftEntries = Object.entries(left);
|
|
138
|
+
const rightEntries = Object.entries(right);
|
|
139
|
+
if (leftEntries.length !== rightEntries.length)
|
|
140
|
+
return false;
|
|
141
|
+
return leftEntries.every(([file, hash]) => right[file] === hash);
|
|
142
|
+
}
|
|
143
|
+
async function restorePersistentCache(args) {
|
|
144
|
+
const cached = await readPersistentCache(args.compilerOptions, args.outputStructure);
|
|
145
|
+
if (cached === undefined)
|
|
146
|
+
return false;
|
|
147
|
+
const cachedReadFiles = new Set();
|
|
148
|
+
for (const file of cached.readFiles) {
|
|
149
|
+
cachedReadFiles.add(file);
|
|
150
|
+
}
|
|
151
|
+
const validationState = {
|
|
152
|
+
...args.state,
|
|
153
|
+
readFiles: cachedReadFiles,
|
|
154
|
+
clearReadFiles: () => cachedReadFiles.clear(),
|
|
155
|
+
};
|
|
156
|
+
const [inputsDigest, previousCompilation, diskOutput] = await Promise.all([
|
|
157
|
+
computeInputsDigest(validationState, args.compilerOptions, args.outputStructure),
|
|
158
|
+
seedPreviousCompilationFromOutdir({
|
|
159
|
+
outdir: args.compilerOptions.outdir,
|
|
160
|
+
fs: args.compilerOptions.fs?.promises,
|
|
161
|
+
}),
|
|
162
|
+
readDirectoryOutput(path.resolve(process.cwd(), args.compilerOptions.outdir), args.compilerOptions.fs?.promises ?? nodeFs.promises),
|
|
163
|
+
]);
|
|
164
|
+
if (inputsDigest !== cached.inputsDigest ||
|
|
165
|
+
!outputHashesMatch(previousCompilation?.outputHashes, cached.outputHashes)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
args.state.clearReadFiles();
|
|
169
|
+
for (const file of cachedReadFiles) {
|
|
170
|
+
args.state.readFiles.add(file);
|
|
171
|
+
}
|
|
172
|
+
args.state.previousCompilation = {
|
|
173
|
+
outputHashes: previousCompilation?.outputHashes,
|
|
174
|
+
output: diskOutput ?? {},
|
|
175
|
+
};
|
|
176
|
+
args.state.previousInputsDigest = inputsDigest;
|
|
177
|
+
updateVirtualModules(args.state, args.compilerOptions, {
|
|
178
|
+
outputHashes: previousCompilation?.outputHashes,
|
|
179
|
+
output: diskOutput ?? {},
|
|
180
|
+
});
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
56
183
|
/**
|
|
57
184
|
* Hashes the files (and directory listings) the last compilation read,
|
|
58
185
|
* together with the options that affect the output. Returns `undefined`
|
|
@@ -70,13 +197,7 @@ export async function computeInputsDigest(state, args, outputStructure) {
|
|
|
70
197
|
const fsp = (args.fs ?? nodeFs).promises;
|
|
71
198
|
const hash = createHash("sha256");
|
|
72
199
|
try {
|
|
73
|
-
|
|
74
|
-
void _fs;
|
|
75
|
-
hash.update(JSON.stringify({
|
|
76
|
-
...serializableArgs,
|
|
77
|
-
outputStructure,
|
|
78
|
-
isServer: isServerExpression,
|
|
79
|
-
}));
|
|
200
|
+
hash.update(JSON.stringify(getCompilerConfig(args, outputStructure)));
|
|
80
201
|
for (const directoryPath of [...targets.directories].sort()) {
|
|
81
202
|
const entries = await fsp
|
|
82
203
|
.readdir(directoryPath)
|
|
@@ -123,6 +244,16 @@ export async function compileFromBuildStart(args) {
|
|
|
123
244
|
const outputStructure = resolveOutputStructure(compilerOptions);
|
|
124
245
|
const isProduction = process.env.NODE_ENV === "production";
|
|
125
246
|
try {
|
|
247
|
+
await preparePersistentCacheDirectory(compilerOptions, outputStructure);
|
|
248
|
+
if (state.previousCompilation === undefined &&
|
|
249
|
+
(await restorePersistentCache({
|
|
250
|
+
state,
|
|
251
|
+
compilerOptions,
|
|
252
|
+
outputStructure,
|
|
253
|
+
}))) {
|
|
254
|
+
logger.info(`Compilation skipped — inputs unchanged (${outputStructure})`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
126
257
|
if (state.previousCompilation && state.previousInputsDigest) {
|
|
127
258
|
const currentDigest = await computeInputsDigest(state, compilerOptions, outputStructure);
|
|
128
259
|
if (currentDigest === state.previousInputsDigest) {
|
|
@@ -146,6 +277,7 @@ export async function compileFromBuildStart(args) {
|
|
|
146
277
|
updateVirtualModules(state, compilerOptions, result);
|
|
147
278
|
state.previousCompilation = result;
|
|
148
279
|
state.previousInputsDigest = await computeInputsDigest(state, compilerOptions, outputStructure);
|
|
280
|
+
await writePersistentCache(state, compilerOptions, outputStructure);
|
|
149
281
|
logger.success(`Compilation complete (${outputStructure})`);
|
|
150
282
|
}
|
|
151
283
|
catch (error) {
|
|
@@ -201,6 +333,7 @@ export async function compileFromWatchChange(args) {
|
|
|
201
333
|
updateVirtualModules(state, compilerOptions, result);
|
|
202
334
|
state.previousCompilation = result;
|
|
203
335
|
state.previousInputsDigest = await computeInputsDigest(state, compilerOptions, outputStructure);
|
|
336
|
+
await writePersistentCache(state, compilerOptions, outputStructure);
|
|
204
337
|
logger.success(`Re-compilation complete (${outputStructure})`);
|
|
205
338
|
const nextTargets = getWatchTargets(readFiles, {
|
|
206
339
|
outdir: compilerOptions.outdir,
|
|
@@ -227,11 +360,52 @@ function updateVirtualModules(state, args, result) {
|
|
|
227
360
|
state.absoluteOutdir = path.resolve(process.cwd(), args.outdir);
|
|
228
361
|
state.virtualModules = buildVirtualModules(args.outdir, result.output, process.cwd());
|
|
229
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Whether a generated paraglide module is side-effect-free and safe to
|
|
365
|
+
* tree-shake per entry.
|
|
366
|
+
*
|
|
367
|
+
* With `outputStructure: "message-modules"` each key is its own file and
|
|
368
|
+
* `messages.js` re-exports them as the `m` barrel. Rolldown can only drop
|
|
369
|
+
* unused barrel re-exports when the modules are known to be pure. Each
|
|
370
|
+
* message file imports `runtime.js`, which has real top-level side effects
|
|
371
|
+
* (`globalThis.__paraglide = …`), so without a purity signal Rolldown packs
|
|
372
|
+
* every message used anywhere in the app into one shared chunk.
|
|
373
|
+
*
|
|
374
|
+
* The compiler emits `messages/package.json` with `sideEffects: false`, but
|
|
375
|
+
* Vite only reads `sideEffects` from package.json on bare package resolves.
|
|
376
|
+
* For `src/paraglide/messages/*.js` resolved by this plugin that walk never
|
|
377
|
+
* happens, and `load()` serves source from memory — so the hook must return
|
|
378
|
+
* `moduleSideEffects: false` explicitly.
|
|
379
|
+
*
|
|
380
|
+
* Scoped to `messages.js` and `messages/` so `runtime.js` (which has real
|
|
381
|
+
* side effects) is unaffected.
|
|
382
|
+
*
|
|
383
|
+
* See https://github.com/opral/paraglide-js/issues/668
|
|
384
|
+
*/
|
|
385
|
+
export function isSideEffectFreeParaglideModule(absolutePath, absoluteOutdir) {
|
|
386
|
+
const normalizedPath = nodeNormalizePath(absolutePath);
|
|
387
|
+
const outdir = nodeNormalizePath(absoluteOutdir);
|
|
388
|
+
if (normalizedPath === `${outdir}/messages.js`) {
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
const messagesDir = `${outdir}/messages/`;
|
|
392
|
+
if (!normalizedPath.startsWith(messagesDir)) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
return (normalizedPath.endsWith(".js") ||
|
|
396
|
+
normalizedPath.endsWith(".mjs") ||
|
|
397
|
+
normalizedPath.endsWith(".cjs"));
|
|
398
|
+
}
|
|
230
399
|
/**
|
|
231
400
|
* Resolves an import to a generated paraglide module when present in memory.
|
|
232
401
|
*
|
|
233
402
|
* Only claims ids that resolve to a path under `outdir`. Relative imports from
|
|
234
403
|
* outside outdir (e.g. Svelte's own `./runtime.js`) must not be rewritten.
|
|
404
|
+
*
|
|
405
|
+
* Side-effect-free message modules (`messages.js`, `messages/*.js`) resolve
|
|
406
|
+
* to `{ id, moduleSideEffects: false }` so Rolldown/Vite can tree-shake
|
|
407
|
+
* unused barrel re-exports per entry. `runtime.js` and other generated
|
|
408
|
+
* modules keep default side-effect handling.
|
|
235
409
|
*/
|
|
236
410
|
export function resolveVirtualModuleId(args) {
|
|
237
411
|
if (args.state.virtualModules.size === 0) {
|
|
@@ -256,19 +430,25 @@ export function resolveVirtualModuleId(args) {
|
|
|
256
430
|
continue;
|
|
257
431
|
}
|
|
258
432
|
if (args.state.virtualModules.has(normalized)) {
|
|
259
|
-
return normalized;
|
|
433
|
+
return toVirtualModuleResolution(normalized, args.state.absoluteOutdir);
|
|
260
434
|
}
|
|
261
435
|
if (args.state.virtualModules.has(`${normalized}.js`)) {
|
|
262
|
-
return `${normalized}.js
|
|
436
|
+
return toVirtualModuleResolution(`${normalized}.js`, args.state.absoluteOutdir);
|
|
263
437
|
}
|
|
264
438
|
const indexPath = nodeNormalizePath(path.join(normalized, "index.js"));
|
|
265
439
|
if (!normalized.endsWith(".js") &&
|
|
266
440
|
args.state.virtualModules.has(indexPath)) {
|
|
267
|
-
return indexPath;
|
|
441
|
+
return toVirtualModuleResolution(indexPath, args.state.absoluteOutdir);
|
|
268
442
|
}
|
|
269
443
|
}
|
|
270
444
|
return undefined;
|
|
271
445
|
}
|
|
446
|
+
function toVirtualModuleResolution(resolved, absoluteOutdir) {
|
|
447
|
+
if (isSideEffectFreeParaglideModule(resolved, absoluteOutdir)) {
|
|
448
|
+
return { id: resolved, moduleSideEffects: false };
|
|
449
|
+
}
|
|
450
|
+
return resolved;
|
|
451
|
+
}
|
|
272
452
|
function isPathInsideDirectory(filePath, directory) {
|
|
273
453
|
const relativePath = path.relative(directory, filePath);
|
|
274
454
|
return (relativePath === "" ||
|
|
@@ -276,7 +456,14 @@ function isPathInsideDirectory(filePath, directory) {
|
|
|
276
456
|
}
|
|
277
457
|
export function loadVirtualModule(id, state) {
|
|
278
458
|
const normalized = nodeNormalizePath(stripQueryAndHash(id));
|
|
279
|
-
|
|
459
|
+
const code = state.virtualModules.get(normalized);
|
|
460
|
+
if (code === undefined) {
|
|
461
|
+
return undefined;
|
|
462
|
+
}
|
|
463
|
+
if (isSideEffectFreeParaglideModule(normalized, state.absoluteOutdir)) {
|
|
464
|
+
return { code, moduleSideEffects: false };
|
|
465
|
+
}
|
|
466
|
+
return code;
|
|
280
467
|
}
|
|
281
468
|
function stripQueryAndHash(id) {
|
|
282
469
|
const queryIndex = id.indexOf("?");
|