Skip to content

Commit

Permalink
fix: transform json in deep import (#1459)
Browse files Browse the repository at this point in the history
fix #1458
  • Loading branch information
hannoeru authored Jan 10, 2021
1 parent 8497f52 commit cf8342b
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
10 changes: 10 additions & 0 deletions packages/playground/json/__tests__/json.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const json = require('../test.json')
const deepJson = require('@vue/runtime-core/package.json')
const stringified = JSON.stringify(json)
const deepStringified = JSON.stringify(deepJson)

test('default import', async () => {
expect(await page.textContent('.full')).toBe(stringified)
Expand All @@ -9,6 +11,14 @@ test('named import', async () => {
expect(await page.textContent('.named')).toBe(json.hello)
})

test('deep import', async () => {
expect(await page.textContent('.deep-full')).toBe(deepStringified)
})

test('named deep import', async () => {
expect(await page.textContent('.deep-named')).toBe(deepJson.name)
})

test('dynamic import', async () => {
expect(await page.textContent('.dynamic')).toBe(stringified)
})
Expand Down
9 changes: 9 additions & 0 deletions packages/playground/json/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ <h2>Normal Import</h2>
<pre class="full"></pre>
<pre class="named"></pre>

<h2>Deep Import</h2>
<pre class="deep-full"></pre>
<pre class="deep-named"></pre>

<h2>Dynamic Import</h2>
<pre class="dynamic"></pre>
<pre class="dynamic-named"></pre>
Expand All @@ -11,9 +15,14 @@ <h2>Raw fetch</h2>

<script type="module">
import json, { hello } from './test.json'
import deepJson, { name } from '@vue/runtime-core/package.json'

text('.full', JSON.stringify(json))
text('.named', hello)

text('.deep-full', JSON.stringify(deepJson))
text('.deep-named', name)

import('/test.json').then((mod) => {
text('.dynamic', JSON.stringify(mod.default))
text('.dynamic-named', mod.hello)
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ResolvedConfig } from '../config'
import { Plugin } from '../plugin'
import aliasPlugin from '@rollup/plugin-alias'
import jsonPlugin from '@rollup/plugin-json'
import { jsonPlugin } from './json'
import { resolvePlugin } from './resolve'
import { esbuildPlugin } from './esbuild'
import { importAnalysisPlugin } from './importAnalysis'
Expand Down
81 changes: 81 additions & 0 deletions packages/vite/src/node/plugins/json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* https://github.com/rollup/plugins/blob/master/packages/json/src/index.js
*
* This source code is licensed under the MIT license found in the
* LICENSE file at
* https://github.com/rollup/plugins/blob/master/LICENSE
*/

import { createFilter, dataToEsm } from '@rollup/pluginutils'
import { FilterPattern } from '@rollup/pluginutils'
import { Plugin } from 'rollup'

export interface RollupJsonOptions {
/**
* All JSON files will be parsed by default,
* but you can also specifically include files
*/
include?: FilterPattern
/**
* All JSON files will be parsed by default,
* but you can also specifically exclude files
*/
exclude?: FilterPattern
/**
* For tree-shaking, properties will be declared as variables, using
* either `var` or `const`.
* @default false
*/
preferConst?: boolean
/**
* Specify indentation for the generated default export
* @default '\t'
*/
indent?: string
/**
* Ignores indent and generates the smallest code
* @default false
*/
compact?: boolean
/**
* Generate a named export for every property of the JSON object
* @default true
*/
namedExports?: boolean
}

// Custom json filter for vite
const jsonExtRE = new RegExp(`\\.json($|\\?)`)

export function jsonPlugin(options: RollupJsonOptions = {}): Plugin {
const filter = createFilter(options.include, options.exclude)
const indent = 'indent' in options ? options.indent : '\t'

return {
name: 'vite:json',

transform(json, id) {
if (!jsonExtRE.test(id) || !filter(id)) return null

try {
const parsed = JSON.parse(json)
return {
code: dataToEsm(parsed, {
preferConst: options.preferConst,
compact: options.compact,
namedExports: options.namedExports,
indent
}),
map: { mappings: '' }
}
} catch (e) {
const errorMessageList = /[\d]/.exec(e.message)
const position = errorMessageList && parseInt(errorMessageList[0], 10)
const msg = position
? `, invalid JSON syntax found at line ${position}`
: `.`
this.error(`Failed to parse JSON file` + msg, e.idx)
}
}
}
}

0 comments on commit cf8342b

Please sign in to comment.