Skip to content

Commit

Permalink
refactor: migrate on message api for postcss-icss-plugin (#838)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi authored Dec 3, 2018
1 parent 476ebca commit 9eaba66
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 46 deletions.
49 changes: 21 additions & 28 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ module.exports = function loader(content, map) {
}
/* eslint-enable no-param-reassign */

const parserOptions = {};
const resolveImport = options.import !== false;
const resolveUrl = options.url !== false;
const loaderContext = this;
Expand Down Expand Up @@ -98,7 +97,7 @@ module.exports = function loader(content, map) {
plugins.push(urlParser());
}

plugins.push(icssParser(parserOptions));
plugins.push(icssParser());

postcss(plugins)
.process(content, {
Expand All @@ -125,34 +124,39 @@ module.exports = function loader(content, map) {

const messages = result.messages || [];
const { camelCase, exportOnlyLocals, importLoaders } = options;
const { importItems } = parserOptions;

// Run other loader (`postcss-loader`, `sass-loader` and etc) for importing CSS
const importUrlPrefix = getImportPrefix(this, importLoaders);

// Prepare replacer to change from `___CSS_LOADER_IMPORT___INDEX___` to `require('./file.css').locals`
const importItemReplacer = (item) => {
const match = placholderRegExps.importItem.exec(item);
const importItemReplacer = (placeholder) => {
const match = placholderRegExps.importItem.exec(placeholder);
const idx = Number(match[1]);

if (!importItems[idx]) {
return item;
const message = messages.find(
// eslint-disable-next-line no-shadow
(message) =>
message.type === 'icss-import' && message.item.index === idx
);

if (!message) {
return placeholder;
}

const importItem = importItems[idx];
const importUrl = importUrlPrefix + importItem.url;
const { item } = message;
const importUrl = importUrlPrefix + item.url;

if (exportOnlyLocals) {
return `" + require(${stringifyRequest(
this,
importUrl
)})[${JSON.stringify(importItem.export)}] + "`;
)})[${JSON.stringify(item.export)}] + "`;
}

return `" + require(${stringifyRequest(
this,
importUrl
)}).locals[${JSON.stringify(importItem.export)}] + "`;
)}).locals[${JSON.stringify(item.export)}] + "`;
};

let exportCode = compileExports(messages, camelCase, (valueAsString) =>
Expand All @@ -166,22 +170,11 @@ module.exports = function loader(content, map) {
);
}

const alreadyImported = {};
const importCode = importItems
.filter((imp) => {
if (!imp.media) {
if (alreadyImported[imp.url]) {
return false;
}

alreadyImported[imp.url] = true;
}

return true;
})
.map((imp) => {
const { url } = imp;
const media = imp.media || '';
const importCode = messages
.filter((message) => message.type === 'import')
.map((message) => {
const { url } = message.item;
const media = message.item.media || '';

if (!isUrlRequest(url)) {
return `exports.push([module.id, ${JSON.stringify(
Expand All @@ -207,7 +200,7 @@ module.exports = function loader(content, map) {
let urlEscapeHelperCode = '';

messages
.filter((message) => message.type === 'url' && resolveUrl)
.filter((message) => message.type === 'url')
.forEach((message) => {
if (!urlEscapeHelperCode) {
urlEscapeHelperCode = `var escape = require(${stringifyRequest(
Expand Down
41 changes: 27 additions & 14 deletions lib/plugins/postcss-icss-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@ const pluginName = 'postcss-icss-parser';

module.exports = postcss.plugin(
pluginName,
(options) =>
() =>
function process(css, result) {
const importItems = (result.messages || [])
.filter((message) => message.type === 'import')
.map((message) => message.item);

const imports = {};
const icss = icssUtils.extractICSS(css);
const exports = icss.icssExports;
Expand All @@ -21,11 +17,32 @@ module.exports = postcss.plugin(
const url = loaderUtils.parseString(key);

Object.keys(icss.icssImports[key]).forEach((prop) => {
imports[`$${prop}`] = importItems.length;
importItems.push({
url,
media: '',
export: icss.icssImports[key][prop],
const index = Object.keys(imports).length;

imports[`$${prop}`] = index;

result.messages.push({
pluginName,
type: 'icss-import',
item: { url, export: icss.icssImports[key][prop], index },
});

const alreadyIncluded = result.messages.find(
(message) =>
message.pluginName === pluginName &&
message.type === 'import' &&
message.item.url === url &&
message.item.media === ''
);

if (alreadyIncluded) {
return;
}

result.messages.push({
pluginName,
type: 'import',
item: { url, media: '' },
});
});
});
Expand Down Expand Up @@ -73,9 +90,5 @@ module.exports = postcss.plugin(
},
});
});

/* eslint-disable no-param-reassign */
options.importItems = importItems;
/* eslint-enable no-param-reassign */
}
);
75 changes: 71 additions & 4 deletions test/__snapshots__/import-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ Array [
Array [
2,
"
",
"",
],
Array [
3,
"
",
"",
],
Expand All @@ -17,6 +23,27 @@ Array [
.ghi {
color: red;
}
.class {
color: blue;
}
.other {
display: block;
}
.other-other {
width: 2112moon;
}
.green {
color: green;
}
.foo {
prop: red;
duplicate: green;
}
",
"",
],
Expand All @@ -27,13 +54,18 @@ exports[`import option false and modules false: module 1`] = `
"exports = module.exports = require(\\"../../../lib/runtime/api.js\\")(false);
// imports
exports.i(require(\\"-!../../../index.js??ref--4-0!./values.css\\"), \\"\\");
exports.i(require(\\"-!../../../index.js??ref--4-0!./something.css\\"), \\"\\");
// module
exports.push([module.id, \\"@import url(test-other.css) (min-width: 100px);\\\\n\\\\n.ghi {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n}\\\\n\\", \\"\\"]);
exports.push([module.id, \\"@import url(test-other.css) (min-width: 100px);\\\\n\\\\n.ghi {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n}\\\\n\\\\n.class {\\\\n color: blue;\\\\n}\\\\n\\\\n.other {\\\\n display: block;\\\\n}\\\\n\\\\n.other-other {\\\\n width: \\" + require(\\"-!../../../index.js??ref--4-0!./something.css\\").locals[\\"something\\"] + \\";\\\\n}\\\\n\\\\n.green {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"other\\"] + \\";\\\\n}\\\\n\\\\n.foo {\\\\n prop: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n duplicate: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"other\\"] + \\";\\\\n}\\\\n\\", \\"\\"]);
// exports
exports.locals = {
\\"def\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\"\\"
\\"def\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\"\\",
\\"other\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"other\\"] + \\"\\",
\\"something\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./something.css\\").locals[\\"something\\"] + \\"\\",
\\"foo\\": \\"blue\\",
\\"bar\\": \\"block\\"
};"
`;
Expand All @@ -46,6 +78,12 @@ Array [
Array [
2,
"
",
"",
],
Array [
3,
"
",
"",
],
Expand All @@ -56,6 +94,27 @@ Array [
._3r49KZIIAltPknAjdNVZ-7 {
color: red;
}
._4o0o5eKzoeDOSI0_cR8mr {
color: blue;
}
._2wLXKM9pRjt1oRYvf0Wo3Q {
display: block;
}
._1RBgqC8j3f4iU6k-ocmIG7 {
width: 2112moon;
}
._1lCIckG6C8tRZjGNDsAPWr {
color: green;
}
._1YL4f0i_603GTMRC_pnsP5 {
prop: red;
duplicate: green;
}
",
"",
],
Expand All @@ -66,14 +125,22 @@ exports[`import option false and modules true: module 1`] = `
"exports = module.exports = require(\\"../../../lib/runtime/api.js\\")(false);
// imports
exports.i(require(\\"-!../../../index.js??ref--4-0!./values.css\\"), \\"\\");
exports.i(require(\\"-!../../../index.js??ref--4-0!./something.css\\"), \\"\\");
// module
exports.push([module.id, \\"@import url(test-other.css) (min-width: 100px);\\\\n\\\\n._3r49KZIIAltPknAjdNVZ-7 {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n}\\\\n\\", \\"\\"]);
exports.push([module.id, \\"@import url(test-other.css) (min-width: 100px);\\\\n\\\\n._3r49KZIIAltPknAjdNVZ-7 {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n}\\\\n\\\\n._4o0o5eKzoeDOSI0_cR8mr {\\\\n color: blue;\\\\n}\\\\n\\\\n._2wLXKM9pRjt1oRYvf0Wo3Q {\\\\n display: block;\\\\n}\\\\n\\\\n._1RBgqC8j3f4iU6k-ocmIG7 {\\\\n width: \\" + require(\\"-!../../../index.js??ref--4-0!./something.css\\").locals[\\"something\\"] + \\";\\\\n}\\\\n\\\\n._1lCIckG6C8tRZjGNDsAPWr {\\\\n color: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"other\\"] + \\";\\\\n}\\\\n\\\\n._1YL4f0i_603GTMRC_pnsP5 {\\\\n prop: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\";\\\\n duplicate: \\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"other\\"] + \\";\\\\n}\\\\n\\", \\"\\"]);
// exports
exports.locals = {
\\"def\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./values.css\\").locals[\\"def\\"] + \\"\\",
\\"ghi\\": \\"_3r49KZIIAltPknAjdNVZ-7\\"
\\"other\\": \\"_2wLXKM9pRjt1oRYvf0Wo3Q\\",
\\"something\\": \\"\\" + require(\\"-!../../../index.js??ref--4-0!./something.css\\").locals[\\"something\\"] + \\"\\",
\\"foo\\": \\"_1YL4f0i_603GTMRC_pnsP5\\",
\\"bar\\": \\"block\\",
\\"ghi\\": \\"_3r49KZIIAltPknAjdNVZ-7\\",
\\"class\\": \\"_4o0o5eKzoeDOSI0_cR8mr\\",
\\"other-other\\": \\"_1RBgqC8j3f4iU6k-ocmIG7\\",
\\"green\\": \\"_1lCIckG6C8tRZjGNDsAPWr\\"
};"
`;
Expand Down
26 changes: 26 additions & 0 deletions test/fixtures/import/css-modules.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
@import url(test-other.css) (min-width: 100px);

@value def from './values.css';
@value other from './values.css';
@value other from './values.css';
@value something from './something.css';
@value foo: blue;
@value bar: block;

.ghi {
color: def;
}

.class {
color: foo;
}

.other {
display: bar;
}

.other-other {
width: something;
}

.green {
color: other;
}

.foo {
prop: def;
duplicate: other;
}
1 change: 1 addition & 0 deletions test/fixtures/import/something.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@value something: 2112moon;
1 change: 1 addition & 0 deletions test/fixtures/import/values.css
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
@value def: red;
@value other: green;

0 comments on commit 9eaba66

Please sign in to comment.