diff --git a/docs/rollup.md b/docs/rollup.md index 3c8f85059..3aaee74e3 100644 --- a/docs/rollup.md +++ b/docs/rollup.md @@ -14,7 +14,7 @@ A minimatch pattern, or an array of minimatch patterns, relative to `process.cwd ### `json` -Boolean to determine if JSON files should be output at the end of compilation. Defaults to `false`. +Boolean/String to determine if JSON files containing all exported classes & values should be output. If set to `true` will write out to a file named `exports.json`. If a `String` will write out to that file name. Defaults to `false`. ### `map` diff --git a/packages/rollup/README.md b/packages/rollup/README.md index 5a9d46251..29d9690e0 100644 --- a/packages/rollup/README.md +++ b/packages/rollup/README.md @@ -54,7 +54,7 @@ A minimatch pattern, or an array of minimatch patterns, relative to `process.cwd ### `json` -Boolean to determine if JSON files should be output at the end of compilation. Defaults to `false`. +Boolean/String to determine if JSON files containing all exported classes & values should be output. If set to `true` will write out to a file named `exports.json`. If a `String` will write out to that file name. Defaults to `false`. ### `map` diff --git a/packages/rollup/rollup.js b/packages/rollup/rollup.js index 65804a97b..9bd8a60ca 100644 --- a/packages/rollup/rollup.js +++ b/packages/rollup/rollup.js @@ -29,15 +29,11 @@ const makeFile = (details) => { module.exports = function(opts) { const options = Object.assign(Object.create(null), { - common : "common.css", - - json : false, - - include : "**/*.css", - + common : "common.css", + json : false, + include : "**/*.css", namedExports : true, - - styleExport : false, + styleExport : false, }, opts); const filter = utils.createFilter(options.include, options.exclude); @@ -77,7 +73,7 @@ module.exports = function(opts) { } // Is this file being processed on a watch update? - if(runs && (id in processor.files)) { + if(runs++ && (id in processor.files)) { const files = []; // Watching will call transform w/ the same entry file, even if it @@ -148,11 +144,6 @@ module.exports = function(opts) { }; }, - // Track # of runs since remove functionality needs to change - buildEnd() { - runs++; - }, - async generateBundle(outputOptions, bundles) { // styleExport disables all output file generation if(styleExport) { @@ -248,7 +239,7 @@ module.exports = function(opts) { await Promise.all( files .filter(({ css }) => css.size) - .map(async ({ base, name, css }) => { + .map(async ({ base, name, css }, idx) => { const id = this.emitAsset(`${base}.css`); const result = await processor.output({ @@ -260,8 +251,12 @@ module.exports = function(opts) { this.setAssetSource(id, result.css); - if(options.json) { - this.emitAsset(`${base}.json`, JSON.stringify(result.compositions, null, 4)); + // result.compositions always includes all the info, so it + // doesn't actually matter which result we use. First one seems reasonable! + if(options.json && idx === 0) { + const file = typeof options.json === "string" ? options.json : "exports.json"; + + this.emitAsset(file, JSON.stringify(result.compositions, null, 4)); } if(result.map) { diff --git a/packages/rollup/test/__snapshots__/rollup.test.js.snap b/packages/rollup/test/__snapshots__/rollup.test.js.snap index 6f781631f..01afc7fcf 100644 --- a/packages/rollup/test/__snapshots__/rollup.test.js.snap +++ b/packages/rollup/test/__snapshots__/rollup.test.js.snap @@ -54,6 +54,15 @@ exports[`/rollup.js should generate JSON 1`] = ` }" `; +exports[`/rollup.js should generate JSON with a custom name 1`] = ` +"{ + \\"packages/rollup/test/specimens/simple.css\\": { + \\"str\\": \\"\\\\\\"string\\\\\\"\\", + \\"fooga\\": \\"fooga\\" + } +}" +`; + exports[`/rollup.js should generate exports 1`] = ` "var css = { \\"str\\": \\"\\\\\\"string\\\\\\"\\", diff --git a/packages/rollup/test/__snapshots__/splitting.test.js.snap b/packages/rollup/test/__snapshots__/splitting.test.js.snap index f2be5befd..820b11722 100644 --- a/packages/rollup/test/__snapshots__/splitting.test.js.snap +++ b/packages/rollup/test/__snapshots__/splitting.test.js.snap @@ -1,5 +1,39 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`/rollup.js code splitting should ouput only 1 JSON file 1`] = ` +Array [ + Object { + "file": "common.css", + "text": "/* packages/rollup/test/specimens/simple.css */ +.fooga { + color: red; +} +", + }, + Object { + "file": "dependencies.css", + "text": "/* packages/rollup/test/specimens/dependencies.css */ +.wooga { + + background: blue; +} +", + }, + Object { + "file": "exports.json", + "text": "{ + \\"packages/rollup/test/specimens/dependencies.css\\": { + \\"wooga\\": \\"fooga wooga\\" + }, + \\"packages/rollup/test/specimens/simple.css\\": { + \\"str\\": \\"\\\\\\"string\\\\\\"\\", + \\"fooga\\": \\"fooga\\" + } +}", + }, +] +`; + exports[`/rollup.js code splitting should support dynamic imports 1`] = ` Array [ Object { diff --git a/packages/rollup/test/rollup.test.js b/packages/rollup/test/rollup.test.js index 594a8049f..8d7084966 100644 --- a/packages/rollup/test/rollup.test.js +++ b/packages/rollup/test/rollup.test.js @@ -160,7 +160,27 @@ describe("/rollup.js", () => { file : prefix(`./output/rollup/json/simple.js`), }); - expect(read("./rollup/json/assets/simple.json")).toMatchSnapshot(); + expect(read("./rollup/json/assets/exports.json")).toMatchSnapshot(); + }); + + it("should generate JSON with a custom name", async () => { + const bundle = await rollup({ + input : require.resolve("./specimens/simple.js"), + plugins : [ + plugin({ + namer, + json : "custom.json", + }), + ], + }); + + await bundle.write({ + format, + assetFileNames, + file : prefix(`./output/rollup/json-named/simple.js`), + }); + + expect(read("./rollup/json-named/assets/custom.json")).toMatchSnapshot(); }); it("should provide named exports", async () => { diff --git a/packages/rollup/test/splitting.test.js b/packages/rollup/test/splitting.test.js index 396d5c5cc..020e4bddd 100644 --- a/packages/rollup/test/splitting.test.js +++ b/packages/rollup/test/splitting.test.js @@ -20,6 +20,8 @@ error.postcssPlugin = "error-plugin"; const assetFileNames = "assets/[name][extname]"; const format = "es"; const map = false; +const sourcemap = false; +const json = true; describe("/rollup.js", () => { beforeAll(() => shell.rm("-rf", prefix("./output/rollup/*"))); @@ -47,6 +49,7 @@ describe("/rollup.js", () => { await bundle.write({ format, + sourcemap, assetFileNames, chunkFileNames, @@ -76,6 +79,7 @@ describe("/rollup.js", () => { await bundle.write({ format, + sourcemap, assetFileNames, chunkFileNames, @@ -105,6 +109,7 @@ describe("/rollup.js", () => { await bundle.write({ format, + sourcemap, assetFileNames, chunkFileNames, @@ -140,6 +145,7 @@ describe("/rollup.js", () => { await bundle.write({ format, + sourcemap, assetFileNames, chunkFileNames, @@ -171,6 +177,7 @@ describe("/rollup.js", () => { await bundle.write({ format, + sourcemap, assetFileNames, chunkFileNames, @@ -180,5 +187,36 @@ describe("/rollup.js", () => { expect(dir("./rollup/dynamic-imports/assets/")).toMatchSnapshot(); }); + + it("should ouput only 1 JSON file", async () => { + const bundle = await rollup({ + experimentalCodeSplitting, + + input : [ + require.resolve("./specimens/simple.js"), + require.resolve("./specimens/dependencies.js"), + ], + + plugins : [ + plugin({ + namer, + map, + json, + }), + ], + }); + + await bundle.write({ + format, + sourcemap, + + assetFileNames, + chunkFileNames, + + dir : prefix(`./output/rollup/json-splitting`), + }); + + expect(dir("./rollup/json-splitting/assets")).toMatchSnapshot(); + }); }); });