Skip to content

Commit

Permalink
feat: add new package with vue extractor
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoffer Jahren committed Mar 31, 2023
1 parent f2961fc commit bc10f9d
Show file tree
Hide file tree
Showing 13 changed files with 375 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ node_modules/
.yalc/
yalc.lock
dist
build

npm-debug.log
yarn-error.log
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ module.exports = {
".*.js.snap$",
],
coverageReporters: ["lcov", "text"],

globalSetup: "./scripts/jest/setupTimezone.js",
projects: [
{
Expand Down Expand Up @@ -70,6 +69,7 @@ module.exports = {
"<rootDir>/packages/format-json",
"<rootDir>/packages/format-csv",
"<rootDir>/packages/message-utils",
"<rootDir>/packages/extractor-vue",
],
},
],
Expand Down
9 changes: 2 additions & 7 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"version": "4.0.0-next.4",
"packages": [
"packages/*"
],
"packages": ["packages/*"],
"npmClient": "yarn",
"useWorkspaces": true,
"command": {
Expand All @@ -19,10 +17,7 @@
]
},
"publish": {
"allowBranch": [
"main",
"next"
],
"allowBranch": ["main", "next"],
"ignoreChanges": [
"**/CHANGELOG.md",
"**/examples/*",
Expand Down
31 changes: 31 additions & 0 deletions packages/extractor-vue/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Vue extractor

This package contains a custom extractors that handles Vue files. It supports extracting messages from script and setup scripts.

## Installation

```sh
npm install @lingui/extractor-vue
```

## Usage

This custom extractor requires that you use typescript for your lingui configuration.

```ts
import { vueExtractor } from "@lingui/extractor-vue"
import babel from "@lingui/cli/api/extractors/babel"

const linguiConfig = {
locales: ["en", "nb"],
sourceLocale: "en",
catalogs: [
{
path: "<rootDir>/src/{locale}",
include: ["<rootDir>/src"],
},
],
extractors: [babel, vueExtractor],
}
export default linguiConfig
```
42 changes: 42 additions & 0 deletions packages/extractor-vue/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@lingui/extractor-vue",
"version": "4.0.0-next.4",
"description": "Custom vue extractor to be used with CLI tool",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"keywords": [
"cli",
"i18n",
"internationalization",
"i10n",
"localization",
"i9n",
"translation"
],
"repository": "lingui/js-lingui",
"bugs": "https://github.com/lingui/js-lingui/issues",
"license": "MIT",
"author": {
"name": "Christoffer Jahren",
"email": "christoffer@jahren.it"
},
"scripts": {
"build": "unbuild",
"stub": "unbuild --stub"
},
"engines": {
"node": ">=16.0.0"
},
"dependencies": {
"@babel/core": "^7.21.0",
"@lingui/cli": "^4.0.0-next.4",
"@lingui/conf": "^4.0.0-next.4",
"@vue/compiler-sfc": "^3.2.47"
},
"devDependencies": {
"@lingui/babel-plugin-extract-messages": "^4.0.0-next.4",
"unbuild": "^1.1.2"
},
"gitHead": "f2961fcb319265b08ddeda3aa2549d104fc4c6d4"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`vue extractor should extract from vue script 1`] = `
[
{
comment: undefined,
context: undefined,
id: SVG Title,
message: undefined,
},
{
comment: undefined,
context: undefined,
id: custom.id,
message: SVG description,
},
]
`;

exports[`vue extractor should extract from vue setup script 1`] = `
[
{
comment: undefined,
context: undefined,
id: Loading...,
message: undefined,
},
]
`;
15 changes: 15 additions & 0 deletions packages/extractor-vue/src/__test__/example-script-setup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<span role="progressbar" aria-valuenow="0" :aria-valuetext="ariaValueText" />
</template>

<script>
export default { name: "fButton" }
</script>

<script setup>
import { i18n } from "@lingui/core"
const props = {
ariaValueText: { type: String, default: i18n._("Loading...") },
}
</script>
28 changes: 28 additions & 0 deletions packages/extractor-vue/src/__test__/example-script.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="none"
viewBox="0 0 16 16"
>
<title>{{ svgTitle }}</title>
<desc>{{ svgDescription }}</desc>
</svg>
</template>

<script>
import { i18n } from "@lingui/core"
export default {
name: "fAffix",
setup(props) {
const svgTitle = i18n._("SVG Title")
const svgDescription = i18n._(
/*i18n*/ { id: "custom.id", message: "SVG description" }
)
return { svgTitle, svgDescription }
},
}
</script>
81 changes: 81 additions & 0 deletions packages/extractor-vue/src/__test__/extractor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { makeConfig } from "@lingui/conf"
import fs from "fs"
import path from "path"
import { vueExtractor } from "../vue-extractor"
import type { ExtractedMessage } from "@lingui/babel-plugin-extract-messages"

/**
* Remove origin from snapshot to avoid
* issues with snapshot tests failing on CI
* @param snapshot
*/
function removeOriginFromSnapshot(snapshot: ExtractedMessage[]) {
snapshot.forEach((entry) => {
if ("origin" in entry) {
delete entry.origin
}
})
}

describe("vue extractor", () => {
const linguiConfig = makeConfig({
locales: ["en", "nb"],
sourceLocale: "en",
rootDir: ".",
catalogs: [
{
path: "<rootDir>/{locale}",
include: ["<rootDir>"],
exclude: [],
},
],
extractorParserOptions: {
tsExperimentalDecorators: false,
flow: false,
},
})

it("should extract from vue script", async () => {
const filePath = path.resolve(__dirname, "example-script.vue")
const code = fs.readFileSync(filePath, "utf-8")

let messages: ExtractedMessage[] = []

await vueExtractor.extract(
"test.vue",
code,
(res) => {
messages.push(res)
},
{
linguiConfig,
}
)

removeOriginFromSnapshot(messages)

expect(messages).toMatchSnapshot()
})

it("should extract from vue setup script", async () => {
const filePath = path.resolve(__dirname, "example-script-setup.vue")
const code = fs.readFileSync(filePath, "utf-8")

let setupMessages: ExtractedMessage[] = []

await vueExtractor.extract(
"test.vue",
code,
(res) => {
setupMessages.push(res)
},
{
linguiConfig,
}
)

removeOriginFromSnapshot(setupMessages)

expect(setupMessages).toMatchSnapshot()
})
})
1 change: 1 addition & 0 deletions packages/extractor-vue/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { vueExtractor } from "./vue-extractor"
27 changes: 27 additions & 0 deletions packages/extractor-vue/src/vue-extractor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as vueCompiler from "@vue/compiler-sfc"
// @ts-expect-error issue with typings, will be fixed shortly
import babel from "@lingui/cli/api/extractors/babel"
import type { ExtractorCtx, ExtractorType } from "@lingui/conf"

export const vueExtractor: ExtractorType = {
match(filename: string) {
return filename.endsWith(".vue")
},
extract(
filename: string,
code: string,
onMessageExtracted,
ctx: ExtractorCtx
) {
const {
descriptor: { script, scriptSetup },
} = vueCompiler.parse(code, { filename, ignoreEmpty: true })

const finalCode = `${script?.content} ${scriptSetup?.content}`

return babel.extract(filename, finalCode ?? code, onMessageExtracted, {
sourcemaps: false,
...ctx,
})
},
}
7 changes: 5 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@
"skipLibCheck": true,
"target": "es2017",
"paths": {
"@lingui/babel-plugin-extract-messages": ["./packages/babel-plugin-extract-messages/src"],
"@lingui/babel-plugin-extract-messages": [
"./packages/babel-plugin-extract-messages/src"
],
"@lingui/core": ["./packages/core/src"],
"@lingui/message-utils/*": ["./packages/message-utils/src/*"],
"@lingui/cli/api": ["./packages/cli/src/api"],
"@lingui/react": ["./packages/react/src"],
"@lingui/conf": ["./packages/conf/src"],
"@lingui/macro": ["./packages/macro/src"],
"@lingui/format-po": ["./packages/format-po/src/po.ts"],
"@lingui/format-json": ["./packages/format-json/src/json.ts"]
"@lingui/format-json": ["./packages/format-json/src/json.ts"],
"@lingui/extractor-vue": ["./packages/extractor-vue/src"]
}
},
"exclude": [
Expand Down
Loading

0 comments on commit bc10f9d

Please sign in to comment.