diff --git a/packages/json/README.md b/packages/json/README.md index 1b1c9cd0f..8d8b4fc2e 100644 --- a/packages/json/README.md +++ b/packages/json/README.md @@ -68,6 +68,12 @@ Default: `null` A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, which specifies the files in the build the plugin should _ignore_. By default no files are ignored. +### `extensions` + +Type: `Array[...String]`
+Default: `['.json']` +A list of file extensions to be handled by the plugin. By default, only `.json` files are handled. + ### `include` Type: `String` | `Array[...String]`
diff --git a/packages/json/src/index.js b/packages/json/src/index.js index dcb8f3333..ac597fa4e 100755 --- a/packages/json/src/index.js +++ b/packages/json/src/index.js @@ -1,15 +1,19 @@ import { createFilter, dataToEsm } from '@rollup/pluginutils'; +import { extname } from 'path'; export default function json(options = {}) { const filter = createFilter(options.include, options.exclude); const indent = 'indent' in options ? options.indent : '\t'; + const extensions = new Set('extensions' in options ? options.extensions : ['.json']); return { name: 'json', // eslint-disable-next-line no-shadow transform(code, id) { - if (id.slice(-5) !== '.json' || !filter(id)) return null; + const extension = extname(id); + + if (!extensions.has(extension) || !filter(id)) return null; try { const parsed = JSON.parse(code); diff --git a/packages/json/test/fixtures/custom-file-extension/config.customjson b/packages/json/test/fixtures/custom-file-extension/config.customjson new file mode 100755 index 000000000..0a6e8769b --- /dev/null +++ b/packages/json/test/fixtures/custom-file-extension/config.customjson @@ -0,0 +1,3 @@ +{ + "answer": 42 +} diff --git a/packages/json/test/fixtures/custom-file-extension/main.js b/packages/json/test/fixtures/custom-file-extension/main.js new file mode 100755 index 000000000..fb5eee1f1 --- /dev/null +++ b/packages/json/test/fixtures/custom-file-extension/main.js @@ -0,0 +1,3 @@ +import config from './config.customjson'; + +t.is(config.answer, 42); diff --git a/packages/json/test/test.js b/packages/json/test/test.js index 9aec69089..ba074ea72 100755 --- a/packages/json/test/test.js +++ b/packages/json/test/test.js @@ -164,3 +164,24 @@ test('handles empty keys', async (t) => { 'export var b = "c";\nexport default {\n\t"": "a",\n\tb: b\n};\n' ); }); + +test('uses extensions option', async (t) => { + const bundle = await rollup({ + input: 'fixtures/custom-file-extension/main.js', + plugins: [ + json({ + extensions: ['.customjson'] + }) + ] + }); + t.plan(1); + return testBundle(t, bundle); +}); + +test('does not process non-custom extensions', async (t) => { + const content = 'some content'; + const id = 'testfile.json'; + const plugin = json({ extensions: ['.custom'] }); + const output = plugin.transform(content, id); + t.is(output, null, 'Should return null for files without custom extensions'); +}); diff --git a/packages/json/types/index.d.ts b/packages/json/types/index.d.ts index 6ef037a23..82ccddb62 100755 --- a/packages/json/types/index.d.ts +++ b/packages/json/types/index.d.ts @@ -12,6 +12,11 @@ export interface RollupJsonOptions { * but you can also specifically exclude files */ exclude?: FilterPattern; + /** + * Specify the file extensions to be parsed as JSON + * @default ['.json'] + */ + extensions?: string[]; /** * For tree-shaking, properties will be declared as variables, using * either `var` or `const`.