Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changeset/legacy-compiler-deprecation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@lingo.dev/_compiler": patch
---

Add deprecation warnings throughout legacy compiler

The legacy compiler (`@lingo.dev/_compiler`) now shows deprecation warnings when used.
Users are encouraged to migrate to the new compiler (`@lingo.dev/compiler`).

Changes:
- Added runtime deprecation warnings in `next()`, `vite()`, and the Turbopack loader
- Added `@deprecated` JSDoc tags to all public APIs
- Updated package README with migration guide and examples
- The deprecation warning includes information about new compiler features and migration guide link
7 changes: 7 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(pnpm build:*)"
]
}
Comment on lines +1 to +6
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and its git status
git ls-files | grep -i settings
git status --ignored | grep -i settings

Repository: lingodotdev/lingo.dev

Length of output: 153


🏁 Script executed:

# Explore the .claude directory structure
ls -la .claude/ 2>/dev/null || echo "Directory may not exist or is empty"
find . -name "*.claude" -o -name ".claude" -type d 2>/dev/null
git ls-files | grep "\.claude"

Repository: lingodotdev/lingo.dev

Length of output: 517


🏁 Script executed:

# Check for similar local/config files in repo
git ls-files | grep -E "\.(local|local\.json|config)$"
cat .gitignore 2>/dev/null | grep -E "(\.local|\.claude|settings)"

Repository: lingodotdev/lingo.dev

Length of output: 164


🏁 Script executed:

# Search for documentation about settings or permissions
fd -e md -e txt | xargs grep -l "\.claude\|settings.*local" 2>/dev/null | head -10
rg "pnpm build" --type md --type txt 2>/dev/null

Repository: lingodotdev/lingo.dev

Length of output: 131


🏁 Script executed:

# Check if .claude is in .gitignore
cat .gitignore | grep -E "\.claude|/\.claude"

Repository: lingodotdev/lingo.dev

Length of output: 47


🏁 Script executed:

# Check the content of the actual file
cat .claude/settings.local.json

Repository: lingodotdev/lingo.dev

Length of output: 139


🏁 Script executed:

# Look for any documentation or README in .claude directory
find .claude -type f -name "*.md" -o -name "README*" | xargs cat 2>/dev/null

Repository: lingodotdev/lingo.dev

Length of output: 14650


🏁 Script executed:

# Search for any references to the permissions system or settings
rg "permissions|allow|Bash\(" --type json --type md --type ts 2>/dev/null | head -20

Repository: lingodotdev/lingo.dev

Length of output: 1788


Verify the breadth of the Bash permission allowlist.

The wildcard pnpm build:* permits any build subcommand and arguments—confirm this scope is intentional for Claude IDE integration.

🤖 Prompt for AI Agents
In @.claude/settings.local.json around lines 1 - 6, The permissions.allow entry
currently uses the broad wildcard "Bash(pnpm build:*)" which permits any pnpm
build subcommand and arguments; update this to the minimal required command(s)
under the permissions.allow array (e.g., replace or add explicit entries instead
of the wildcard) or document/confirm the intended scope so Claude IDE only gets
the exact pnpm build:... subcommands needed; locate the permissions.allow JSON
key and the string "Bash(pnpm build:*)" and either constrain it to specific
commands or add justification in the settings.

}
2 changes: 2 additions & 0 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@

**Lingo.dev Compiler** is a free, open-source compiler middleware, designed to make any React app multilingual at build time without requiring any changes to the existing React components.

> **Note:** If you're using the legacy compiler (`@lingo.dev/_compiler`), please migrate to `@lingo.dev/compiler`. The legacy compiler is deprecated and will be removed in a future release.

Install once:

```bash
Expand Down
93 changes: 90 additions & 3 deletions packages/compiler/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,92 @@
# Lingo.dev Compiler
# Lingo.dev Compiler (Legacy)

**Lingo.dev Compiler** is a free, open-source compiler middleware, that makes React apps multilingual at build time without requiring any changes to the existing React components.
> **DEPRECATED:** This package (`@lingo.dev/_compiler`) is deprecated. Please migrate to `@lingo.dev/compiler` (the new compiler).

Documentation: https://lingo.dev/compiler
## Migration

Install the new compiler:

```bash
npm install @lingo.dev/compiler
```

Update your configuration:

**Next.js (before):**
```ts
import lingoCompiler from "@lingo.dev/_compiler";
import type { NextConfig } from "next";

const nextConfig: NextConfig = {};

export default lingoCompiler.next({
sourceRoot: "app",
models: "lingo.dev",
})(nextConfig);
```

**Next.js (after):**
```ts
import type { NextConfig } from "next";
import { withLingo } from "@lingo.dev/compiler/next";

const nextConfig: NextConfig = {};

export default async function (): Promise<NextConfig> {
return await withLingo(nextConfig, {
sourceLocale: "en",
targetLocales: ["es", "fr"],
models: "lingo.dev",
});
}
```

**Vite (before):**
```ts
import { defineConfig, type UserConfig } from "vite";
import react from "@vitejs/plugin-react";
import lingoCompiler from "@lingo.dev/_compiler";

const viteConfig: UserConfig = {
plugins: [react()],
};

export default defineConfig(() =>
lingoCompiler.vite({
models: "lingo.dev",
})(viteConfig)
);
```

**Vite (after):**
```ts
import { defineConfig, type UserConfig } from "vite";
import react from "@vitejs/plugin-react";
import { withLingo } from "@lingo.dev/compiler/vite";

const viteConfig: UserConfig = {
plugins: [react()],
};

export default defineConfig(async () =>
await withLingo(viteConfig, {
sourceLocale: "en",
targetLocales: ["es", "fr"],
models: "lingo.dev",
})
);
```

## New Compiler Features

The new compiler (`@lingo.dev/compiler`) offers:

- Advanced virtual module system for better code splitting
- Built-in development translation server
- Pluralization detection with ICU MessageFormat support
- Improved metadata management for better caching
- Thread-safe concurrent build support

## Documentation

Full documentation: https://lingo.dev/compiler
Comment on lines +90 to +92
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Format URL as markdown link.

The bare URL should be formatted as a proper markdown link for better accessibility and consistency with markdown best practices.

📝 Proposed fix
 ## Documentation

-Full documentation: https://lingo.dev/compiler
+Full documentation: [https://lingo.dev/compiler](https://lingo.dev/compiler)
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

92-92: Bare URL used

(MD034, no-bare-urls)

🤖 Prompt for AI Agents
In `@packages/compiler/README.md` around lines 90 - 92, Update the "##
Documentation" section to replace the bare URL with a markdown link: change the
line containing "Full documentation: https://lingo.dev/compiler" so it uses link
syntax (e.g., "Full documentation:
[https://lingo.dev/compiler](https://lingo.dev/compiler)" or "Full
documentation: [Lingo Compiler Docs](https://lingo.dev/compiler)") so the URL is
properly formatted as a markdown link.

23 changes: 23 additions & 0 deletions packages/compiler/src/_deprecation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const DEPRECATION_WARNING = `
⚠️ DEPRECATION WARNING: @lingo.dev/_compiler is deprecated.
Please migrate to @lingo.dev/compiler (the new compiler).

The new compiler offers:
• Advanced virtual module system for better code splitting
• Built-in development translation server
• Pluralization detection with ICU MessageFormat support
• Improved metadata management for better caching
• Thread-safe concurrent build support

Migration guide: https://lingo.dev/compiler

This legacy compiler will be removed in a future release.
`;

let deprecationWarningShown = false;

export function showDeprecationWarning() {
if (deprecationWarningShown) return;
deprecationWarningShown = true;
console.warn(DEPRECATION_WARNING);
}
6 changes: 6 additions & 0 deletions packages/compiler/src/_loader-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import { parseParametrizedModuleId } from "./utils/module-params";

/**
* Loads a dictionary for a specific locale
*
* @deprecated This function is part of the legacy compiler (@lingo.dev/_compiler).
* Please migrate to @lingo.dev/compiler. See https://lingo.dev/compiler
*/
export async function loadDictionary(options: {
resourcePath: string;
Expand Down Expand Up @@ -79,6 +82,9 @@ export async function loadDictionary(options: {

/**
* Transforms component code
*
* @deprecated This function is part of the legacy compiler (@lingo.dev/_compiler).
* Please migrate to @lingo.dev/compiler. See https://lingo.dev/compiler
*/
export function transformComponent(options: {
code: string;
Expand Down
58 changes: 51 additions & 7 deletions packages/compiler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from "./utils/llm-api-key";
import { isRunningInCIOrDocker } from "./utils/env";
import { providerDetails } from "./lib/lcp/api/provider-details";
import { showDeprecationWarning } from "./_deprecation";
import { loadDictionary, transformComponent } from "./_loader-utils";
import trackEvent from "./utils/observability";

Expand Down Expand Up @@ -61,6 +62,7 @@ function sendBuildEvent(framework: string, config: any, isDev: boolean) {

const unplugin = createUnplugin<Partial<typeof defaultParams> | undefined>(
(_params, _meta) => {
showDeprecationWarning();
console.log("ℹ️ Starting Lingo.dev compiler...");

const params = _.defaults(_params, defaultParams);
Expand Down Expand Up @@ -155,13 +157,32 @@ export default {
/**
* Initializes Lingo.dev Compiler for Next.js (App Router).
*
* @deprecated This legacy compiler is deprecated. Please migrate to `@lingo.dev/compiler`.
* See migration guide at https://lingo.dev/compiler
*
* @param compilerParams - The compiler parameters.
*
* @returns The Next.js configuration.
*
* @example Configuration for Next.js's default template
* @example New compiler usage (recommended):
* ```ts
* import lingoCompiler from "lingo.dev/compiler";
* import type { NextConfig } from "next";
* import { withLingo } from "@lingo.dev/compiler/next";
*
* const nextConfig: NextConfig = {};
*
* export default async function (): Promise<NextConfig> {
* return await withLingo(nextConfig, {
* sourceLocale: "en",
* targetLocales: ["es", "fr"],
* models: "lingo.dev",
* });
* }
* ```
*
* @example Legacy compiler usage (deprecated):
* ```ts
* import lingoCompiler from "@lingo.dev/_compiler";
* import type { NextConfig } from "next";
*
* const nextConfig: NextConfig = {
Expand All @@ -184,6 +205,7 @@ export default {
},
) =>
(nextConfig: any = {}): NextConfig => {
showDeprecationWarning();
const mergedParams = _.merge(
{},
defaultParams,
Expand Down Expand Up @@ -272,17 +294,38 @@ export default {
/**
* Initializes Lingo.dev Compiler for Vite.
*
* @deprecated This legacy compiler is deprecated. Please migrate to `@lingo.dev/compiler`.
* See migration guide at https://lingo.dev/compiler
*
* @param compilerParams - The compiler parameters.
*
* @returns The Vite configuration.
*
* @example Configuration for Vite's "react-ts" template
* @example New compiler usage (recommended):
* ```ts
* import { defineConfig, type UserConfig } from "vite";
* import react from "@vitejs/plugin-react";
* import { withLingo } from "@lingo.dev/compiler/vite";
*
* const viteConfig: UserConfig = {
* plugins: [react()],
* };
*
* export default defineConfig(async () =>
* await withLingo(viteConfig, {
* sourceLocale: "en",
* targetLocales: ["es", "fr"],
* models: "lingo.dev",
* })
* );
* ```
*
* @example Legacy Vite configuration (deprecated):
* ```ts
* import { defineConfig, type UserConfig } from "vite";
* import react from "@vitejs/plugin-react";
* import lingoCompiler from "lingo.dev/compiler";
* import lingoCompiler from "@lingo.dev/_compiler";
*
* // https://vite.dev/config/
* const viteConfig: UserConfig = {
* plugins: [react()],
* };
Expand All @@ -294,11 +337,11 @@ export default {
* );
* ```
*
* @example Configuration for React Router's default template
* @example Legacy React Router configuration (deprecated):
* ```ts
* import { reactRouter } from "@react-router/dev/vite";
* import tailwindcss from "@tailwindcss/vite";
* import lingoCompiler from "lingo.dev/compiler";
* import lingoCompiler from "@lingo.dev/_compiler";
* import { defineConfig, type UserConfig } from "vite";
* import tsconfigPaths from "vite-tsconfig-paths";
*
Expand All @@ -315,6 +358,7 @@ export default {
* ```
*/
vite: (compilerParams?: Partial<typeof defaultParams>) => (config: any) => {
showDeprecationWarning();
const mergedParams = _.merge(
{},
defaultParams,
Expand Down
6 changes: 6 additions & 0 deletions packages/compiler/src/lingo-turbopack-loader.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { showDeprecationWarning } from "./_deprecation";
import { loadDictionary, transformComponent } from "./_loader-utils";

/**
* @deprecated This loader is part of the legacy compiler. Please migrate to @lingo.dev/compiler.
* See migration guide at https://lingo.dev/compiler
*/
// This loader handles component transformations and dictionary generation
export default async function (this: any, source: string) {
showDeprecationWarning();
const callback = this.async();
const params = this.getOptions();
const isDev = process.env.NODE_ENV !== "production";
Expand Down