Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
08635c9
feat: support compile with multi thread
Zxilly Aug 14, 2025
e5a9f2a
docs: add experimental.multiThread
Zxilly Aug 15, 2025
9860755
feat: support multi thread extraction
Zxilly Aug 18, 2025
caff0ef
fix: type anno
Zxilly Aug 18, 2025
2b6df75
fix: type lint
Zxilly Aug 18, 2025
c8b01b5
feat: apply limit to read
Zxilly Aug 19, 2025
49dbd7d
fix: use utils readFile instead
Zxilly Aug 19, 2025
374d6c3
feat(cli): revert experimental multithreading, support custom extractors
timofei-iatsenko Aug 19, 2025
6e73172
prettier
timofei-iatsenko Aug 19, 2025
5aa1c1d
revert package.json changes
timofei-iatsenko Aug 19, 2025
b30788b
extract seqeuntially if not multithreading
timofei-iatsenko Aug 19, 2025
ec8db78
revert compile multithreading
timofei-iatsenko Aug 19, 2025
2537a70
feat(cli): add multithreading for lingui compile
timofei-iatsenko Aug 20, 2025
e75e9e8
control compile workers from cli arguments
timofei-iatsenko Aug 20, 2025
903179f
control multithreading in extract using cli args, add multithreading …
timofei-iatsenko Aug 21, 2025
b0f48e7
optimize resource loading in workers
timofei-iatsenko Aug 21, 2025
cfcde65
add multithreading for experimental extractor
timofei-iatsenko Aug 21, 2025
3393fe4
revert readfile queuing
timofei-iatsenko Aug 21, 2025
921f154
fix build
timofei-iatsenko Aug 22, 2025
4013acb
sort entries in experimental extractor stats
timofei-iatsenko Aug 22, 2025
d07869c
satisfy linter
timofei-iatsenko Aug 22, 2025
0f293a8
satisfy linter
timofei-iatsenko Aug 22, 2025
1db1397
improve coverage
timofei-iatsenko Aug 22, 2025
a5b5236
fix cli argument params
timofei-iatsenko Aug 22, 2025
dad50cb
add pnpm to contributing guide
timofei-iatsenko Aug 22, 2025
8ff1951
streamline --workers argument in cli
timofei-iatsenko Aug 22, 2025
2793f28
streamline --workers argument in cli
timofei-iatsenko Aug 22, 2025
4d9cb4c
cli logging fix
timofei-iatsenko Aug 22, 2025
427b233
pass pool size arguments correctly
timofei-iatsenko Aug 22, 2025
47191be
show elapsed time in cli commands
timofei-iatsenko Aug 22, 2025
d9bea15
add docs
timofei-iatsenko Aug 22, 2025
60c03ab
package.json
timofei-iatsenko Aug 22, 2025
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
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ There are two documented ways to do this: first is a generic way described in th
YARN_NPM_REGISTRY_SERVER=http://0.0.0.0:4873/ yarn up "@lingui/*"
```

with PNPM:

```sh
pnpm -r up "@lingui/*" --latest --registry=http://0.0.0.0:4873/
```

5. After you make some changes, you need to run the same process. (Releasing + yarn upgrade)

6. When finished testing, restore default registry (only for NPM)
Expand Down
8 changes: 6 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,23 @@
"esbuild": "^0.25.1",
"glob": "^11.0.0",
"micromatch": "^4.0.7",
"ms": "^2.1.3",
"normalize-path": "^3.0.0",
"ora": "^5.1.0",
"picocolors": "^1.1.1",
"pofile": "^1.1.4",
"pseudolocale": "^2.0.0",
"source-map": "^0.8.0-beta.0"
"source-map": "^0.8.0-beta.0",
"threads": "^1.7.0"
},
"devDependencies": {
"@lingui/jest-mocks": "*",
"@types/convert-source-map": "^2.0.0",
"@types/micromatch": "^4.0.1",
"@types/ms": "^2.1.0",
"@types/normalize-path": "^3.0.0",
"mock-fs": "^5.2.0",
"mockdate": "^3.0.5"
"mockdate": "^3.0.5",
"ts-node": "^10.9.2"
}
}
7 changes: 7 additions & 0 deletions packages/cli/src/api/ProgramExit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export class ProgramExit extends Error {
constructor() {
super()

this.name = "ProgramExit"
}
}
8 changes: 4 additions & 4 deletions packages/cli/src/api/catalog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import mockFs from "mock-fs"
import { mockConsole } from "@lingui/jest-mocks"
import { LinguiConfig, makeConfig } from "@lingui/conf"

import { Catalog, cleanObsolete, order } from "./catalog"
import { Catalog, cleanObsolete, order, writeCompiled } from "./catalog"
import { createCompiledCatalog } from "./compile"

import {
Expand Down Expand Up @@ -688,9 +688,9 @@ describe("writeCompiled", () => {
async ({ namespace, extension }) => {
const { source } = createCompiledCatalog("en", {}, { namespace })
// Test that the file extension of the compiled catalog is `.mjs`
expect(await catalog.writeCompiled("en", source, namespace)).toMatch(
extension
)
expect(
await writeCompiled(catalog.path, "en", source, namespace)
).toMatch(extension)
}
)
})
103 changes: 54 additions & 49 deletions packages/cli/src/api/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import normalize from "normalize-path"
import { LinguiConfigNormalized, OrderBy } from "@lingui/conf"

import { FormatterWrapper } from "./formats"
import { CliExtractOptions } from "../lingui-extract"
import { CliExtractTemplateOptions } from "../lingui-extract-template"
import { CompiledCatalogNamespace } from "./compile"
import {
getTranslationsForCatalog,
GetTranslationsOptions,
TranslationMissingEvent,
} from "./catalog/getTranslationsForCatalog"
import { mergeCatalog } from "./catalog/mergeCatalog"
import { extractFromFiles } from "./catalog/extractFromFiles"
import {
extractFromFiles,
extractFromFilesWithWorkerPool,
} from "./catalog/extractFromFiles"
import {
isDirectory,
makePathRegexSafe,
Expand All @@ -24,16 +24,24 @@ import {
writeFile,
} from "./utils"
import { AllCatalogsType, CatalogType, ExtractedCatalogType } from "./types"
import { ExtractWorkerPool } from "./extractWorkerPool"

const LOCALE = "{locale}"
const LOCALE_SUFFIX_RE = /\{locale\}.*$/

export type MakeOptions = CliExtractOptions & {
export type MakeOptions = {
files?: string[]
clean: boolean
overwrite: boolean
locale: string[]
orderBy?: OrderBy
workerPool?: ExtractWorkerPool
}

export type MakeTemplateOptions = CliExtractTemplateOptions & {
export type MakeTemplateOptions = {
files?: string[]
orderBy?: OrderBy
workerPool?: ExtractWorkerPool
}

export type MergeOptions = {
Expand Down Expand Up @@ -81,7 +89,7 @@ export class Catalog {

async make(options: MakeOptions): Promise<AllCatalogsType | false> {
const [nextCatalog, prevCatalogs] = await Promise.all([
this.collect({ files: options.files }),
this.collect({ files: options.files, workerPool: options.workerPool }),
this.readAll(),
])

Expand Down Expand Up @@ -116,7 +124,10 @@ export class Catalog {
async makeTemplate(
options: MakeTemplateOptions
): Promise<CatalogType | false> {
const catalog = await this.collect({ files: options.files })
const catalog = await this.collect({
files: options.files,
workerPool: options.workerPool,
})
if (!catalog) return false
const sorted = order(options.orderBy, catalog as CatalogType)

Expand All @@ -128,7 +139,7 @@ export class Catalog {
* Collect messages from source paths. Return a raw message catalog as JSON.
*/
async collect(
options: { files?: string[] } = {}
options: { files?: string[]; workerPool?: ExtractWorkerPool } = {}
): Promise<ExtractedCatalogType | undefined> {
let paths = this.sourcePaths
if (options.files) {
Expand All @@ -140,6 +151,14 @@ export class Catalog {
paths = paths.filter((path: string) => regex.test(normalize(path)))
}

if (options.workerPool) {
return await extractFromFilesWithWorkerPool(
options.workerPool,
paths,
this.config
)
}

return await extractFromFiles(paths, this.config)
}

Expand Down Expand Up @@ -181,23 +200,8 @@ export class Catalog {
)
}

async getTranslations(
locale: string,
options: Omit<GetTranslationsOptions, "onMissing">
) {
const missing: TranslationMissingEvent[] = []

const messages = await getTranslationsForCatalog(this, locale, {
...options,
onMissing: (event) => {
missing.push(event)
},
})

return {
missing,
messages,
}
async getTranslations(locale: string, options: GetTranslationsOptions) {
return await getTranslationsForCatalog(this, locale, options)
}

async write(
Expand All @@ -217,29 +221,6 @@ export class Catalog {
await this.format.write(filename, messages, undefined)
}

async writeCompiled(
locale: string,
compiledCatalog: string,
namespace?: CompiledCatalogNamespace
) {
let ext: string
switch (namespace) {
case "es":
ext = "mjs"
break
case "ts":
case "json":
ext = namespace
break
default:
ext = "js"
}

const filename = `${replacePlaceholders(this.path, { locale })}.${ext}`
await writeFile(filename, compiledCatalog)
return filename
}

async read(locale: string): Promise<CatalogType> {
return await this.format.read(this.getFilename(locale), locale)
}
Expand Down Expand Up @@ -364,6 +345,30 @@ function orderByOrigin<T extends ExtractedCatalogType>(messages: T): T {
}, {} as T)
}

export async function writeCompiled(
path: string,
locale: string,
compiledCatalog: string,
namespace?: CompiledCatalogNamespace
) {
let ext: string
switch (namespace) {
case "es":
ext = "mjs"
break
case "ts":
case "json":
ext = namespace
break
default:
ext = "js"
}

const filename = `${replacePlaceholders(path, { locale })}.${ext}`
await writeFile(filename, compiledCatalog)
return filename
}

export function orderByMessage<T extends ExtractedCatalogType>(messages: T): T {
// hardcoded en-US locale to have consistent sorting
// @see https://github.com/lingui/js-lingui/pull/1808
Expand Down
Loading
Loading