Skip to content

Commit

Permalink
add vue-vite-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
timofei-iatsenko committed Jun 27, 2024
1 parent 8ddc0b1 commit effd2c0
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 36 deletions.
19 changes: 18 additions & 1 deletion packages/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@
"default": "./dist/extractor/index.mjs"
}
},
"./vite-plugin": {
"require": {
"types": "./dist/vite-plugin/index.d.cts",
"default": "./dist/vite-plugin/index.cjs"
},
"import": {
"types": "./dist/vite-plugin/index.d.mts",
"default": "./dist/vite-plugin/index.mjs"
}
},
"./package.json": "./package.json"
},
"files": [
Expand All @@ -87,13 +97,20 @@
"@lingui/cli": "4.8.0-next.1",
"@lingui/core": "4.8.0-next.1",
"@lingui/message-utils": "4.8.0-next.1",
"@lingui/vite-plugin": "4.8.0-next.1",
"@vue/compiler-core": "^3.3.4",
"@vue/compiler-sfc": "^3.3.4",
"vue": "^3.3.4"
},
"peerDependencies": {
"@vitejs/plugin-vue": "*",
"vite": "^3 || ^4 || ^5.0.9"
},
"devDependencies": {
"@lingui/conf": "4.8.0-next.1",
"@types/babel__core": "^7.20.5",
"unbuild": "2.0.0"
"@vitejs/plugin-vue": "^5.0.5",
"unbuild": "2.0.0",
"vite": "4.1.4"
}
}
1 change: 0 additions & 1 deletion packages/vue/src/compiler/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { babelMacros } from "./babel-macros"
export { transformer } from "./transformer"
7 changes: 4 additions & 3 deletions packages/vue/src/compiler/transformTrans.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
createSimpleExpression,
type ElementNode,
type TransformContext,
NodeTypes,
ConstantTypes,
ElementTypes,
Expand Down Expand Up @@ -133,7 +132,9 @@ function convertLoc(

export function transformTrans(
node: ElementNode,
transformContext: TransformContext
options: {
stripNonEssentialProps?: boolean
}
) {
const loc = node.loc
const tokens = tokenizeTrans(
Expand All @@ -144,7 +145,7 @@ export function transformTrans(
}

return identifier.name === macro
}, false)
}, !!options.stripNonEssentialProps)
)

const messageFormat = new ICUMessageFormat()
Expand Down
9 changes: 6 additions & 3 deletions packages/vue/src/compiler/transformVt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ function createLinguiSimpleExpression(
)
}

function createVueMacroContext() {
function createVueMacroContext(options: { stripNonEssentialProps?: boolean }) {
return createMacroJsContext((identifier, macro) => {
if (macro === JsMacroName.t) {
return identifier.name === "vt"
}

return identifier.name === macro
}, false)
}, !!options?.stripNonEssentialProps)
}

export function tokenizeAsChoiceComponentOrUndefined(
Expand Down Expand Up @@ -74,8 +74,11 @@ export function tokenizeAsLinguiTemplateLiteralOrUndefined(

export function transformVt(
vueNode: ExpressionNode,
ctx = createVueMacroContext()
options: {
stripNonEssentialProps?: boolean
}
) {
const ctx = createVueMacroContext(options)
if (!vueNode.ast) {
return vueNode
}
Expand Down
51 changes: 33 additions & 18 deletions packages/vue/src/compiler/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import {
import { transformVt } from "./transformVt"
import { transformTrans } from "./transformTrans"

export type LinguiTransformerOptions = {
stripNonEssentialProps?: boolean
}

/**
* Here is an entry point transformer.
* We need our template transformer to operate on user authored code
Expand All @@ -17,32 +21,43 @@ import { transformTrans } from "./transformTrans"
* So this transformer unshifts a real transformer to the transformers array.
*
*/
export const transformer: NodeTransform = (node, context) => {
if (
node.type === NodeTypes.ROOT &&
!context.nodeTransforms.includes(templateTransformer)
) {
context.nodeTransforms.unshift(templateTransformer)
export const transformer =
(options: LinguiTransformerOptions): NodeTransform =>
(node, context) => {
if (
node.type === NodeTypes.ROOT &&
!context.nodeTransforms.find(
(t) => (t as any).__name === "linguiTransform"
)
) {
context.nodeTransforms.unshift(templateTransformer(options))
}
}
}

/**
* Actual transformer expanding macro calls.
*/
const templateTransformer: NodeTransform = (node, context) => {
if (isElementNode(node)) {
if (isTrans(node)) {
transformTrans(node, context)
}
const templateTransformer = (
options: LinguiTransformerOptions
): NodeTransform => {
const transformer: NodeTransform = (node) => {
if (isElementNode(node)) {
if (isTrans(node)) {
transformTrans(node, options)
}

for (const prop of node.props) {
if (isDirectiveNode(prop) && prop.exp) {
prop.exp = transformVt(prop.exp)
for (const prop of node.props) {
if (isDirectiveNode(prop) && prop.exp) {
prop.exp = transformVt(prop.exp, options)
}
}
}
}

if (isInterpolationNode(node)) {
node.content = transformVt(node.content)
if (isInterpolationNode(node)) {
node.content = transformVt(node.content, options)
}
}

;(transformer as any).__name = "linguiTransform"
return transformer
}
2 changes: 0 additions & 2 deletions packages/vue/src/plugins/lingui.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { type I18n } from "@lingui/core"
import { inject, type Plugin } from "vue"

//

type LinguiPluginOptions = {
i18n: I18n
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// TODO: need to go full ESM to be able to use those types
// import { type Plugin, type TransformResult } from 'vite'
import { type Plugin, type TransformResult } from "vite"
import * as babel from "@babel/core"

const sourceRegex = /\.(:?[j|t]sx?|vue)$/u

// make babel macros works in vite
export function babelMacros() {
export function linguiCoreMacros(): Plugin {
return {
name: "vite-plugin-babel-macros",
async transform(source: string, filename: string) {
name: "vite-plugin-vue-lingui-babel-macro",
async transform(
source: string,
filename: string
): Promise<string | undefined | TransformResult> {
if (filename.includes("node_modules")) {
return undefined
}
Expand All @@ -19,13 +21,16 @@ export function babelMacros() {

const result = await babel.transformAsync(source, {
filename,
plugins: ["macros"],
plugins: ["@lingui/babel-plugin-lingui-macro"],
babelrc: false,
configFile: false,
sourceMaps: true,
})

return result
return {
code: result?.code,
map: result?.map,
} as TransformResult
},
} as const
}
61 changes: 61 additions & 0 deletions packages/vue/src/vite-plugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { PluginOption } from "vite"
import { lingui } from "@lingui/vite-plugin"
import { linguiCoreMacros } from "./core-macros-plugin"
import type { Api } from "@vitejs/plugin-vue"
import { transformer } from "../compiler"

type LinguiConfigOpts = {
cwd?: string
configPath?: string
skipValidation?: boolean
}

type Options = {
suppressRegisteringBabelMacro?: boolean
linguiConfigOptions?: LinguiConfigOpts
isProduction?: boolean
}

export function vueLingui(options: Options = {}): PluginOption[] {
options = {
suppressRegisteringBabelMacro: false,
isProduction: process.env.NODE_ENV === "production",
...options,
}

return [
lingui(options.linguiConfigOptions),
!options.suppressRegisteringBabelMacro ? linguiCoreMacros() : false,
{
name: "vite-plugin-lingui-vue-transform",
enforce: "pre",
configResolved(config) {
const vitePlugin = config.plugins.find(
(plugin) => plugin.name === "vite:vue"
)

if (!vitePlugin) {
throw new Error(
"Lingui Vue Plugin: Vite plugin is not found in your configuration. Please install it and to your Vite config"
)
}

const api = vitePlugin.api as Api

// register Lingui template transformer
api.options.template = {
...api.options.template,
compilerOptions: {
...api.options.template?.compilerOptions,
nodeTransforms: [
transformer({ stripNonEssentialProps: options.isProduction }),
...(api.options.template?.compilerOptions?.nodeTransforms || []),
],
},
}
},
},
]
}

export default lingui
18 changes: 17 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2989,7 +2989,7 @@ __metadata:
languageName: unknown
linkType: soft

"@lingui/vite-plugin@workspace:packages/vite-plugin":
"@lingui/vite-plugin@4.8.0-next.1, @lingui/vite-plugin@workspace:packages/vite-plugin":
version: 0.0.0-use.local
resolution: "@lingui/vite-plugin@workspace:packages/vite-plugin"
dependencies:
Expand Down Expand Up @@ -3017,11 +3017,17 @@ __metadata:
"@lingui/conf": 4.8.0-next.1
"@lingui/core": 4.8.0-next.1
"@lingui/message-utils": 4.8.0-next.1
"@lingui/vite-plugin": 4.8.0-next.1
"@types/babel__core": ^7.20.5
"@vitejs/plugin-vue": ^5.0.5
"@vue/compiler-core": ^3.3.4
"@vue/compiler-sfc": ^3.3.4
unbuild: 2.0.0
vite: 4.1.4
vue: ^3.3.4
peerDependencies:
"@vitejs/plugin-vue": "*"
vite: ^3 || ^4 || ^5.0.9
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -4487,6 +4493,16 @@ __metadata:
languageName: node
linkType: hard

"@vitejs/plugin-vue@npm:^5.0.5":
version: 5.0.5
resolution: "@vitejs/plugin-vue@npm:5.0.5"
peerDependencies:
vite: ^5.0.0
vue: ^3.2.25
checksum: 96077539da0c6d0d19f68ca112466d804e374a9e18cdb97b5396793a7eecaff433c109bac82ff0d130d39c48963f658158f2f44696fd0a50df2eb5080fafbdcc
languageName: node
linkType: hard

"@vue/compiler-core@npm:3.2.47":
version: 3.2.47
resolution: "@vue/compiler-core@npm:3.2.47"
Expand Down

0 comments on commit effd2c0

Please sign in to comment.