Skip to content

Commit

Permalink
feat: support sourcemap generation (#70)
Browse files Browse the repository at this point in the history
related #1
  • Loading branch information
kazupon committed Nov 21, 2021
1 parent 9db2b54 commit 976861b
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 24 deletions.
8 changes: 6 additions & 2 deletions packages/vite-plugin-vue-i18n/examples/legacy/main.ts
@@ -1,12 +1,16 @@
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import App from './App.vue'
import messages from '@intlify/vite-plugin-vue-i18n/messages'
import en from './locales/en.yaml'
import ja from './locales/ja.json'

const i18n = createI18n({
legacy: true,
locale: 'ja',
messages
messages: {
en,
ja
}
})

const app = createApp(App)
Expand Down
1 change: 1 addition & 0 deletions packages/vite-plugin-vue-i18n/package.json
Expand Up @@ -27,6 +27,7 @@
"@intlify/shared": "beta",
"@rollup/pluginutils": "^4.1.0",
"debug": "^4.3.1",
"source-map": "0.6.1",
"fast-glob": "^3.2.5"
},
"devDependencies": {},
Expand Down
63 changes: 44 additions & 19 deletions packages/vite-plugin-vue-i18n/src/index.ts
Expand Up @@ -10,6 +10,7 @@ import {
import fg from 'fast-glob'
import createDebug from 'debug'
import { normalizePath } from 'vite'
import { RawSourceMap } from 'source-map'
import { parseVueRequest } from './query'

import type { Plugin, ResolvedConfig, UserConfig } from 'vite'
Expand Down Expand Up @@ -70,7 +71,9 @@ function pluginI18n(
? 'vue-i18n'
: `${installedPkg}`
const forceStringify = !!options.forceStringify

let isProduction = false
let sourceMap = false

return {
name: 'vite-plugin-vue-i18n',
Expand Down Expand Up @@ -129,6 +132,7 @@ function pluginI18n(

configResolved(config: ResolvedConfig) {
isProduction = config.isProduction
sourceMap = config.command === 'build' ? !!config.build.sourcemap : false

// json transform handling
const jsonPlugin = config.plugins.find(p => p.name === 'vite:json')
Expand Down Expand Up @@ -167,13 +171,15 @@ function pluginI18n(
for (const inc of includePaths) {
resourcePaths = [...(await fg(inc))]
}
// TODO: source-map
const code = await generateBundleResources(
resourcePaths,
isProduction,
forceStringify
)
return Promise.resolve(code)
return Promise.resolve({
code,
map: { mappings: '' }
})
}
},

Expand All @@ -194,17 +200,12 @@ function pluginI18n(
debug('transform', id, JSON.stringify(query))

let langInfo = 'json'
let inSourceMap: RawSourceMap | undefined

if (!query.vue) {
if (/\.(json5?|ya?ml)$/.test(id) && filter(id)) {
langInfo = path.parse(filename).ext

// NOTE:
// `.json` is handled default in vite, and it's transformed to JS object.
let _source = code
if (langInfo === '.json') {
_source = await getRaw(id)
}

const generate = /\.?json5?/.test(langInfo)
? generateJSON
: generateYAML
Expand All @@ -213,17 +214,26 @@ function pluginI18n(
filename,
isProduction,
query as Record<string, unknown>,
sourceMap,
inSourceMap,
globalSFCScope,
forceStringify
) as CodeGenOptions
debug('parseOptions', parseOptions)

const { code: generatedCode } = generate(_source, parseOptions)
debug('generated code', generatedCode)
// TODO: error handling & sourcempa
return Promise.resolve(generatedCode)
const { code: generatedCode, map } = generate(code, parseOptions)
debug('generated code', generatedCode, id)
debug('sourcemap', map, id)

return Promise.resolve({
code: generatedCode,
map: (sourceMap ? map : { mappings: '' }) as any // eslint-disable-line @typescript-eslint/no-explicit-any
})
} else {
return Promise.resolve(code)
return Promise.resolve({
code,
map: sourceMap ? this.getCombinedSourcemap() : { mappings: '' }
})
}
} else {
// for Vue SFC
Expand All @@ -246,17 +256,26 @@ function pluginI18n(
filename,
isProduction,
query as Record<string, unknown>,
sourceMap,
inSourceMap,
globalSFCScope,
forceStringify
) as CodeGenOptions
debug('parseOptions', parseOptions)

const { code: generatedCode } = generate(code, parseOptions)
debug('generated code', generatedCode)
// TODO: error handling & sourcempa
return Promise.resolve(generatedCode)
const { code: generatedCode, map } = generate(code, parseOptions)
debug('generated code', generatedCode, id)
debug('sourcemap', map, id)

return Promise.resolve({
code: generatedCode,
map: (sourceMap ? map : { mappings: '' }) as any // eslint-disable-line @typescript-eslint/no-explicit-any
})
} else {
return Promise.resolve(code)
return Promise.resolve({
code,
map: sourceMap ? this.getCombinedSourcemap() : { mappings: '' }
})
}
}
}
Expand Down Expand Up @@ -295,13 +314,17 @@ function getOptions(
filename: string,
isProduction: boolean,
query: Record<string, unknown>,
sourceMap: boolean,
inSourceMap: RawSourceMap | undefined,
isGlobal = false,
forceStringify = false
): Record<string, unknown> {
const mode: DevEnv = isProduction ? 'production' : 'development'

const baseOptions = {
filename,
sourceMap,
inSourceMap,
forceStringify,
env: mode,
onWarn: (msg: string): void => {
Expand Down Expand Up @@ -344,6 +367,8 @@ async function generateBundleResources(
res,
isProduction,
{},
false,
undefined,
isGlobal,
forceStringify
) as CodeGenOptions
Expand Down
@@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`custom blocks json 1`] = `";;;;;;;;;;;;;;;;;;;;;;AAIE;SACO;;;"`;

exports[`custom blocks json5 1`] = `";;;;;;;;;;;;;;;;;;;;;;AAIE;SACO;;;"`;

exports[`custom blocks yaml 1`] = `";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIE;SACO;;;"`;

exports[`custom blocks yml 1`] = `";;;;;;;;;;;;;;;;;;;;AAIE;SACO;;;"`;

exports[`resource files json 1`] = `";;;2EACYA,gDAAAC;;;;;wBAEAC;;;;;;;;;;;;;;;;;;;;;;ACCV;SACO;;;"`;

exports[`resource files json5 1`] = `";;;;;;;;;;;AAIE;SACO;;;"`;

exports[`resource files yaml 1`] = `";;;;;;;;;;;AAIE;SACO;;;"`;
3 changes: 3 additions & 0 deletions packages/vite-plugin-vue-i18n/test/fixtures/yml.vue
@@ -0,0 +1,3 @@
<i18n lang="yml">
message: "@.caml:{'no apples'} | {0} apple | {n} apples"
</i18n>
47 changes: 47 additions & 0 deletions packages/vite-plugin-vue-i18n/test/sourcemap.test.ts
@@ -0,0 +1,47 @@
import path from 'path'
import { bundleAndRun } from './utils'

describe('resource files', () => {
const options = {
sourcemap: true,
target: './fixtures/locales/',
include: [path.resolve(__dirname, './fixtures/locales/**')]
}

test('json', async () => {
const { map } = await bundleAndRun('ja.json', options)
expect(map.mappings).toMatchSnapshot()
})

test('json5', async () => {
const { map } = await bundleAndRun('en.json5', options)
expect(map.mappings).toMatchSnapshot()
})

test('yaml', async () => {
const { map } = await bundleAndRun('ko.yaml', options)
expect(map.mappings).toMatchSnapshot()
})
})

describe('custom blocks', () => {
test('json', async () => {
const { map } = await bundleAndRun('basic.vue', { sourcemap: true })
expect(map.mappings).toMatchSnapshot()
})

test('yaml', async () => {
const { map } = await bundleAndRun('yaml.vue', { sourcemap: true })
expect(map.mappings).toMatchSnapshot()
})

test('yml', async () => {
const { map } = await bundleAndRun('yml.vue', { sourcemap: true })
expect(map.mappings).toMatchSnapshot()
})

test('json5', async () => {
const { map } = await bundleAndRun('json5.vue', { sourcemap: true })
expect(map.mappings).toMatchSnapshot()
})
})
14 changes: 11 additions & 3 deletions packages/vite-plugin-vue-i18n/test/utils.ts
Expand Up @@ -13,6 +13,7 @@ async function bundle(fixture: string, options: Record<string, unknown> = {}) {
const include = (options.include as string[]) || [
path.resolve(__dirname, './fixtures/**')
]
const sourcemap = (options.sourcemap as boolean) || false
const silent = isBoolean(options.silent)
? options.silent === false
? 'info'
Expand Down Expand Up @@ -46,22 +47,27 @@ async function bundle(fixture: string, options: Record<string, unknown> = {}) {
},
plugins,
build: {
sourcemap,
write: false,
minify: false,
rollupOptions: {
input: path.resolve(__dirname, input)
}
}
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return { code: (result as any).output[0].code }
return {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
code: (result as any).output[0].code,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
map: (result as any).output[0].map
}
}

export async function bundleAndRun(
fixture: string,
options: Record<string, unknown> = {}
) {
const { code } = await bundle(fixture, options)
const { code, map } = await bundle(fixture, options)

let dom: JSDOM | null = null
let jsdomError
Expand All @@ -87,6 +93,8 @@ export async function bundleAndRun(
window,
module,
exports,
code,
map,
jsdomError
})
}

0 comments on commit 976861b

Please sign in to comment.