Skip to content

Commit

Permalink
refactor: code (#1017)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi authored Dec 12, 2019
1 parent c80c39f commit 3b12c87
Show file tree
Hide file tree
Showing 19 changed files with 645 additions and 367 deletions.
32 changes: 16 additions & 16 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,6 @@ export default function loader(content, map, meta) {

const callback = this.async();
const sourceMap = options.sourceMap || false;

// Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
// eslint-disable-next-line no-param-reassign
map = sourceMap && map ? normalizeSourceMap(map) : null;

// Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
if (meta) {
const { ast } = meta;

if (ast && ast.type === 'postcss' && ast.version === postcssPkg.version) {
// eslint-disable-next-line no-param-reassign
content = ast.root;
}
}

const plugins = [];

if (options.modules) {
Expand Down Expand Up @@ -74,12 +59,27 @@ export default function loader(content, map, meta) {
);
}

// Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
if (meta) {
const { ast } = meta;

if (ast && ast.type === 'postcss' && ast.version === postcssPkg.version) {
// eslint-disable-next-line no-param-reassign
content = ast.root;
}
}

postcss(plugins)
.process(content, {
from: this.remainingRequest.split('!').pop(),
to: this.currentRequest.split('!').pop(),
map: options.sourceMap
? { prev: map, inline: false, annotation: false }
? {
// Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
prev: sourceMap && map ? normalizeSourceMap(map) : null,
inline: false,
annotation: false,
}
: false,
})
.then((result) => {
Expand Down
67 changes: 36 additions & 31 deletions src/plugins/postcss-icss-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,67 @@ import { urlToRequest } from 'loader-utils';

const pluginName = 'postcss-icss-parser';

function normalizeIcssImports(icssImports) {
return Object.keys(icssImports).reduce((accumulator, url) => {
const tokensMap = icssImports[url];
const tokens = Object.keys(tokensMap);

if (tokens.length === 0) {
return accumulator;
}

const normalizedUrl = urlToRequest(url);

if (!accumulator[normalizedUrl]) {
// eslint-disable-next-line no-param-reassign
accumulator[normalizedUrl] = tokensMap;
} else {
// eslint-disable-next-line no-param-reassign
accumulator[normalizedUrl] = {
...accumulator[normalizedUrl],
...tokensMap,
};
}

return accumulator;
}, {});
}

export default postcss.plugin(
pluginName,
() =>
function process(css, result) {
const importReplacements = Object.create(null);
const { icssImports, icssExports } = extractICSS(css);

const normalizedIcssImports = Object.keys(icssImports).reduce(
(accumulator, url) => {
const tokensMap = icssImports[url];
const tokens = Object.keys(tokensMap);

if (tokens.length === 0) {
return accumulator;
}

const normalizedUrl = urlToRequest(url);

if (!accumulator[normalizedUrl]) {
// eslint-disable-next-line no-param-reassign
accumulator[normalizedUrl] = tokensMap;
} else {
// eslint-disable-next-line no-param-reassign
accumulator[normalizedUrl] = {
...accumulator[normalizedUrl],
...tokensMap,
};
}

return accumulator;
},
{}
);
const normalizedIcssImports = normalizeIcssImports(icssImports);

Object.keys(normalizedIcssImports).forEach((url, importIndex) => {
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;

result.messages.push({
pluginName,
type: 'import',
value: { type: 'icss-import', name: importName, url },
value: { type: 'icss-import', importName, url },
});

const tokenMap = normalizedIcssImports[url];
const tokens = Object.keys(tokenMap);

tokens.forEach((token, replacementIndex) => {
const name = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
const localName = tokenMap[token];

importReplacements[token] = name;
importReplacements[token] = replacementName;

result.messages.push({
pluginName,
type: 'replacer',
value: { type: 'icss-import', name, importName, localName },
value: {
type: 'icss-import',
importName,
replacementName,
localName,
},
});
});
});
Expand Down
38 changes: 10 additions & 28 deletions src/plugins/postcss-import-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function parseImport(params) {
}

function walkAtRules(css, result, filter) {
const items = new Map();
const items = [];

css.walkAtRules(/^import$/i, (atRule) => {
// Convert only top-level @import
Expand Down Expand Up @@ -91,14 +91,7 @@ function walkAtRules(css, result, filter) {

atRule.remove();

const { url, media } = parsed;
const value = items.get(url);

if (!value) {
items.set(url, new Set([media]));
} else {
value.add(media);
}
items.push(parsed);
});

return items;
Expand All @@ -110,25 +103,14 @@ export default postcss.plugin(
function process(css, result) {
const items = walkAtRules(css, result, options.filter);

[...items]
.reduce((accumulator, currentValue) => {
const [url, medias] = currentValue;

medias.forEach((media) => {
accumulator.push({ url, media });
});

return accumulator;
}, [])
.forEach((item, index) => {
const { url, media } = item;
const name = `___CSS_LOADER_AT_RULE_IMPORT_${index}___`;

result.messages.push({
pluginName,
type: 'import',
value: { type: '@import', name, url, media },
});
items.forEach((item) => {
const { url, media } = item;

result.messages.push({
pluginName,
type: 'import',
value: { type: '@import', url, media },
});
});
}
);
23 changes: 11 additions & 12 deletions src/plugins/postcss-url-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,45 +139,44 @@ export default postcss.plugin(
(options) =>
function process(css, result) {
const traversed = walkDecls(css, result, options.filter);
const paths = collectUniqueUrlsWithNodes(
flatten(traversed.map((item) => item.urls))
);
const flattenTraversed = flatten(traversed.map((item) => item.urls));
const urlsWithNodes = collectUniqueUrlsWithNodes(flattenTraversed);
const replacers = new Map();

paths.forEach((path, index) => {
const { url, hash, needQuotes, nodes } = path;
const name = `___CSS_LOADER_URL_IMPORT_${index}___`;
urlsWithNodes.forEach((urlWithNodes, index) => {
const { url, hash, needQuotes, nodes } = urlWithNodes;
const replacementName = `___CSS_LOADER_URL_REPLACEMENT_${index}___`;

result.messages.push(
{
pluginName,
type: 'import',
value: { type: 'url', name, url, needQuotes, hash, index },
value: { type: 'url', replacementName, url, needQuotes, hash },
},
{
pluginName,
type: 'replacer',
value: { type: 'url', name },
value: { type: 'url', replacementName },
}
);

nodes.forEach((node) => {
replacers.set(node, name);
replacers.set(node, replacementName);
});
});

traversed.forEach((item) => {
walkUrls(item.parsed, (node) => {
const name = replacers.get(node);
const replacementName = replacers.get(node);

if (!name) {
if (!replacementName) {
return;
}

// eslint-disable-next-line no-param-reassign
node.type = 'word';
// eslint-disable-next-line no-param-reassign
node.value = name;
node.value = replacementName;
});

// eslint-disable-next-line no-param-reassign
Expand Down
Loading

0 comments on commit 3b12c87

Please sign in to comment.