Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
04c3d16
refactor: drop `css` modules
alexander-akait Jul 9, 2018
09e21c1
refactor: `runtime` code
alexander-akait Jul 9, 2018
c012f9b
refactor: move `postcss` plugin into own file
alexander-akait Jul 9, 2018
b130031
refactor: move `CssLoaderError` into own file
alexander-akait Jul 9, 2018
d1f80ee
refactor: merge code from `processCss` with `loader` code
alexander-akait Jul 9, 2018
ebdaf84
refactor: drop export locals
alexander-akait Jul 9, 2018
8150d2b
refactor: drop `icss` utils
alexander-akait Jul 9, 2018
f95be98
refactor: some stuff
alexander-akait Jul 9, 2018
c81edd4
refactor: `url` part of plugin
alexander-akait Jul 10, 2018
c49b5da
refactor: `import` part of plugin
alexander-akait Jul 10, 2018
254be6b
refactor: stuff
alexander-akait Jul 10, 2018
d22c14f
refactor: escape
alexander-akait Jul 10, 2018
cddbea5
refactor: rename `escape` to `runtimeEscape`
alexander-akait Jul 10, 2018
186f5b6
refactor: `getImportPrefix`
alexander-akait Jul 10, 2018
aa3918a
refactor: loader
alexander-akait Jul 10, 2018
7570df9
refactor: tests
alexander-akait Jul 10, 2018
ff7a4c8
refactor: SyntaxError class
alexander-akait Jul 10, 2018
2f769b3
refactor: loader
alexander-akait Jul 10, 2018
fdfdc17
refactor: use `runtime` message api
alexander-akait Jul 11, 2018
f424b92
refactor: `url` in lowercase
alexander-akait Jul 11, 2018
1aaecdd
refactor: rename `modify-runtime` to `modify-runtime-code`
alexander-akait Jul 11, 2018
45469b7
refactor: `loader` and `plugin`
alexander-akait Jul 11, 2018
ede061d
refactor: options
alexander-akait Jul 12, 2018
9075cfc
feat: validate options
alexander-akait Jul 12, 2018
99ffe87
tests: escaped characters
alexander-akait Jul 12, 2018
81d104a
refactor: webpack-defaults
alexander-akait Jul 12, 2018
f0c5312
refactor: tests
alexander-akait Aug 7, 2018
ae51bf0
refactor: modify message api
alexander-akait Aug 7, 2018
9ad9e21
chore(deps): update postcss to `7` version
alexander-akait Aug 8, 2018
1fdc462
chore(deps): use `schema-utils`
alexander-akait Aug 8, 2018
64a5b48
refactor: SyntaxError and Warning
alexander-akait Aug 8, 2018
0aea5d7
refactor: stuff
alexander-akait Aug 8, 2018
1554d66
test: fix
alexander-akait Aug 8, 2018
ca846b4
refactor: comment
alexander-akait Aug 8, 2018
1330534
refactor: stuff
alexander-akait Aug 8, 2018
84ffe7f
refactor: postcss option
alexander-akait Aug 8, 2018
fe0b78e
test: more
alexander-akait Aug 8, 2018
2b758e8
refactor: remove unnecessary map check
alexander-akait Aug 8, 2018
063dd2d
chore: update `postcss-loader`
alexander-akait Aug 8, 2018
868a5c3
feat: custom error messages
alexander-akait Aug 8, 2018
d49b1db
fix: test
alexander-akait Aug 8, 2018
c4037b0
refactor: reuing ast
alexander-akait Aug 8, 2018
f9cc7ba
docs: note about `css` modules
alexander-akait Aug 8, 2018
eab41ba
fix: use postcss ast only if versions is equals
alexander-akait Aug 15, 2018
06e6d08
refactor: tests
alexander-akait Aug 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor: use runtime message api
  • Loading branch information
alexander-akait committed Jul 11, 2018
commit fdfdc177b488069435cb0e1624208c4b9e5314e7
6 changes: 3 additions & 3 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ rules:
array-bracket-spacing: 'off'
array-callback-return: error
arrow-body-style: error
arrow-parens: error
arrow-parens: 'off'
arrow-spacing: error
block-scoped-var: 'off'
block-spacing:
Expand Down Expand Up @@ -90,7 +90,7 @@ rules:
no-bitwise: error
no-caller: error
no-catch-shadow: error
no-confusing-arrow: error
no-confusing-arrow: 'off'
no-continue: error
no-div-regex: error
no-duplicate-imports: error
Expand Down Expand Up @@ -176,7 +176,7 @@ rules:
no-useless-constructor: error
no-useless-escape: error
no-useless-rename: error
no-useless-return: error
no-useless-return: 'off'
no-var: 'off'
no-void: error
no-warning-comments: error
Expand Down
20 changes: 0 additions & 20 deletions lib/getImportPrefix.js

This file was deleted.

126 changes: 41 additions & 85 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/

const loaderUtils = require("loader-utils");
const postcss = require("postcss");
const plugin = require("./plugin");
const getImportPrefix = require("./getImportPrefix");
const SyntaxError = require("./SyntaxError");

module.exports = function(content, map, meta) {
Expand Down Expand Up @@ -42,7 +42,9 @@ module.exports = function(content, map, meta) {
const plugins = [
plugin({
url: options.url !== false,
import: options.import !== false
import: options.import !== false,
loaderContext: this,
importLoaders: options.importLoaders
})
];

Expand Down Expand Up @@ -71,75 +73,8 @@ module.exports = function(content, map, meta) {
postcss(plugins)
.process(content, postcssOptions)
.then(result => {
let cssAsString = JSON.stringify(result.css);
let imports = "";
let exports = "";
let urlEscapeHelperCode = "";

if (options.import !== false) {
const alreadyImported = {};
imports = result.messages
.filter(message => message.type === "at-rule-import")
.filter(message => {
if (!message.mediaQuery) {
if (alreadyImported[message.url]) {
return false;
}

alreadyImported[message.url] = true;
}

return true;
})
.map(message => {
if (!loaderUtils.isUrlRequest(message.url)) {
return (
"exports.push([module.id, " +
JSON.stringify("@import url(" + message.url + ");") +
", " +
JSON.stringify(message.mediaQuery) +
"]);"
);
}

// for importing CSS
var importUrlPrefix = getImportPrefix(this, options);
var importUrl = importUrlPrefix + message.url;

return (
"exports.i(require(" +
loaderUtils.stringifyRequest(this, importUrl) +
"), " +
JSON.stringify(message.mediaQuery) +
");"
);
})
.join("\n");
}

if (options.url !== false) {
urlEscapeHelperCode =
"var runtimeEscape = require(" +
loaderUtils.stringifyRequest(
this,
require.resolve("./runtimeEscape.js")
) +
");\n";

result.messages
.filter(message => message.type === "function-url")
.forEach(message => {
const { placeholder, url } = message;
const splittedURL = url.split(/(\?)?#/);
const importURLString =
'" + runtimeEscape(require(' +
loaderUtils.stringifyRequest(this, splittedURL[0]) +
')) + "' +
(splittedURL[1] ? splittedURL[1] : "") +
(splittedURL[2] ? `#${splittedURL[2]}` : "");

cssAsString = cssAsString.replace(placeholder, importURLString);
});
if (meta && meta.messages) {
result.messages = result.messages.concat(meta.messages);
}

if (sourceMap && result.map) {
Expand All @@ -162,33 +97,54 @@ module.exports = function(content, map, meta) {
map = JSON.stringify(map);
}

const runtimeCode = `module.exports = exports = require(${loaderUtils.stringifyRequest(
this,
require.resolve("./runtime.js")
)})(${!!sourceMap});\n`;
const moduleCode = `// CSS Module\nexports.push([module.id, ${cssAsString}, ""${
map ? `,${map}` : ""
}]);\n`;
const importsCode = imports ? `// CSS Imports\n${imports}\n` : "";
// Todo need save backward compatibility with old `style-loader` and exports.locals
const exportsCode = exports ? `// CSS Exports\n${exports}\n` : false;
let newContent = {
imports: "",
runtime: `module.exports = exports = require(${loaderUtils.stringifyRequest(
this,
require.resolve("./runtime.js")
)})(${!!sourceMap});\n`,
module: `exports.push([module.id, ${JSON.stringify(result.css)}, ""${
map ? `,${map}` : ""
}]);\n`,
exports: ""
};

if (result.messages && result.messages.length > 0) {
newContent = result.messages
.filter(message => (message.type === "modify-runtime" ? message : false))
.reduce((initialValue, message) => {
try {
initialValue = message.modifyRuntimeCode(this, initialValue);
} catch (err) {
this.emitError(err);
}

return initialValue;
}, newContent);
}

const {imports, runtime, module, exports} = newContent;

cb(
null,
[
urlEscapeHelperCode,
runtimeCode,
importsCode,
moduleCode,
exportsCode
imports ? `// CSS imports\n${imports}` : "",
runtime ? `// CSS runtime\n${runtime}` : "",
module ? `// CSS module\n${newContent.module}` : "",
exports ? `// CSS exports\n${newContent.exports}` : ""
].join("\n")
);

return;
})
.catch(err => {
if (err.file) {
this.addDependency(err.file);
}

cb(err.name === "CssSyntaxError" ? new SyntaxError(err) : err);

return;
});
};
108 changes: 90 additions & 18 deletions lib/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,28 @@ const loaderUtils = require("loader-utils");

const pluginName = "postcss-css-loader";

function getImportPrefix(loaderContext, importLoaders) {
if (importLoaders === false) {
return "";
}

const importLoadersValue = parseInt(importLoaders, 10) || 0;
const loadersRequest = loaderContext.loaders
.slice(
loaderContext.loaderIndex,
loaderContext.loaderIndex + 1 + importLoadersValue
)
.map(x => x.request)
.join("!");

return "-!" + loadersRequest + "!";
}

module.exports = postcss.plugin(pluginName, function(options) {
return function(css, result) {
if (options.import) {
const alreadyImported = {};

css.walkAtRules(/^import$/i, function(rule) {
const parsedValue = valueParser(rule.params);

Expand Down Expand Up @@ -35,20 +54,43 @@ module.exports = postcss.plugin(pluginName, function(options) {
return;
}

const mediaQuery = valueParser
.stringify(parsedValue.nodes.slice(1))
.trim();

let runtimeCode = "";

if (loaderUtils.isUrlRequest(url)) {
url = loaderUtils.urlToRequest(url);

const importUrlPrefix = getImportPrefix(
options.loaderContext,
options.importLoaders
);

runtimeCode = `exports.i(require(${loaderUtils.stringifyRequest(
options.loaderContext,
importUrlPrefix + url
)}), ${JSON.stringify(mediaQuery)});\n`;
} else {
runtimeCode = `exports.push([module.id, ${JSON.stringify(
"@import url(" + url + ");"
)}, ${JSON.stringify(mediaQuery)}]);`;
}

const mediaQuery = valueParser
.stringify(parsedValue.nodes.slice(1))
.trim();
if (!alreadyImported[url]) {
result.messages.push({
pluginName,
type: "modify-runtime",
modifyRuntimeCode: (loaderContext, content) => {
content.runtime = `${content.runtime}${runtimeCode}\n`;

return content;
}
});

result.messages.push({
pluginName,
type: "at-rule-import",
url: url,
mediaQuery: mediaQuery
});
alreadyImported[url] = true;
}

rule.remove();
});
Expand All @@ -75,37 +117,67 @@ module.exports = postcss.plugin(pluginName, function(options) {
}

const URLNode = node.nodes[0];
const URLValue = URLNode.value.trim().replace(/\\[\r\n]/g, "");
const URL = URLNode.value.trim().replace(/\\[\r\n]/g, "");

// Skip empty URLs
// Empty URL function equals request to current stylesheet where it is declared
if (URLValue.length === 0) {
if (URL.length === 0) {
return;
}

if (!loaderUtils.isUrlRequest(URLValue)) {
if (!loaderUtils.isUrlRequest(URL)) {
return;
}

// Remove spaces before and after
node.before = "";
node.after = "";

const requestedURL = loaderUtils.urlToRequest(URLValue);
const placeholder = "___CSS_LOADER_IMPORT_URL_PLACEHOLDER___" + index + "___";
const splittedURL = URL.split(/(\?)?#/);
const normalizedURL = splittedURL[0];

const requestedURL = loaderUtils.urlToRequest(normalizedURL);
const placeholder =
"___CSS_LOADER_IMPORT_URL_PLACEHOLDER___" + index + "___";

URLNode.value = placeholder;
// Strip quotes, they will be re-added if the module needs them
URLNode.quote = "";

let hasURLEscapeRuntimeCode = false;

result.messages.push({
pluginName,
type: "function-url",
placeholder: placeholder,
url: requestedURL
type: "modify-runtime",
modifyRuntimeCode: (loaderContext, content) => {
if (!hasURLEscapeRuntimeCode) {
content.imports = `var runtimeEscape = require(${loaderUtils.stringifyRequest(
loaderContext,
require.resolve("./runtimeEscape.js")
)});\n${content.imports}`;

hasURLEscapeRuntimeCode = true;
}

content.imports = `${
content.imports
}var ${placeholder} = require(${loaderUtils.stringifyRequest(
loaderContext,
requestedURL
)});\n`;

content.module = content.module.replace(
placeholder,
`" + runtimeEscape(${placeholder}) + "${
splittedURL[1] ? splittedURL[1] : ""
}${splittedURL[2] ? `#${splittedURL[2]}` : ""}`
);

return content;
}
});

index++;
index += 1;

return false;
})
Expand Down
Loading