-
Notifications
You must be signed in to change notification settings - Fork 380
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement @lingui/vite-plugin (#1306)
* implement @lingui/vite-plugin * chore: build node package with tsc to produce typings
- Loading branch information
1 parent
6f0a48c
commit db5d3c3
Showing
18 changed files
with
476 additions
and
6 deletions.
There are no files selected for viewing
File renamed without changes.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
[![License][badge-license]][license] | ||
[![Version][badge-version]][package] | ||
[![Downloads][badge-downloads]][package] | ||
|
||
# @lingui/vite-plugin | ||
|
||
> Vite plugin which compiles on the fly the .po files for auto-refreshing. In summary, `lingui compile` command isn't required when using this plugin | ||
`@lingui/vite-plugin` is part of [LinguiJS][linguijs]. See the [documentation][documentation] for all information, tutorials and examples. | ||
|
||
## Installation | ||
|
||
```sh | ||
npm install --save-dev @lingui/vite-plugin | ||
# yarn add --dev @lingui/vite-plugin | ||
``` | ||
|
||
## Usage | ||
|
||
### Via `vite.config.ts` | ||
|
||
```ts | ||
import { UserConfig } from 'vite'; | ||
import lingui from '@lingui/vite-plugin' | ||
|
||
const config: UserConfig = { | ||
plugins: [lingui()] | ||
} | ||
``` | ||
|
||
### Then in Vite-processed code: | ||
|
||
```ts | ||
const { messages } = await import(`./locales/${language}.po`); | ||
``` | ||
> See Vite's official documentation for more info about Vite dynamic imports | ||
> https://vitejs.dev/guide/features.html#dynamic-import | ||
|
||
## License | ||
|
||
[MIT][license] | ||
|
||
[license]: https://github.com/lingui/js-lingui/blob/main/LICENSE | ||
[linguijs]: https://github.com/lingui/js-lingui | ||
[documentation]: https://lingui.dev/ | ||
[package]: https://www.npmjs.com/package/@lingui/vite-plugin | ||
[badge-downloads]: https://img.shields.io/npm/dw/@lingui/vite-plugin.svg | ||
[badge-version]: https://img.shields.io/npm/v/@lingui/vite-plugin.svg | ||
[badge-license]: https://img.shields.io/npm/l/@lingui/vite-plugin.svg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from "./src" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "@lingui/vite-plugin", | ||
"version": "3.16.1", | ||
"description": "Vite plugin for Lingui message catalogs", | ||
"main": "./build/index.js", | ||
"types": "./build/index.d.ts", | ||
"license": "MIT", | ||
"keywords": [ | ||
"vite-plugin", | ||
"i18n", | ||
"vite", | ||
"linguijs", | ||
"internationalization", | ||
"i10n", | ||
"localization", | ||
"i9n", | ||
"translation" | ||
], | ||
"scripts": { | ||
"build": "rimraf ./build && tsc" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/lingui/js-lingui.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/lingui/js-lingui/issues" | ||
}, | ||
"engines": { | ||
"node": ">=14.0.0" | ||
}, | ||
"dependencies": { | ||
"@lingui/cli": "^3.16.1", | ||
"@lingui/conf": "^3.16.1" | ||
}, | ||
"devDependencies": { | ||
"vite": "3.2.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { getConfig } from '@lingui/conf'; | ||
import { createCompiledCatalog, getCatalogs, getCatalogForFile } from '@lingui/cli/api'; | ||
import path from 'path'; | ||
import type { Plugin } from 'vite'; | ||
|
||
const fileRegex = /\.(po)$/; | ||
|
||
type LinguiConfigOpts = { | ||
cwd?: string; | ||
configPath?: string; | ||
skipValidation?: boolean; | ||
} | ||
|
||
export default function lingui(linguiConfig: LinguiConfigOpts = {}): Plugin { | ||
const config = getConfig(linguiConfig); | ||
|
||
return { | ||
name: 'vite-plugin-lingui', | ||
|
||
transform(src, id) { | ||
if (fileRegex.test(id)) { | ||
const catalogRelativePath = path.relative(config.rootDir, id); | ||
|
||
const fileCatalog = getCatalogForFile( | ||
catalogRelativePath, | ||
getCatalogs(config), | ||
); | ||
|
||
const { locale, catalog } = fileCatalog; | ||
const catalogs = catalog.readAll(); | ||
|
||
const messages = Object.keys(catalogs[locale]).reduce((acc, key) => { | ||
acc[key] = catalog.getTranslation(catalogs, locale, key, { | ||
fallbackLocales: config.fallbackLocales, | ||
sourceLocale: config.sourceLocale, | ||
}); | ||
|
||
return acc; | ||
}, {}); | ||
|
||
const compiled = createCompiledCatalog(locale, messages, { | ||
strict: false, | ||
namespace: 'es', | ||
pseudoLocale: config.pseudoLocale, | ||
}); | ||
|
||
return { | ||
code: compiled, | ||
map: null, // provide source map if available | ||
}; | ||
} | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"locales": ["en", "cs"], | ||
"catalogs": [{ | ||
"path": "<rootDir>/locale/{locale}/messages" | ||
}], | ||
"format": "po" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`vite-plugin should return compiled catalog 1`] = ` | ||
Object { | ||
code: /*eslint-disable*/export const messages=JSON.parse("{\\"Hello World\\":\\"Hello World\\",\\"My name is {name}\\":[\\"My name is \\",[\\"name\\"]]}");, | ||
map: null, | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import path from "path" | ||
import vitePlugin from "../src" | ||
|
||
describe("vite-plugin", () => { | ||
it("should return compiled catalog", async() => { | ||
const p = vitePlugin({ | ||
configPath: path.resolve( | ||
__dirname, | ||
".linguirc", | ||
), | ||
}) | ||
const result = await (p.transform as any)('', path.join(__dirname, "locale", "en", "messages.po")) | ||
expect(result).toMatchSnapshot() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
msgid "Hello World" | ||
msgstr "Hello World" | ||
|
||
msgid "My name is {name}" | ||
msgstr "My name is {name}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
msgid "Hello World" | ||
msgstr "Hello World" | ||
|
||
msgid "My name is {name}" | ||
msgstr "My name is {name}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"target": "ES2019", | ||
"sourceMap": true, | ||
"noEmit": false, | ||
"declaration": true, | ||
"outDir": "./build", | ||
"esModuleInterop": true, | ||
"resolveJsonModule": true | ||
}, | ||
"include": [ | ||
"src" | ||
], | ||
"exclude": [ | ||
"node_modules" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import {exec} from "child_process" | ||
import {BundleDef} from "./bundles" | ||
import chalk from "chalk" | ||
import ora from "ora" | ||
|
||
function asyncExecuteCommand(command: string) { | ||
return new Promise((resolve, reject) => | ||
exec(command, (error, stdout, stderr) => { | ||
stdout = stdout.trim() | ||
stderr = stderr.trim() | ||
|
||
if (error) { | ||
reject({stdout, stderr}) | ||
return | ||
} | ||
resolve({stdout, stderr}) | ||
}) | ||
) | ||
} | ||
|
||
export default async function(bundle: BundleDef) { | ||
const logKey = chalk.white.bold(bundle.packageName) | ||
|
||
const spinner = ora(logKey).start() | ||
|
||
try { | ||
await asyncExecuteCommand(bundle.cmd); | ||
} catch (error) { | ||
spinner.fail(error.stdout) | ||
process.exit(1); | ||
} | ||
|
||
spinner.succeed() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Vite Plugin | ||
|
||
It's a good practice to use compiled message catalogs during development. However, running [`compile`](/docs/ref/cli.md#compile) everytime messages are changed soon becomes tedious. | ||
|
||
`@lingui/vite-plugin` is a Vite plugin, which compiles `.po` catalogs on the fly: | ||
|
||
## Installation | ||
|
||
Install `@lingui/vite-plugin` as a development dependency: | ||
|
||
```bash npm2yarn | ||
npm install --save-dev @lingui/vite-plugin | ||
``` | ||
|
||
## Usage | ||
|
||
Simply add `@lingui/vite-plugin` inside your `vite.config.ts`: | ||
|
||
```ts title="vite.config.ts" | ||
import { UserConfig } from 'vite'; | ||
import lingui from '@lingui/vite-plugin' | ||
|
||
const config: UserConfig = { | ||
plugins: [lingui()] | ||
} | ||
``` | ||
|
||
Then in your code all you need is to use [dynamic imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports) to load only necessary catalog. Extension is mandatory. | ||
|
||
```ts | ||
export async function dynamicActivate(locale: string) { | ||
const { messages } = await import(`./locales/${locale}.po`); | ||
|
||
i18n.load(locale, messages) | ||
i18n.activate(locale) | ||
} | ||
``` | ||
|
||
See the [guide about dynamic loading catalogs](/docs/guides/dynamic-loading-catalogs.md) for more info. | ||
|
||
See [Vite's official documentation](https://vitejs.dev/guide/features.html#dynamic-import) for more info about Vite dynamic imports. | ||
|
||
:::note | ||
You also need to set up [babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros) to support [macros](/docs/ref/macro.md). | ||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
db5d3c3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
js-lingui – ./
js-lingui.vercel.app
js-lingui-lingui.vercel.app
js-lingui-git-main-lingui.vercel.app
lingui.dev
lingui.js.org