@inlang/paraglide-js 2.18.2 → 2.19.0
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/README.md +27 -27
- package/dist/bundler-plugins/unplugin.d.ts.map +1 -1
- package/dist/bundler-plugins/unplugin.js +239 -120
- package/dist/bundler-plugins/unplugin.js.map +1 -1
- package/dist/bundler-plugins/unplugin.test.js +184 -1
- package/dist/bundler-plugins/unplugin.test.js.map +1 -1
- package/dist/cli/commands/compile/command.js +1 -1
- package/dist/cli/commands/compile/command.js.map +1 -1
- package/dist/cli/commands/init/command.js +2 -2
- package/dist/cli/commands/init/command.js.map +1 -1
- package/dist/compiler/compile-annotation.d.ts +13 -0
- package/dist/compiler/compile-annotation.d.ts.map +1 -0
- package/dist/compiler/compile-annotation.js +136 -0
- package/dist/compiler/compile-annotation.js.map +1 -0
- package/dist/compiler/compile-local-variable.d.ts.map +1 -1
- package/dist/compiler/compile-local-variable.js +1 -108
- package/dist/compiler/compile-local-variable.js.map +1 -1
- package/dist/compiler/compile-message.js +4 -0
- package/dist/compiler/compile-message.js.map +1 -1
- package/dist/compiler/compile-message.test.js +81 -0
- package/dist/compiler/compile-message.test.js.map +1 -1
- package/dist/compiler/compile-pattern.d.ts +8 -0
- package/dist/compiler/compile-pattern.d.ts.map +1 -1
- package/dist/compiler/compile-pattern.js +38 -2
- package/dist/compiler/compile-pattern.js.map +1 -1
- package/dist/compiler/compile-pattern.test.js +109 -0
- package/dist/compiler/compile-pattern.test.js.map +1 -1
- package/dist/compiler/compile-project.js +1 -1
- package/dist/compiler/compile-project.test.js +69 -0
- package/dist/compiler/compile-project.test.js.map +1 -1
- package/dist/compiler/compiler-options.d.ts +1 -1
- package/dist/compiler/create-readme.js +4 -4
- package/dist/compiler/runtime/extract-locale-from-request.js +1 -1
- package/dist/compiler/runtime/extract-locale-from-request.js.map +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.d.ts +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.js +1 -1
- package/dist/compiler/runtime/get-locale.js +4 -4
- package/dist/compiler/runtime/get-locale.js.map +1 -1
- package/dist/compiler/runtime/localize-href.d.ts +2 -2
- package/dist/compiler/runtime/localize-href.js +2 -2
- package/dist/compiler/runtime/localize-url.d.ts +2 -2
- package/dist/compiler/runtime/localize-url.js +2 -2
- package/dist/compiler/runtime/set-locale.d.ts +1 -1
- package/dist/compiler/runtime/set-locale.js +1 -1
- package/dist/compiler/runtime/should-redirect.d.ts +1 -1
- package/dist/compiler/runtime/should-redirect.js +1 -1
- package/dist/compiler/runtime/strategy.d.ts +2 -2
- package/dist/compiler/runtime/strategy.js +2 -2
- package/dist/compiler/server/middleware.d.ts +1 -1
- package/dist/compiler/server/middleware.js +1 -1
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/file-watching/tracked-fs.d.ts.map +1 -1
- package/dist/services/file-watching/tracked-fs.js +3 -1
- package/dist/services/file-watching/tracked-fs.js.map +1 -1
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
14
|
-
<a href="https://
|
|
14
|
+
<a href="https://paraglidejs.com"><strong>Documentation</strong></a> ·
|
|
15
15
|
<a href="#quick-start"><strong>Quick Start</strong></a> ·
|
|
16
16
|
<a href="https://github.com/opral/inlang-paraglide-js/issues"><strong>Report Bug</strong></a>
|
|
17
17
|
</p>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<p align="center">
|
|
34
34
|
<sub>Framework-authored and framework-tested</sub><br/><br/>
|
|
35
35
|
<a href="https://svelte.dev/docs/cli/paraglide"><img src="https://cdn.simpleicons.org/svelte/FF3E00" alt="Svelte" height="14" /> SvelteKit's official i18n integration</a><br/>
|
|
36
|
-
<a href="https://
|
|
36
|
+
<a href="https://paraglidejs.com/blog/tanstack-ci"><img src="https://tanstack.com/images/logos/logo-color-100.png" alt="TanStack" height="14" /> TanStack Router's e2e-tested i18n example</a>
|
|
37
37
|
</p>
|
|
38
38
|
|
|
39
39
|
## Code Preview
|
|
@@ -51,7 +51,7 @@ import { m } from "./paraglide/messages.js";
|
|
|
51
51
|
m.greeting({ name: "World" }); // "Hello World!" — fully typesafe
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
The compiler turns your messages into typed ESM functions. Vite, Rollup, and other modern bundlers can tree-shake unused translations before they reach the browser. Expect [**up to 70% smaller i18n bundle sizes**](https://
|
|
54
|
+
The compiler turns your messages into typed ESM functions. Vite, Rollup, and other modern bundlers can tree-shake unused translations before they reach the browser. Expect [**up to 70% smaller i18n bundle sizes**](https://paraglidejs.com/benchmark) compared to runtime i18n libraries (e.g. 47 KB vs 205 KB).
|
|
55
55
|
|
|
56
56
|
## Why Paraglide?
|
|
57
57
|
|
|
@@ -67,23 +67,23 @@ The compiler turns your messages into typed ESM functions. Vite, Rollup, and oth
|
|
|
67
67
|
## Get Started With Your Framework
|
|
68
68
|
|
|
69
69
|
<p>
|
|
70
|
-
<a href="https://
|
|
71
|
-
<a href="https://
|
|
70
|
+
<a href="https://paraglidejs.com/vite"><img src="https://cdn.simpleicons.org/react/61DAFB" alt="React" width="18" height="18" /> React</a> ·
|
|
71
|
+
<a href="https://paraglidejs.com/vite"><img src="https://cdn.simpleicons.org/vuedotjs/4FC08D" alt="Vue" width="18" height="18" /> Vue</a> ·
|
|
72
72
|
<a href="https://github.com/TanStack/router/tree/main/examples/react/start-i18n-paraglide"><img src="https://tanstack.com/images/logos/logo-color-100.png" alt="TanStack" width="18" height="18" /> TanStack Start</a> ·
|
|
73
|
-
<a href="https://
|
|
74
|
-
<a href="https://
|
|
75
|
-
<a href="https://
|
|
76
|
-
<a href="https://
|
|
73
|
+
<a href="https://paraglidejs.com/sveltekit"><img src="https://cdn.simpleicons.org/svelte/FF3E00" alt="Svelte" width="18" height="18" /> SvelteKit</a> ·
|
|
74
|
+
<a href="https://paraglidejs.com/react-router"><img src="https://cdn.simpleicons.org/reactrouter/CA4245" alt="React Router" width="18" height="18" /> React Router</a> ·
|
|
75
|
+
<a href="https://paraglidejs.com/astro"><img src="https://cdn.simpleicons.org/astro/FF5D01" alt="Astro" width="18" height="18" /> Astro</a> ·
|
|
76
|
+
<a href="https://paraglidejs.com/vanilla-js-ts"><img src="https://cdn.simpleicons.org/javascript/F7DF1E" alt="JavaScript" width="18" height="18" /> Vanilla JS/TS</a>
|
|
77
77
|
</p>
|
|
78
78
|
|
|
79
79
|
- **[TanStack Start example](https://github.com/TanStack/router/tree/main/examples/react/start-i18n-paraglide)** — SSR, localized routing, and TanStack Router integration.
|
|
80
|
-
- **[SvelteKit guide](https://
|
|
81
|
-
- **[React Router guide](https://
|
|
82
|
-
- **[Astro guide](https://
|
|
83
|
-
- **[Vite guide](https://
|
|
80
|
+
- **[SvelteKit guide](https://paraglidejs.com/sveltekit)** — SvelteKit's official i18n integration.
|
|
81
|
+
- **[React Router guide](https://paraglidejs.com/react-router)** — SSR and client routing.
|
|
82
|
+
- **[Astro guide](https://paraglidejs.com/astro)** — static and server-rendered sites.
|
|
83
|
+
- **[Vite guide](https://paraglidejs.com/vite)** — React, Vue, Solid, or vanilla JS/TS.
|
|
84
84
|
|
|
85
85
|
> [!TIP]
|
|
86
|
-
> <img src="https://vitejs.dev/logo.svg" alt="Vite" width="16" height="16" /> **Paraglide is ideal for Vite-based apps.** Setup is one plugin, messages compile to ESM, and Vite's tree-shaking eliminates unused translations automatically. [Get started →](https://
|
|
86
|
+
> <img src="https://vitejs.dev/logo.svg" alt="Vite" width="16" height="16" /> **Paraglide is ideal for Vite-based apps.** Setup is one plugin, messages compile to ESM, and Vite's tree-shaking eliminates unused translations automatically. [Get started →](https://paraglidejs.com/vite)
|
|
87
87
|
|
|
88
88
|
## SSR Ready
|
|
89
89
|
|
|
@@ -109,7 +109,7 @@ export function handle(request: Request) {
|
|
|
109
109
|
}
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
-
**[SSR Docs →](https://
|
|
112
|
+
**[SSR Docs →](https://paraglidejs.com/server-side-rendering)** · **[Middleware Docs →](https://paraglidejs.com/middleware)**
|
|
113
113
|
|
|
114
114
|
## Router Composition
|
|
115
115
|
|
|
@@ -129,7 +129,7 @@ localizeUrl("https://example.com/about", { locale: "de" }).href; // https://exam
|
|
|
129
129
|
|
|
130
130
|
For routers with rewrite hooks, call `deLocalizeUrl()` on incoming URLs and `localizeUrl()` on outgoing URLs. For file-based routers, keep your file routes canonical and localize at the routing boundary.
|
|
131
131
|
|
|
132
|
-
**[i18n Routing Docs →](https://
|
|
132
|
+
**[i18n Routing Docs →](https://paraglidejs.com/i18n-routing)**
|
|
133
133
|
|
|
134
134
|
### TanStack Start
|
|
135
135
|
|
|
@@ -177,7 +177,7 @@ getLocale(); // "en"
|
|
|
177
177
|
setLocale("de"); // switches to German
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
**[Full Getting Started Guide →](https://
|
|
180
|
+
**[Full Getting Started Guide →](https://paraglidejs.com)**
|
|
181
181
|
|
|
182
182
|
## Rich Text
|
|
183
183
|
|
|
@@ -202,7 +202,7 @@ export function ContactCta() {
|
|
|
202
202
|
|
|
203
203
|
The markup names come from your message and are type-checked, so translators control where links and emphasis appear while your React app controls how they render.
|
|
204
204
|
|
|
205
|
-
**[Markup Docs →](https://
|
|
205
|
+
**[Markup Docs →](https://paraglidejs.com/markup)** · **[React](https://www.npmjs.com/package/@inlang/paraglide-js-react)** · **[Svelte](https://www.npmjs.com/package/@inlang/paraglide-js-svelte)** · **[Vue](https://www.npmjs.com/package/@inlang/paraglide-js-vue)** · **[Solid](https://www.npmjs.com/package/@inlang/paraglide-js-solid)**
|
|
206
206
|
|
|
207
207
|
## How It Works
|
|
208
208
|
|
|
@@ -248,7 +248,7 @@ m.items_in_cart({ count: 5 }); // "5 items in cart"
|
|
|
248
248
|
|
|
249
249
|
Message format is **plugin-based** — use the default inlang format, or switch to i18next, JSON, or ICU MessageFormat via [plugins](https://inlang.com/c/plugins). If your team relies on ICU MessageFormat 1 syntax, use the [inlang-icu-messageformat-1 plugin](https://inlang.com/m/p7c8m1d2/plugin-inlang-icu-messageformat-1).
|
|
250
250
|
|
|
251
|
-
**[Formatting Docs →](https://
|
|
251
|
+
**[Formatting Docs →](https://paraglidejs.com/formatting)** · **[Pluralization & Variants Docs →](https://paraglidejs.com/variants)**
|
|
252
252
|
|
|
253
253
|
## Why Compiler-First?
|
|
254
254
|
|
|
@@ -256,7 +256,7 @@ Runtime i18n libraries like i18next resolve message keys from dictionaries while
|
|
|
256
256
|
|
|
257
257
|
That means Vite can tree-shake unused translations, TypeScript can autocomplete message keys and parameters, and your components call plain functions instead of resolving strings through a runtime lookup layer.
|
|
258
258
|
|
|
259
|
-
In the [Paraglide benchmark](https://
|
|
259
|
+
In the [Paraglide benchmark](https://paraglidejs.com/benchmark), typical scenarios shipped **47-144 KB with Paraglide** vs **205-422 KB with i18next**. With 5 locales, 100 used messages, and 200 total messages, Paraglide shipped **47 KB** while i18next shipped **205 KB**.
|
|
260
260
|
|
|
261
261
|
Tree-shaking also keeps Paraglide stable as your message catalog grows. In the benchmark, using 100 messages shipped **47 KB** with Paraglide whether the project had 200, 500, or 1,000 total messages. The i18next runtime bundle grew from **205 KB** to **414 KB**.
|
|
262
262
|
|
|
@@ -273,7 +273,7 @@ Tree-shaking also keeps Paraglide stable as your message catalog grows. In the b
|
|
|
273
273
|
| **Rich text** | ✅ Typed markup adapters | ✅ Rich-text components | Via framework wrappers |
|
|
274
274
|
| **ICU MessageFormat 1** | ✅ [Via plugin](https://inlang.com/m/p7c8m1d2/plugin-inlang-icu-messageformat-1) | ✅ | Via plugin |
|
|
275
275
|
|
|
276
|
-
**[Full Comparison →](https://
|
|
276
|
+
**[Full Comparison →](https://paraglidejs.com/comparison)**
|
|
277
277
|
|
|
278
278
|
## FAQ
|
|
279
279
|
|
|
@@ -333,12 +333,12 @@ Paraglide compiles messages from [inlang](https://github.com/opral/inlang), the
|
|
|
333
333
|
|
|
334
334
|
## Documentation
|
|
335
335
|
|
|
336
|
-
- [Getting Started](https://
|
|
337
|
-
- [Framework Guides](https://
|
|
338
|
-
- [Message Syntax & Pluralization](https://
|
|
339
|
-
- [Formatting (Number/Date/Relative Time)](https://
|
|
340
|
-
- [Routing & SSR](https://
|
|
341
|
-
- [API Reference](https://
|
|
336
|
+
- [Getting Started](https://paraglidejs.com)
|
|
337
|
+
- [Framework Guides](https://paraglidejs.com/react-router) (React Router, SvelteKit, Astro, etc.)
|
|
338
|
+
- [Message Syntax & Pluralization](https://paraglidejs.com/variants)
|
|
339
|
+
- [Formatting (Number/Date/Relative Time)](https://paraglidejs.com/formatting)
|
|
340
|
+
- [Routing & SSR](https://paraglidejs.com/server-side-rendering)
|
|
341
|
+
- [API Reference](https://paraglidejs.com)
|
|
342
342
|
|
|
343
343
|
## Contributing
|
|
344
344
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unplugin.d.ts","sourceRoot":"","sources":["../../src/bundler-plugins/unplugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"unplugin.d.ts","sourceRoot":"","sources":["../../src/bundler-plugins/unplugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AA8IvE,eAAO,MAAM,eAAe,EAAE,eAAe,CAAC,eAAe,CAiN5D,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { compile } from "../compiler/compile.js";
|
|
2
2
|
import { relative } from "node:path";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import nodeFs from "node:fs";
|
|
3
5
|
import { Logger } from "../services/logger/index.js";
|
|
4
6
|
import { createTrackedFs, getWatchTargets, isPathWithinDirectories, } from "../services/file-watching/tracked-fs.js";
|
|
5
7
|
import { nodeNormalizePath } from "../utilities/node-normalize-path.js";
|
|
@@ -10,156 +12,273 @@ const logger = new Logger();
|
|
|
10
12
|
* Default isServer which differs per bundler.
|
|
11
13
|
*/
|
|
12
14
|
let isServer;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
// Module-scoped so the warm state survives plugin re-instantiation within
|
|
16
|
+
// one process (e.g. a vite config reload), but recreated when a different
|
|
17
|
+
// fs is passed — the tracked wrapper, read set, and cached compilation are
|
|
18
|
+
// only valid for the filesystem they were produced from.
|
|
19
|
+
let pluginState;
|
|
20
|
+
function getPluginState(args) {
|
|
21
|
+
if (pluginState === undefined || pluginState.baseFs !== args.fs) {
|
|
22
|
+
const tracked = createTrackedFs({ fs: args.fs });
|
|
23
|
+
pluginState = {
|
|
24
|
+
baseFs: args.fs,
|
|
25
|
+
trackedFs: tracked.fs,
|
|
26
|
+
readFiles: tracked.readFiles,
|
|
27
|
+
clearReadFiles: tracked.clearReadFiles,
|
|
28
|
+
previousCompilation: undefined,
|
|
29
|
+
previousInputsDigest: undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return pluginState;
|
|
33
|
+
}
|
|
15
34
|
function withoutCleanOutdir(args) {
|
|
16
35
|
const { cleanOutdir, ...compileArgs } = args;
|
|
17
36
|
void cleanOutdir;
|
|
18
37
|
return compileArgs;
|
|
19
38
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Hashes the files (and directory listings) the last compilation read,
|
|
41
|
+
* together with the options that affect the output. Returns `undefined`
|
|
42
|
+
* when the digest can't be computed (no tracked reads yet, an unexpected
|
|
43
|
+
* read error, ...) — `undefined` never matches, so the caller compiles.
|
|
44
|
+
*
|
|
45
|
+
* Directory listings are included so that a message file *added* next to
|
|
46
|
+
* the tracked ones invalidates the digest, not only edits to known files.
|
|
47
|
+
* All components are length-prefixed so distinct input states can't
|
|
48
|
+
* produce the same hash stream.
|
|
49
|
+
*
|
|
50
|
+
* The digest is taken after the compile, by re-reading the inputs. A file
|
|
51
|
+
* edited *during* a compile can therefore be hashed at its new content
|
|
52
|
+
* while the output reflects the old one — accepted: in dev, watchChange
|
|
53
|
+
* recompiles on that edit, and a fresh build process always recompiles.
|
|
54
|
+
*/
|
|
55
|
+
async function computeInputsDigest(state, args, outputStructure) {
|
|
56
|
+
if (state.readFiles.size === 0) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const targets = getWatchTargets(state.readFiles, { outdir: args.outdir });
|
|
60
|
+
if (targets.files.size === 0) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const fsp = (args.fs ?? nodeFs).promises;
|
|
64
|
+
const hash = createHash("sha256");
|
|
65
|
+
try {
|
|
66
|
+
const { fs: _fs, ...serializableArgs } = args;
|
|
67
|
+
void _fs;
|
|
68
|
+
hash.update(JSON.stringify({ ...serializableArgs, outputStructure, isServer }));
|
|
69
|
+
for (const directoryPath of [...targets.directories].sort()) {
|
|
70
|
+
const entries = await fsp
|
|
71
|
+
.readdir(directoryPath)
|
|
72
|
+
// tracked reads include probed-but-absent paths (the SDK reads
|
|
73
|
+
// optional files and handles ENOENT itself) — a missing entry
|
|
74
|
+
// is valid input state, hash it as such
|
|
75
|
+
.catch(rethrowUnlessEnoent);
|
|
76
|
+
hash.update(`\0dir:${directoryPath.length}:${directoryPath}:`);
|
|
77
|
+
if (entries === undefined) {
|
|
78
|
+
hash.update("missing");
|
|
59
79
|
}
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
else {
|
|
81
|
+
for (const entry of [...entries].sort()) {
|
|
82
|
+
hash.update(`${entry.length}:${entry},`);
|
|
83
|
+
}
|
|
62
84
|
}
|
|
63
85
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const shouldCompile = targets.files.has(normalizedPath) ||
|
|
72
|
-
isPathWithinDirectories(normalizedPath, targets.directories);
|
|
73
|
-
if (shouldCompile === false) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
77
|
-
// default to locale-modules for development to speed up the dev server
|
|
78
|
-
// https://github.com/opral/inlang-paraglide-js/issues/486
|
|
79
|
-
const outputStructure = args.outputStructure ??
|
|
80
|
-
(isProduction ? "message-modules" : "locale-modules");
|
|
81
|
-
const previouslyReadFiles = new Set(readFiles);
|
|
82
|
-
try {
|
|
83
|
-
logger.info(`Re-compiling inlang project... File "${relative(process.cwd(), path)}" has changed.`);
|
|
84
|
-
// Clear readFiles to track fresh file reads
|
|
85
|
-
clearReadFiles();
|
|
86
|
-
previousCompilation = await compile({
|
|
87
|
-
fs: trackedFs,
|
|
88
|
-
previousCompilation,
|
|
89
|
-
outputStructure,
|
|
90
|
-
isServer,
|
|
91
|
-
...withoutCleanOutdir(args),
|
|
92
|
-
cleanOutdir: false,
|
|
93
|
-
});
|
|
94
|
-
logger.success(`Re-compilation complete (${outputStructure})`);
|
|
95
|
-
// Add any new files to watch
|
|
96
|
-
const nextTargets = getWatchTargets(readFiles, { outdir: args.outdir });
|
|
97
|
-
for (const filePath of nextTargets.files) {
|
|
98
|
-
this.addWatchFile(filePath);
|
|
99
|
-
}
|
|
100
|
-
for (const directoryPath of nextTargets.directories) {
|
|
101
|
-
this.addWatchFile(directoryPath);
|
|
86
|
+
for (const filePath of [...targets.files].sort()) {
|
|
87
|
+
const content = await fsp.readFile(filePath).catch(rethrowUnlessEnoent);
|
|
88
|
+
hash.update(`\0file:${filePath.length}:${filePath}:`);
|
|
89
|
+
if (content === undefined) {
|
|
90
|
+
hash.update("missing");
|
|
102
91
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
for (const filePath of previouslyReadFiles) {
|
|
107
|
-
readFiles.add(filePath);
|
|
92
|
+
else {
|
|
93
|
+
hash.update(`${content.length}:`);
|
|
94
|
+
hash.update(content);
|
|
108
95
|
}
|
|
109
|
-
// Reset compilation result on error
|
|
110
|
-
previousCompilation = undefined;
|
|
111
|
-
logger.warn("Failed to re-compile project:", e.message);
|
|
112
96
|
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
async_hooks: false,
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
compiler.hooks.beforeRun.tapPromise(PLUGIN_NAME, async () => {
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return hash.digest("hex");
|
|
102
|
+
}
|
|
103
|
+
function rethrowUnlessEnoent(error) {
|
|
104
|
+
if (error?.code === "ENOENT") {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
export const unpluginFactory = (args) => {
|
|
110
|
+
const state = getPluginState(args);
|
|
111
|
+
const { trackedFs, readFiles, clearReadFiles } = state;
|
|
112
|
+
return {
|
|
113
|
+
name: PLUGIN_NAME,
|
|
114
|
+
enforce: "pre",
|
|
115
|
+
async buildStart() {
|
|
136
116
|
const isProduction = process.env.NODE_ENV === "production";
|
|
137
117
|
// default to locale-modules for development to speed up the dev server
|
|
138
118
|
// https://github.com/opral/inlang-paraglide-js/issues/486
|
|
139
119
|
const outputStructure = args.outputStructure ??
|
|
140
120
|
(isProduction ? "message-modules" : "locale-modules");
|
|
141
121
|
try {
|
|
142
|
-
|
|
122
|
+
// `vite build` calls buildStart once per environment (client, ssr).
|
|
123
|
+
// Skip the expensive compile when the inputs haven't changed.
|
|
124
|
+
if (state.previousCompilation && state.previousInputsDigest) {
|
|
125
|
+
const currentDigest = await computeInputsDigest(state, args, outputStructure);
|
|
126
|
+
if (currentDigest === state.previousInputsDigest) {
|
|
127
|
+
logger.info(`Compilation skipped — inputs unchanged (${outputStructure})`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// On a fresh process, seed previousCompilation from on-disk hashes
|
|
132
|
+
// so the first compile is a no-op when inputs are unchanged. Avoids
|
|
133
|
+
// racing concurrent readers that wiping outdir would interrupt.
|
|
134
|
+
const seededPrevious = state.previousCompilation ??
|
|
143
135
|
(await seedPreviousCompilationFromOutdir({
|
|
144
136
|
outdir: args.outdir,
|
|
145
137
|
fs: args.fs?.promises,
|
|
146
138
|
}));
|
|
147
|
-
previousCompilation = await compile({
|
|
148
|
-
fs: trackedFs,
|
|
139
|
+
state.previousCompilation = await compile({
|
|
149
140
|
previousCompilation: seededPrevious,
|
|
150
141
|
outputStructure,
|
|
142
|
+
isServer,
|
|
151
143
|
...withoutCleanOutdir(args),
|
|
152
144
|
cleanOutdir: false,
|
|
145
|
+
// after the args spread so a user-provided fs doesn't bypass
|
|
146
|
+
// the read tracking (trackedFs wraps args.fs when provided)
|
|
147
|
+
fs: trackedFs,
|
|
153
148
|
});
|
|
149
|
+
state.previousInputsDigest = await computeInputsDigest(state, args, outputStructure);
|
|
154
150
|
logger.success(`Compilation complete (${outputStructure})`);
|
|
155
151
|
}
|
|
156
152
|
catch (error) {
|
|
157
|
-
|
|
158
|
-
logger.
|
|
153
|
+
state.previousInputsDigest = undefined;
|
|
154
|
+
logger.error("Failed to compile project:", error.message);
|
|
155
|
+
logger.info("Please check your translation files for syntax errors.");
|
|
159
156
|
if (isProduction)
|
|
160
157
|
throw error;
|
|
161
158
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
});
|
|
159
|
+
finally {
|
|
160
|
+
// in any case add the files to watch
|
|
161
|
+
const targets = getWatchTargets(readFiles, { outdir: args.outdir });
|
|
162
|
+
for (const filePath of targets.files) {
|
|
163
|
+
this.addWatchFile(filePath);
|
|
164
|
+
}
|
|
165
|
+
for (const directoryPath of targets.directories) {
|
|
166
|
+
this.addWatchFile(directoryPath);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
async watchChange(path) {
|
|
171
|
+
const normalizedPath = nodeNormalizePath(path);
|
|
172
|
+
const targets = getWatchTargets(readFiles, { outdir: args.outdir });
|
|
173
|
+
if (targets.isIgnoredPath(normalizedPath)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const shouldCompile = targets.files.has(normalizedPath) ||
|
|
177
|
+
isPathWithinDirectories(normalizedPath, targets.directories);
|
|
178
|
+
if (shouldCompile === false) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
182
|
+
// default to locale-modules for development to speed up the dev server
|
|
183
|
+
// https://github.com/opral/inlang-paraglide-js/issues/486
|
|
184
|
+
const outputStructure = args.outputStructure ??
|
|
185
|
+
(isProduction ? "message-modules" : "locale-modules");
|
|
186
|
+
const previouslyReadFiles = new Set(readFiles);
|
|
187
|
+
try {
|
|
188
|
+
logger.info(`Re-compiling inlang project... File "${relative(process.cwd(), path)}" has changed.`);
|
|
189
|
+
// Clear readFiles to track fresh file reads
|
|
190
|
+
clearReadFiles();
|
|
191
|
+
state.previousCompilation = await compile({
|
|
192
|
+
previousCompilation: state.previousCompilation,
|
|
193
|
+
outputStructure,
|
|
194
|
+
isServer,
|
|
195
|
+
...withoutCleanOutdir(args),
|
|
196
|
+
cleanOutdir: false,
|
|
197
|
+
fs: trackedFs,
|
|
198
|
+
});
|
|
199
|
+
state.previousInputsDigest = await computeInputsDigest(state, args, outputStructure);
|
|
200
|
+
logger.success(`Re-compilation complete (${outputStructure})`);
|
|
201
|
+
// Add any new files to watch
|
|
202
|
+
const nextTargets = getWatchTargets(readFiles, { outdir: args.outdir });
|
|
203
|
+
for (const filePath of nextTargets.files) {
|
|
204
|
+
this.addWatchFile(filePath);
|
|
205
|
+
}
|
|
206
|
+
for (const directoryPath of nextTargets.directories) {
|
|
207
|
+
this.addWatchFile(directoryPath);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
clearReadFiles();
|
|
212
|
+
for (const filePath of previouslyReadFiles) {
|
|
213
|
+
readFiles.add(filePath);
|
|
214
|
+
}
|
|
215
|
+
// Reset compilation result on error
|
|
216
|
+
state.previousCompilation = undefined;
|
|
217
|
+
state.previousInputsDigest = undefined;
|
|
218
|
+
logger.warn("Failed to re-compile project:", e.message);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
vite: {
|
|
222
|
+
config: {
|
|
223
|
+
handler: () => {
|
|
224
|
+
isServer = "import.meta.env?.SSR ?? typeof window === 'undefined'";
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
configEnvironment: {
|
|
228
|
+
handler: () => {
|
|
229
|
+
isServer = "import.meta.env?.SSR ?? typeof window === 'undefined'";
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
webpack(compiler) {
|
|
234
|
+
compiler.options.resolve = {
|
|
235
|
+
...compiler.options.resolve,
|
|
236
|
+
fallback: {
|
|
237
|
+
...compiler.options.resolve?.fallback,
|
|
238
|
+
// https://stackoverflow.com/a/72989932
|
|
239
|
+
async_hooks: false,
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
compiler.hooks.beforeRun.tapPromise(PLUGIN_NAME, async () => {
|
|
243
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
244
|
+
// default to locale-modules for development to speed up the dev server
|
|
245
|
+
// https://github.com/opral/inlang-paraglide-js/issues/486
|
|
246
|
+
const outputStructure = args.outputStructure ??
|
|
247
|
+
(isProduction ? "message-modules" : "locale-modules");
|
|
248
|
+
try {
|
|
249
|
+
// Multi-compiler webpack setups (client + server) trigger
|
|
250
|
+
// beforeRun once per compiler — skip when inputs are unchanged.
|
|
251
|
+
if (state.previousCompilation && state.previousInputsDigest) {
|
|
252
|
+
const currentDigest = await computeInputsDigest(state, args, outputStructure);
|
|
253
|
+
if (currentDigest === state.previousInputsDigest) {
|
|
254
|
+
logger.info(`Compilation skipped — inputs unchanged (${outputStructure})`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const seededPrevious = state.previousCompilation ??
|
|
259
|
+
(await seedPreviousCompilationFromOutdir({
|
|
260
|
+
outdir: args.outdir,
|
|
261
|
+
fs: args.fs?.promises,
|
|
262
|
+
}));
|
|
263
|
+
state.previousCompilation = await compile({
|
|
264
|
+
previousCompilation: seededPrevious,
|
|
265
|
+
outputStructure,
|
|
266
|
+
...withoutCleanOutdir(args),
|
|
267
|
+
cleanOutdir: false,
|
|
268
|
+
fs: trackedFs,
|
|
269
|
+
});
|
|
270
|
+
state.previousInputsDigest = await computeInputsDigest(state, args, outputStructure);
|
|
271
|
+
logger.success(`Compilation complete (${outputStructure})`);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
state.previousInputsDigest = undefined;
|
|
275
|
+
logger.warn("Failed to compile project:", error.message);
|
|
276
|
+
logger.warn("Please check your translation files for syntax errors.");
|
|
277
|
+
if (isProduction)
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
};
|
|
165
284
|
//# sourceMappingURL=unplugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unplugin.js","sourceRoot":"","sources":["../../src/bundler-plugins/unplugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAA0B,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,OAAO,EACN,eAAe,EACf,eAAe,EACf,uBAAuB,GACvB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,iCAAiC,EAAE,MAAM,0CAA0C,CAAC;AAE7F,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;AAE5B;;GAEG;AACH,IAAI,QAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"unplugin.js","sourceRoot":"","sources":["../../src/bundler-plugins/unplugin.ts"],"names":[],"mappings":"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"}
|