From 85e118a68c242103d81b1c50fe259c34b4e4859c Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Tue, 12 Nov 2024 20:17:29 +0200 Subject: [PATCH 1/6] Remove not used files --- package.json | 1 - rollup.d.ts | 1 - vite.d.ts | 1 - webpack.d.ts | 1 - 4 files changed, 4 deletions(-) delete mode 100644 rollup.d.ts delete mode 100644 vite.d.ts delete mode 100644 webpack.d.ts diff --git a/package.json b/package.json index eef051a..1595e3a 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,6 @@ "module": "dist/index.js", "types": "dist/index.d.ts", "files": [ - "*.d.ts", "dist" ], "scripts": { diff --git a/rollup.d.ts b/rollup.d.ts deleted file mode 100644 index 7a5813f..0000000 --- a/rollup.d.ts +++ /dev/null @@ -1 +0,0 @@ -export { ExternalFluentPlugin, SFCFluentPlugin } from './dist/rollup' diff --git a/vite.d.ts b/vite.d.ts deleted file mode 100644 index e76d5be..0000000 --- a/vite.d.ts +++ /dev/null @@ -1 +0,0 @@ -export { ExternalFluentPlugin, SFCFluentPlugin } from './dist/vite' diff --git a/webpack.d.ts b/webpack.d.ts deleted file mode 100644 index 9979987..0000000 --- a/webpack.d.ts +++ /dev/null @@ -1 +0,0 @@ -export { ExternalFluentPlugin, SFCFluentPlugin } from './dist/webpack' From 55cf21b40f2187599dbb46998500ef2a5be4c31f Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Tue, 12 Nov 2024 20:34:47 +0200 Subject: [PATCH 2/6] Enable and fix TS errors --- package.json | 1 + src/plugins/external-plugin.ts | 7 ++++--- src/plugins/sfc-plugin.ts | 2 +- tsconfig.json | 4 +++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1595e3a..9ecf7ea 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "test": "vitest", "test:coverage": "vitest --coverage", "build": "tsup", + "typecheck": "tsc --noEmit", "lint": "eslint .", "prepare": "husky", "release": "dotenv release-it" diff --git a/src/plugins/external-plugin.ts b/src/plugins/external-plugin.ts index cf53c81..689db25 100644 --- a/src/plugins/external-plugin.ts +++ b/src/plugins/external-plugin.ts @@ -46,11 +46,12 @@ export const unplugin = createUnplugin((options: ExternalPluginOptions) => { ...options, } + let getFtlPath if ('getFtlPath' in options) { - resolvedOptions.getFtlPath = options.getFtlPath + getFtlPath = options.getFtlPath } else { - resolvedOptions.getFtlPath = (locale: string, vuePath: string) => { + getFtlPath = (locale: string, vuePath: string) => { return join(options.ftlDir, locale, `${relative(options.baseDir, vuePath)}.ftl`) } } @@ -58,7 +59,7 @@ export const unplugin = createUnplugin((options: ExternalPluginOptions) => { const getTranslationsForFile = async (id: string) => { const dependencies: Dependency[] = [] for (const locale of options.locales) { - const ftlPath = normalizePath(resolvedOptions.getFtlPath(locale, id)) + const ftlPath = normalizePath(getFtlPath(locale, id)) const ftlExists = await fileExists(ftlPath) let relativeFtlPath = normalizePath(relative(dirname(id), ftlPath)) if (!relativeFtlPath.startsWith('.')) diff --git a/src/plugins/sfc-plugin.ts b/src/plugins/sfc-plugin.ts index 8c5c172..7d2a5c5 100644 --- a/src/plugins/sfc-plugin.ts +++ b/src/plugins/sfc-plugin.ts @@ -58,6 +58,6 @@ export default function (Component) { } }) -export const vitePlugin: (options?: SFCPluginOptions) => VitePlugin = unplugin.vite +export const vitePlugin = unplugin.vite as (options?: SFCPluginOptions) => VitePlugin export const rollupPlugin = unplugin.rollup export const webpackPlugin = unplugin.webpack diff --git a/tsconfig.json b/tsconfig.json index a80bd93..5cad25c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,10 @@ "baseUrl": ".", "moduleResolution": "node", "types": ["node"], + "strict": true, "sourceMap": true, - "esModuleInterop": true + "esModuleInterop": true, + "skipLibCheck": true }, "exclude": [ "node_modules" From 4f7075b7b9e4f7cefbf5a716199dfac9ff9df623 Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Wed, 13 Nov 2024 11:43:37 +0200 Subject: [PATCH 3/6] Include map in ExternalFluentPlugin --- src/plugins/external-plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/external-plugin.ts b/src/plugins/external-plugin.ts index 689db25..8e496bb 100644 --- a/src/plugins/external-plugin.ts +++ b/src/plugins/external-plugin.ts @@ -126,7 +126,7 @@ export const unplugin = createUnplugin((options: ExternalPluginOptions) => { return { code: magic.toString(), - map: { mappings: '' }, + map: magic.generateMap(), } } From 7d6b2bcafbcba8ff18654c15f90739c58bf73b2e Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Wed, 13 Nov 2024 11:54:36 +0200 Subject: [PATCH 4/6] Add support for sourcemaps to SFCFluentPlugin --- .../webpack/__snapshots__/sfc.spec.ts.snap | 12 +++----- src/plugins/sfc-plugin.ts | 30 ++++++++++++------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap b/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap index a9619da..112d38d 100644 --- a/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap +++ b/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap @@ -2,28 +2,24 @@ exports[`Webpack SFC > generates custom block code 1`] = ` [ - " -import { FluentResource } from '@fluent/bundle' + "import { FluentResource } from '@fluent/bundle' export default function (Component) { const target = Component.options || Component target.fluent = target.fluent || {} target.fluent['en'] = new FluentResource("# Simple things are simple.\\nhello-user = Hello, {$userName}!\\n\\n# Complex things are possible.\\nshared-photos =\\n {$userName} {$photoCount ->\\n [one] added one photo\\n *[other] added {$photoCount} new photos\\n } to {$userGender ->\\n [male] his stream\\n [female] her stream\\n *[other] their stream\\n }.") -} -", +}", ] `; exports[`Webpack SFC > includes HMR code only when HMR is enabled 1`] = ` [ - " -import { FluentResource } from '@fluent/bundle' + "import { FluentResource } from '@fluent/bundle' export default function (Component) { const target = Component.options || Component target.fluent = target.fluent || {} target.fluent['en'] = new FluentResource("# Simple things are simple.\\nhello-user = Hello, {$userName}!\\n\\n# Complex things are possible.\\nshared-photos =\\n {$userName} {$photoCount ->\\n [one] added one photo\\n *[other] added {$photoCount} new photos\\n } to {$userGender ->\\n [male] his stream\\n [female] her stream\\n *[other] their stream\\n }.") -} -", +}", ] `; diff --git a/src/plugins/sfc-plugin.ts b/src/plugins/sfc-plugin.ts index 7d2a5c5..57e1b27 100644 --- a/src/plugins/sfc-plugin.ts +++ b/src/plugins/sfc-plugin.ts @@ -1,6 +1,7 @@ import type { VitePlugin } from 'unplugin' import type { SFCPluginOptions } from '../types' +import MagicString from 'magic-string' import { createUnplugin } from 'unplugin' import { isCustomBlock, parseVueRequest } from '../loader-query' import { getSyntaxErrors } from './ftl/parse' @@ -23,11 +24,11 @@ export const unplugin = createUnplugin((options: SFCPluginOptions, meta) => { const { query } = parseVueRequest(id) if (isCustomBlock(query, resolvedOptions)) { - const data = source - // vue-loader pads SFC file sections with newlines - trim those - .replace(/^(\n|\r\n)+|(\n|\r\n)+$/g, '') - // normalise newlines - .replace(/\r\n/g, '\n') + const originalSource = source + + const magic = new MagicString(source, { filename: id }) + + source = source.replace(/\r\n/g, '\n').trim() if (query.locale == null) this.error('Custom block does not have locale attribute') @@ -37,20 +38,29 @@ export const unplugin = createUnplugin((options: SFCPluginOptions, meta) => { return source if (resolvedOptions.checkSyntax) { - const errorsText = getSyntaxErrors(data) + const errorsText = getSyntaxErrors(source) if (errorsText) this.error(errorsText) } - return ` + if (originalSource.length > 0) + magic.update(0, originalSource.length, JSON.stringify(source)) + else + magic.append('""') + + magic.prepend(` import { FluentResource } from '@fluent/bundle' export default function (Component) { const target = Component.options || Component target.fluent = target.fluent || {} - target.fluent['${query.locale}'] = new FluentResource(${JSON.stringify(data)}) -} -` + target.fluent['${query.locale}'] = new FluentResource(`) + magic.append(')\n}\n') + + return { + code: magic.toString(), + map: magic.generateMap(), + } } return undefined From 6b21ec28d9ef3ebf78befe406f53a2bcfef0d5ab Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Wed, 13 Nov 2024 12:22:27 +0200 Subject: [PATCH 5/6] Add automatic publish script --- .github/workflows/test.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5727438..4ea8084 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -49,6 +49,23 @@ jobs: - name: Lint run: pnpm lint + publish: + runs-on: ubuntu-latest + name: Publish test build to pkg.pr.new + steps: + - name: Checkout + uses: actions/checkout@v4.2.2 + - name: Setup Node.js + uses: actions/setup-node@v4.1.0 + - uses: pnpm/action-setup@v4.0.0 + with: + run_install: true + + - name: Build + run: pnpm build + - name: Publish + run: pnpx pkg-pr-new publish + test-examples: runs-on: ubuntu-latest name: Test build of example projects From a013fd7d5a7dff3bc457d3e12b6bc568e22aaa14 Mon Sep 17 00:00:00 2001 From: Ivan Demchuk Date: Wed, 13 Nov 2024 12:54:25 +0200 Subject: [PATCH 6/6] Don't tranform file is not needed --- .../webpack/__snapshots__/sfc.spec.ts.snap | 12 ++++++++---- src/plugins/sfc-plugin.ts | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap b/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap index 112d38d..a9619da 100644 --- a/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap +++ b/__tests__/frameworks/webpack/__snapshots__/sfc.spec.ts.snap @@ -2,24 +2,28 @@ exports[`Webpack SFC > generates custom block code 1`] = ` [ - "import { FluentResource } from '@fluent/bundle' + " +import { FluentResource } from '@fluent/bundle' export default function (Component) { const target = Component.options || Component target.fluent = target.fluent || {} target.fluent['en'] = new FluentResource("# Simple things are simple.\\nhello-user = Hello, {$userName}!\\n\\n# Complex things are possible.\\nshared-photos =\\n {$userName} {$photoCount ->\\n [one] added one photo\\n *[other] added {$photoCount} new photos\\n } to {$userGender ->\\n [male] his stream\\n [female] her stream\\n *[other] their stream\\n }.") -}", +} +", ] `; exports[`Webpack SFC > includes HMR code only when HMR is enabled 1`] = ` [ - "import { FluentResource } from '@fluent/bundle' + " +import { FluentResource } from '@fluent/bundle' export default function (Component) { const target = Component.options || Component target.fluent = target.fluent || {} target.fluent['en'] = new FluentResource("# Simple things are simple.\\nhello-user = Hello, {$userName}!\\n\\n# Complex things are possible.\\nshared-photos =\\n {$userName} {$photoCount ->\\n [one] added one photo\\n *[other] added {$photoCount} new photos\\n } to {$userGender ->\\n [male] his stream\\n [female] her stream\\n *[other] their stream\\n }.") -}", +} +", ] `; diff --git a/src/plugins/sfc-plugin.ts b/src/plugins/sfc-plugin.ts index 57e1b27..2a5fd84 100644 --- a/src/plugins/sfc-plugin.ts +++ b/src/plugins/sfc-plugin.ts @@ -35,7 +35,7 @@ export const unplugin = createUnplugin((options: SFCPluginOptions, meta) => { // I have no idea why webpack processes this file multiple times if (source.includes('FluentResource') || source.includes('unplugin-fluent-vue-sfc')) - return source + return undefined if (resolvedOptions.checkSyntax) { const errorsText = getSyntaxErrors(source)