Skip to content

Commit

Permalink
refactor: code
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Mar 23, 2020
1 parent 3bc3a41 commit 1b29b28
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 284 deletions.
31 changes: 21 additions & 10 deletions src/index.js
Expand Up @@ -87,26 +87,34 @@ export default function loader(content, map, meta) {
: false,
})
.then((result) => {
result
.warnings()
.forEach((warning) => this.emitWarning(new Warning(warning)));
for (const warning of result.warnings()) {
this.emitWarning(new Warning(warning));
}

const imports = [];
const apiImports = [];
const urlReplacements = [];
const icssReplacements = [];
const exports = [];
const replacers = [];

for (const message of result.messages) {
// eslint-disable-next-line default-case
switch (message.type) {
case 'import':
imports.push(message.value);
break;
case 'api-import':
apiImports.push(message.value);
break;
case 'url-replacement':
urlReplacements.push(message.value);
break;
case 'icss-replacement':
icssReplacements.push(message.value);
break;
case 'export':
exports.push(message.value);
break;
case 'replacer':
replacers.push(message.value);
break;
}
}

Expand All @@ -118,23 +126,26 @@ export default function loader(content, map, meta) {
this,
imports,
exportType,
sourceMap,
importLoaders,
esModule
);
const moduleCode = getModuleCode(
this,
result,
exportType,
esModule,
sourceMap,
replacers
importLoaders,
apiImports,
urlReplacements,
icssReplacements
);
const exportCode = getExportCode(
this,
exports,
exportType,
replacers,
localsConvention,
icssReplacements,
esModule
);

Expand Down
100 changes: 44 additions & 56 deletions src/plugins/postcss-icss-parser.js
Expand Up @@ -2,9 +2,7 @@ import postcss from 'postcss';
import { extractICSS, replaceValueSymbols, replaceSymbols } from 'icss-utils';
import { urlToRequest } from 'loader-utils';

const pluginName = 'postcss-icss-parser';

function normalizeIcssImports(icssImports) {
function makeRequestableIcssImports(icssImports) {
return Object.keys(icssImports).reduce((accumulator, url) => {
const tokensMap = icssImports[url];
const tokens = Object.keys(tokensMap);
Expand All @@ -30,60 +28,50 @@ function normalizeIcssImports(icssImports) {
}, {});
}

export default postcss.plugin(
pluginName,
() =>
function process(css, result) {
const importReplacements = Object.create(null);
const { icssImports, icssExports } = extractICSS(css);
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', importName, url },
});

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

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

importReplacements[token] = replacementName;

result.messages.push({
pluginName,
type: 'replacer',
value: {
type: 'icss-import',
importName,
replacementName,
localName,
},
});
});
});

if (Object.keys(importReplacements).length > 0) {
replaceSymbols(css, importReplacements);
export default postcss.plugin('postcss-icss-parser', () => (css, result) => {
const importReplacements = Object.create(null);
const extractedICSS = extractICSS(css);
const icssImports = makeRequestableIcssImports(extractedICSS.icssImports);

for (const [importIndex, url] of Object.keys(icssImports).entries()) {
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;

result.messages.push(
{
type: 'import',
value: { type: 'icss', importName, url },
},
{
type: 'api-import',
value: { type: 'internal', importName, dedupe: true },
}
);

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

for (const [replacementIndex, token] of tokens.entries()) {
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
const localName = tokenMap[token];

Object.keys(icssExports).forEach((name) => {
const value = replaceValueSymbols(
icssExports[name],
importReplacements
);

result.messages.push({
pluginName,
type: 'export',
value: { name, value },
});
importReplacements[token] = replacementName;

result.messages.push({
type: 'icss-replacement',
value: { replacementName, importName, localName },
});
}
);
}

if (Object.keys(importReplacements).length > 0) {
replaceSymbols(css, importReplacements);
}

const { icssExports } = extractedICSS;

for (const name of Object.keys(icssExports)) {
const value = replaceValueSymbols(icssExports[name], importReplacements);

result.messages.push({ type: 'export', value: { name, value } });
}
});
28 changes: 26 additions & 2 deletions src/plugins/postcss-import-parser.js
Expand Up @@ -7,6 +7,8 @@ import { normalizeUrl } from '../utils';
const pluginName = 'postcss-import-parser';

export default postcss.plugin(pluginName, (options) => (css, result) => {
const importsMap = new Map();

css.walkAtRules(/^import$/i, (atRule) => {
// Convert only top-level @import
if (atRule.parent.type !== 'root') {
Expand Down Expand Up @@ -96,10 +98,32 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {

atRule.remove();

if (isRequestable) {
const importKey = url;
let importName = importsMap.get(importKey);

if (!importName) {
importName = `___CSS_LOADER_AT_RULE_IMPORT_${importsMap.size}___`;
importsMap.set(importKey, importName);

result.messages.push({
type: 'import',
value: { type: '@import', importName, url },
});
}

result.messages.push({
type: 'api-import',
value: { type: 'internal', importName, media },
});

return;
}

result.messages.push({
pluginName,
type: 'import',
value: { type: '@import', isRequestable, url, media },
type: 'api-import',
value: { type: 'external', url, media },
});
});
});
39 changes: 27 additions & 12 deletions src/plugins/postcss-url-parser.js
Expand Up @@ -32,7 +32,7 @@ function walkUrls(parsed, callback) {
}

if (isImageSetFunc.test(node.value)) {
node.nodes.forEach((nNode) => {
for (const nNode of node.nodes) {
const { type, value } = nNode;

if (type === 'function' && isUrlFunc.test(value)) {
Expand All @@ -50,7 +50,7 @@ function walkUrls(parsed, callback) {
if (type === 'string') {
callback(nNode, value, true, true);
}
});
}

// Do not traverse inside `image-set`
// eslint-disable-next-line consistent-return
Expand All @@ -61,7 +61,9 @@ function walkUrls(parsed, callback) {

export default postcss.plugin(pluginName, (options) => (css, result) => {
const importsMap = new Map();
const replacersMap = new Map();
const replacementsMap = new Map();

let hasHelper = false;

css.walkDecls((decl) => {
if (!needParseDecl.test(decl.value)) {
Expand Down Expand Up @@ -100,6 +102,20 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
importName = `___CSS_LOADER_URL_IMPORT_${importsMap.size}___`;
importsMap.set(importKey, importName);

if (!hasHelper) {
result.messages.push({
pluginName,
type: 'import',
value: {
type: 'url',
importName: '___CSS_LOADER_GET_URL_IMPORT___',
url: require.resolve('../runtime/getUrl.js'),
},
});

hasHelper = true;
}

result.messages.push({
pluginName,
type: 'import',
Expand All @@ -111,25 +127,24 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
});
}

const replacerKey = JSON.stringify({ importKey, hash, needQuotes });

let replacerName = replacersMap.get(replacerKey);
const replacementKey = JSON.stringify({ importKey, hash, needQuotes });
let replacementName = replacementsMap.get(replacementKey);

if (!replacerName) {
replacerName = `___CSS_LOADER_URL_REPLACEMENT_${replacersMap.size}___`;
replacersMap.set(replacerKey, replacerName);
if (!replacementName) {
replacementName = `___CSS_LOADER_URL_REPLACEMENT_${replacementsMap.size}___`;
replacementsMap.set(replacementKey, replacementName);

result.messages.push({
pluginName,
type: 'replacer',
value: { type: 'url', replacerName, importName, hash, needQuotes },
type: 'url-replacement',
value: { replacementName, importName, hash, needQuotes },
});
}

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

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

0 comments on commit 1b29b28

Please sign in to comment.