Skip to content

Commit

Permalink
⭐ new: support lang attribute
Browse files Browse the repository at this point in the history
closes #52
  • Loading branch information
kazupon committed Jul 22, 2019
1 parent 2505a83 commit 36c62a5
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 66 deletions.
4 changes: 2 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var querystring_1 = require("querystring");
var loader = function (source) {
var loader = function (source, sourceMap) {
if (this.version && Number(this.version) >= 2) {
try {
this.cacheable && this.cacheable();
this.callback(null, "module.exports = " + generateCode(source, querystring_1.parse(this.resourceQuery)));
this.callback(null, "module.exports = " + generateCode(source, querystring_1.parse(this.resourceQuery)), sourceMap);
}
catch (err) {
this.emitError(err.message);
Expand Down
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@
"bugs": {
"url": "https://github.com/kazupon/vue-i18n-loader/issues"
},
"dependencies": {
"js-yaml": "^3.13.1",
"json5": "^2.1.0"
},
"devDependencies": {
"@types/jest": "^24.0.15",
"@types/js-yaml": "^3.12.1",
"@types/jsdom": "^12.2.4",
"@types/json5": "^0.0.30",
"@types/memory-fs": "^0.3.2",
"@types/node": "^12.6.8",
"@types/webpack": "^4.4.35",
"@types/webpack-merge": "^4.1.5",
"@typescript-eslint/eslint-plugin": "^1.12.0",
"@typescript-eslint/parser": "^1.12.0",
"@typescript-eslint/typescript-estree": "^1.12.0",
Expand All @@ -31,7 +38,8 @@
"typescript": "^3.5.3",
"vue-loader": "^15.7.0",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.35.3"
"webpack": "^4.35.3",
"webpack-merge": "^4.2.1"
},
"engines": {
"node": ">= 8"
Expand Down
28 changes: 20 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import webpack from 'webpack'
import { ParsedUrlQuery, parse } from 'querystring'
import { RawSourceMap } from 'source-map'
import JSON5 from 'json5'
import yaml from 'js-yaml'

const loader: webpack.loader.Loader = function (
source: string | Buffer, sourceMap: RawSourceMap | undefined): void {
Expand All @@ -20,14 +22,8 @@ const loader: webpack.loader.Loader = function (
}

function generateCode (source: string | Buffer, query: ParsedUrlQuery): string {
let code = ''

let value = typeof source === 'string'
? JSON.parse(source)
: Buffer.isBuffer(source)
? JSON.parse(source.toString())
: null
if (value === null) { throw new Error('invalid source!') }
const data = convert(source, query.lang as string)
let value = JSON.parse(data)

if (query.locale && typeof query.locale === 'string') {
value = Object.assign({}, { [query.locale]: value })
Expand All @@ -38,6 +34,7 @@ function generateCode (source: string | Buffer, query: ParsedUrlQuery): string {
.replace(/\u2029/g, '\\u2029')
.replace(/\\/g, '\\\\')

let code = ''
code += `function (Component) {
Component.options.__i18n = Component.options.__i18n || []
Component.options.__i18n.push('${value.replace(/\u0027/g, '\\u0027')}')
Expand All @@ -46,4 +43,19 @@ function generateCode (source: string | Buffer, query: ParsedUrlQuery): string {
return code
}

function convert (source: string | Buffer, lang: string): string {
const value = Buffer.isBuffer(source) ? source.toString() : source

switch (lang) {
case 'yaml':
case 'yml':
const data = yaml.safeLoad(value)
return JSON.stringify(data, undefined, '\t')
case 'json5':
return JSON.stringify(JSON5.parse(value))
default:
return value
}
}

export default loader
13 changes: 13 additions & 0 deletions test/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ Array [
]
`;

exports[`json5 1`] = `
Array [
"{\\"en\\":{\\"hello\\":\\"hello world!\\"}}",
]
`;

exports[`locale attr 1`] = `
Array [
"{\\"ja\\":{\\"hello\\":\\"こんにちは、世界!\\"}}",
Expand Down Expand Up @@ -43,3 +49,10 @@ Array [
"{\\"en\\":{\\"hello\\":\\"hello\\\\ngreat\\\\t\\\\\\"world\\\\\\"\\"}}",
]
`;

exports[`yaml 1`] = `
Array [
"{\\"en\\":{\\"hello\\":\\"hello world!\\"}}",
"{\\"ja\\":{\\"hello\\":\\"こんにちは、世界!\\"}}",
]
`;
8 changes: 8 additions & 0 deletions test/fixtures/json5.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<i18n lang="json5">
{
"en": {
// comments
"hello": "hello world!"
}
}
</i18n>
7 changes: 7 additions & 0 deletions test/fixtures/yaml.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<i18n locale="en" lang="yaml">
hello: "hello world!"
</i18n>

<i18n locale="ja" lang="yml">
hello: "こんにちは、世界!"
</i18n>
10 changes: 10 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,13 @@ test('locale attr and import', async () => {
const { module } = await bundleAndRun('locale-import.vue')
expect(module.__i18n).toMatchSnapshot()
})

test('yaml', async () => {
const { module } = await bundleAndRun('yaml.vue')
expect(module.__i18n).toMatchSnapshot()
})

test('json5', async () => {
const { module } = await bundleAndRun('json5.vue')
expect(module.__i18n).toMatchSnapshot()
})
18 changes: 12 additions & 6 deletions test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'path'
import webpack from 'webpack'
import merge from 'webpack-merge'
import memoryfs from 'memory-fs'
import { JSDOM, VirtualConsole, DOMWindow } from 'jsdom'
import { VueLoaderPlugin } from 'vue-loader'
Expand All @@ -17,8 +18,8 @@ type BundleResolveResolve = BundleResolve & {
exports: any
}

export function bundle (fixture: string): Promise<BundleResolve> {
const compiler = webpack({
export function bundle (fixture: string, options = {}): Promise<BundleResolve> {
const baseConfig: webpack.Configuration = {
mode: 'development',
devtool: false,
entry: path.resolve(__dirname, './fixtures/entry.js'),
Expand All @@ -38,13 +39,18 @@ export function bundle (fixture: string): Promise<BundleResolve> {
}, {
resourceQuery: /blockType=i18n/,
type: 'javascript/auto',
loader: path.resolve(__dirname, '../src/index.ts')
use: [
path.resolve(__dirname, '../src/index.ts')
]
}]
},
plugins: [
new VueLoaderPlugin()
]
})
}

const config = merge({}, baseConfig, options)
const compiler = webpack(config)

const mfs = new memoryfs() // eslint-disable-line
compiler.outputFileSystem = mfs
Expand All @@ -58,8 +64,8 @@ export function bundle (fixture: string): Promise<BundleResolve> {
})
}

export async function bundleAndRun (fixture: string): Promise<BundleResolveResolve> {
const { code, stats } = await bundle(fixture)
export async function bundleAndRun (fixture: string, config = {}): Promise<BundleResolveResolve> {
const { code, stats } = await bundle(fixture, config)

let dom: JSDOM | null = null
let jsdomError
Expand Down
Loading

0 comments on commit 36c62a5

Please sign in to comment.