Skip to content
Permalink
Browse files

feat: Rework rollup support (#531)

- fix: double-hashed CSS filenames if chunk names include hash
- fix: increment CSS chunk names using same logic as rollup
- fix: correct some deficiencies in CSS bundle-splitting logic
- fix: Fix a race condition in file-walking

BREAKING CHANGE: changed rollup plugin CSS output so it better matches rollup output chunk format & bumped minimum rollup version to 0.68.0
  • Loading branch information...
tivac committed Dec 22, 2018
1 parent 8c52345 commit fce87fe7e5ba6f200c6046f4ad1c3ee4d142e27d
Showing with 663 additions and 356 deletions.
  1. +15 −15 package-lock.json
  2. +1 −1 package.json
  3. +16 −16 packages/browserify/browserify.js
  4. +4 −3 packages/processor/lib/output.js
  5. +10 −9 packages/processor/plugins/values-replace.js
  6. +45 −32 packages/processor/processor.js
  7. +44 −4 packages/processor/test/__snapshots__/options.test.js.snap
  8. +2 −1 packages/rollup/README.md
  9. +1 −1 packages/rollup/package.json
  10. +106 −119 packages/rollup/rollup.js
  11. +89 −47 packages/rollup/test/__snapshots__/rollup.test.js.snap
  12. +87 −22 packages/rollup/test/__snapshots__/splitting.test.js.snap
  13. +46 −56 packages/rollup/test/rollup.test.js
  14. +2 −0 packages/rollup/test/specimens/casing/foo.css
  15. +2 −0 packages/rollup/test/specimens/dynamic-imports/b.css
  16. +2 −0 packages/rollup/test/specimens/dynamic-imports/d.css
  17. +3 −0 packages/rollup/test/specimens/dynamic-imports/e.css
  18. +3 −0 packages/rollup/test/specimens/dynamic-imports/f.css
  19. +5 −0 packages/rollup/test/specimens/multiple-chunks/a.css
  20. +8 −0 packages/rollup/test/specimens/multiple-chunks/a.js
  21. +5 −0 packages/rollup/test/specimens/multiple-chunks/b.css
  22. +4 −0 packages/rollup/test/specimens/multiple-chunks/b.js
  23. +5 −0 packages/rollup/test/specimens/multiple-chunks/c.css
  24. +4 −0 packages/rollup/test/specimens/multiple-chunks/c.js
  25. +1 −0 packages/rollup/test/specimens/multiple-chunks/common.js
  26. +1 −0 packages/rollup/test/specimens/multiple-chunks/constants.css
  27. +5 −0 packages/rollup/test/specimens/multiple-chunks/shared.css
  28. +80 −23 packages/rollup/test/splitting.test.js
  29. +66 −6 packages/svelte/test/__snapshots__/svelte.test.js.snap
  30. +1 −1 packages/test-utils/read-dir.js

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -36,7 +36,7 @@
"lerna": "^3.4.3",
"pegjs": "0.10.0",
"read-dir-deep": "1.0.4",
"rollup": "^0.67.3",
"rollup": "^0.68.0",
"rollup-plugin-svelte": "^4.3.2",
"shelljs": "^0.8.3",
"svelte": "^2.15.3",
@@ -44,7 +44,7 @@ module.exports = (browserify, opts) => {

function depReducer(curr, next) {
curr[prefixed(options.cwd, next)] = next;

return curr;
}

@@ -84,19 +84,19 @@ module.exports = (browserify, opts) => {
processor.dependencies(result.id).forEach((dep) =>
browserify.emit("file", dep, dep)
);

push(outputs(result));

done();
},

(error) => {
// Thrown from the current bundler instance, NOT the main browserify
// instance. This is so that watchify won't explode.
bundler.emit("error", error);

push(buffer);

done();
}
);
@@ -108,32 +108,32 @@ module.exports = (browserify, opts) => {
if(path.extname(row.file) !== options.ext) {
return done(null, row);
}

handled[row.id] = true;

// Ensure that browserify knows about the CSS dependency tree by updating
// any referenced entries w/ their dependencies
row.deps = processor.dependencies(row.file).reduce(depReducer, {});

return done(null, row);
}, function(done) {
// Ensure that any CSS dependencies not directly referenced are
// injected into the stream of files being managed
const push = this.push.bind(this);

processor.dependencies().forEach((dep) => {
if(dep in handled) {
return;
}

push({
id : path.resolve(options.cwd, dep),
file : path.resolve(options.cwd, dep),
source : outputs(processor.files[dep]),
deps : processor.dependencies(dep).reduce(depReducer, {}),
});
});

done();
}));

@@ -169,24 +169,24 @@ module.exports = (browserify, opts) => {
// in case things have changed out from under us, like when using watchify
bundles = {};
handled = {};

// cache set to false means we need to create a new Processor each run-through
if(!options.cache) {
processor = new Processor(options);
}

bundler = current;

// Listen for bundling to finish
bundler.on("end", () => {
const bundling = Object.keys(bundles).length > 0;

if(options.json) {
mkdirp.sync(path.dirname(options.json));

fs.writeFileSync(
options.json,
JSON.stringify(output.compositions(options.cwd, processor), null, 4)
JSON.stringify(output.compositions(processor), null, 4)
);
}

@@ -231,7 +231,7 @@ module.exports = (browserify, opts) => {
if(!common.length && !options.empty) {
return Promise.resolve();
}

return write(bundling && common, options.css);
});
});
@@ -11,14 +11,15 @@ exports.join = (output) =>
classes.toString()
));

exports.compositions = (cwd, { files }) => {
exports.compositions = ({ options, files }) => {
const { cwd } = options;
const json = {};

Object.keys(files)
.sort()
.forEach((file) =>
(json[relative(cwd, file)] = exports.join(files[file].exports))
);

return json;
};
@@ -3,10 +3,9 @@
const selector = require("postcss-selector-parser");
const value = require("postcss-value-parser");
const escape = require("escape-string-regexp");
const each = require("lodash/forEach");
const get = require("lodash/get");
const Graph = require("dependency-graph").DepGraph;

const namespaced = require("./values-namespaced.js");

module.exports = (css, { opts, messages }) => {
@@ -22,8 +21,10 @@ module.exports = (css, { opts, messages }) => {
messages
.filter(({ plugin }) => plugin === namespaced.postcssPlugin)
.forEach((msg) =>
each(msg.values, (children, ns) =>
each(children, (details, child) => (values[`${ns}.${child}`] = details))
Object.entries(msg.values).forEach(([ ns, children ]) =>
Object.entries(children).forEach(([ child, details ]) =>
(values[`${ns}.${child}`] = details)
)
)
);

@@ -54,17 +55,17 @@ module.exports = (css, { opts, messages }) => {
const replacer = (prop) =>
(thing) => {
const parsed = value(thing[prop]);

parsed.walk((node) => {
if(node.type !== "word") {
return;
}

// Replace any value instances
node.value = node.value.replace(matchRegex, (match) => {
// Source map support
thing.source = values[match].source;

return values[match].value;
});
});
@@ -73,7 +74,7 @@ module.exports = (css, { opts, messages }) => {
};

// Walk through all values & build dependency graph
each(values, (details, name) => {
Object.entries(values).forEach(([ name, details ]) => {
graph.addNode(name);

value(details.value).walk((node) => {
@@ -89,7 +90,7 @@ module.exports = (css, { opts, messages }) => {
// Walk through values in dependency order & update any inter-dependent values
graph.overallOrder().forEach((name) => {
const parsed = value(values[name].value);

parsed.walk((node) => {
if(node.type !== "word" || !values[node.value]) {
return;
Oops, something went wrong.

0 comments on commit fce87fe

Please sign in to comment.
You can’t perform that action at this time.