Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reduce count of require #1004

Merged
merged 10 commits into from
Dec 5, 2019
Next Next commit
refactor: reduce count of require
alexander-akait committed Dec 4, 2019
commit decacd389be94fa63da6353fb7b39dee258d2973
24 changes: 12 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -54,20 +54,22 @@ export default function loader(content, map, meta) {
plugins.push(...getModulesPlugins(options, this));
}

const exportType = options.onlyLocals ? 'locals' : 'full';

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

plugins.push(icssParser());

if (options.import !== false) {
if (options.import !== false && exportType === 'full') {
plugins.push(
importParser({
filter: getFilter(options.import, this.resourcePath),
})
);
}

if (options.url !== false) {
if (options.url !== false && exportType === 'full') {
plugins.push(
urlParser({
filter: getFilter(options.url, this.resourcePath, (value) =>
@@ -109,22 +111,20 @@ export default function loader(content, map, meta) {
}
}

const isNormalMode = !options.onlyLocals;

const apiCode = isNormalMode ? getApiCode(this, sourceMap) : '';
const apiCode = exportType === 'full' ? getApiCode(this, sourceMap) : '';
const importCode =
isNormalMode && imports.length > 0
? getImportCode(this, imports, { importPrefix })
imports.length > 0
? getImportCode(this, imports, { importPrefix, exportType })
: '';
const moduleCode =
exportType === 'full'
? getModuleCode(this, result, replacers, sourceMap)
: '';
const moduleCode = isNormalMode
? getModuleCode(this, result, replacers, { sourceMap, importPrefix })
: '';
const exportCode =
exports.length > 0
? getExportCode(this, exports, replacers, {
importPrefix,
localsConvention: options.localsConvention,
onlyLocals: options.onlyLocals,
exportType,
})
: '';

58 changes: 21 additions & 37 deletions src/plugins/postcss-icss-parser.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,47 @@
import postcss from 'postcss';
import { extractICSS, replaceValueSymbols, replaceSymbols } from 'icss-utils';
import loaderUtils from 'loader-utils';

const pluginName = 'postcss-icss-parser';

function hasImportMessage(messages, url) {
return messages.find(
(message) =>
message.pluginName === pluginName &&
message.type === 'import' &&
message.value &&
message.value.url === url &&
message.value.media === ''
);
}

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

let index = 0;
Object.keys(icssImports).forEach((url, importIndex) => {
const tokens = Object.keys(icssImports[url]);

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

for (const importUrl of Object.keys(icssImports)) {
const url = loaderUtils.parseString(importUrl);
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;

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

for (const token of Object.keys(icssImports[importUrl])) {
const name = `___CSS_LOADER_IMPORT___${index}___`;
tokens.forEach((token, replacementIndex) => {
const name = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
const localName = icssImports[url][token];

index += 1;
importReplacements[token] = name;

result.messages.push({
pluginName,
type: 'replacer',
value: {
type: 'icss-import',
name,
url,
export: icssImports[importUrl][token],
},
value: { type: 'icss-import', name, importName, localName },
});

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

replaceSymbols(css, importReplacements);

for (const exportName of Object.keys(icssExports)) {
const name = exportName;
Object.keys(icssExports).forEach((name) => {
const value = replaceValueSymbols(
icssExports[name],
importReplacements
@@ -68,6 +52,6 @@ export default postcss.plugin(
type: 'export',
value: { name, value },
});
}
});
}
);
7 changes: 5 additions & 2 deletions src/plugins/postcss-import-parser.js
Original file line number Diff line number Diff line change
@@ -96,11 +96,14 @@ export default postcss.plugin(
(value, other) => value.url === other.url && value.media === other.media
);

paths.forEach((item) => {
paths.forEach((item, index) => {
const { url, media } = item;
const name = `___CSS_LOADER_IMPORT___${index}___`;

result.messages.push({
pluginName,
type: 'import',
value: { type: '@import', url: item.url, media: item.media },
value: { type: '@import', name, url, media },
});
});
}
46 changes: 21 additions & 25 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -228,7 +228,11 @@ function getImportCode(loaderContext, imports, options) {
return;
}

items.push(`exports.i(require(${url}), ${media});`);
items.push(`var ${item.name} = require(${url});`);

if (options.exportType === 'full') {
items.push(`exports.i(${item.name}, ${media});`);
}
}

if (item.type === 'url') {
@@ -274,9 +278,9 @@ function getImportCode(loaderContext, imports, options) {
return `// Imports\n${items.join('\n')}\n`;
}

function getModuleCode(loaderContext, result, replacers, options) {
function getModuleCode(loaderContext, result, replacers, sourceMap) {
const { css, map } = result;
const sourceMapValue = options.sourceMap && map ? `,${map}` : '';
const sourceMapValue = sourceMap && map ? `,${map}` : '';
let cssCode = JSON.stringify(css);

replacers.forEach((replacer) => {
@@ -287,17 +291,11 @@ function getModuleCode(loaderContext, result, replacers, options) {
}

if (type === 'icss-import') {
const url = stringifyRequest(
loaderContext,
options.importPrefix + urlToRequest(replacer.url)
);
const exportName = JSON.stringify(replacer.export);
cssCode = cssCode.replace(new RegExp(name, 'g'), () => {
const { importName, localName } = replacer;

// eslint-disable-next-line no-param-reassign
cssCode = cssCode.replace(
new RegExp(replacer.name, 'g'),
`" + require(${url}).locals[${exportName}] + "`
);
return `" + ${importName}.locals[${JSON.stringify(localName)}] + "`;
});
}
});

@@ -356,22 +354,20 @@ function getExportCode(loaderContext, exports, replacers, options) {
}
});

const exportType = options.onlyLocals ? 'module.exports' : 'exports.locals';
let exportCode = `// Exports\n${exportType} = {\n${items.join(',\n')}\n};`;
let exportCode = `// Exports\n${
options.exportType === 'locals' ? 'module.exports' : 'exports.locals'
} = {\n${items.join(',\n')}\n};`;

replacers.forEach((replacer) => {
const { type } = replacer;

if (type === 'icss-import') {
const importUrl = options.importPrefix + urlToRequest(replacer.url);
if (replacer.type === 'icss-import') {
const { name, importName } = replacer;

exportCode = exportCode.replace(new RegExp(replacer.name, 'g'), () => {
const url = stringifyRequest(loaderContext, importUrl);
const importName = JSON.stringify(replacer.export);
exportCode = exportCode.replace(new RegExp(name, 'g'), () => {
const localName = JSON.stringify(replacer.localName);

return options.onlyLocals
? `" + require(${url})[${importName}] + "`
: `" + require(${url}).locals[${importName}] + "`;
return options.exportType === 'locals'
? `" + ${importName}[${localName}] + "`
: `" + ${importName}.locals[${localName}] + "`;
});
}
});
Loading