diff --git a/src/index.js b/src/index.js index 4f0f20f4..547d6d5e 100644 --- a/src/index.js +++ b/src/index.js @@ -37,14 +37,9 @@ export default function loader(content, map, meta) { const callback = this.async(); const sourceMap = options.sourceMap || false; - if (sourceMap && map) { - // eslint-disable-next-line no-param-reassign - map = normalizeSourceMap(map); - } else { - // Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it - // eslint-disable-next-line no-param-reassign - map = null; - } + // 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) { @@ -140,7 +135,7 @@ export default function loader(content, map, meta) { const importCode = getImportCode(importItems, onlyLocals); const moduleCode = getModuleCode(result, sourceMap, onlyLocals); const exportCode = getExportCode(exportItems, onlyLocals); - const apiCode = getApiCode(this, sourceMap, importItems, moduleCode); + const apiCode = getApiCode(this, sourceMap, onlyLocals); return callback( null, diff --git a/src/plugins/postcss-icss-parser.js b/src/plugins/postcss-icss-parser.js index 9d8d1d3e..a0305568 100644 --- a/src/plugins/postcss-icss-parser.js +++ b/src/plugins/postcss-icss-parser.js @@ -1,9 +1,8 @@ import postcss from 'postcss'; import { extractICSS, replaceValueSymbols, replaceSymbols } from 'icss-utils'; import loaderUtils from 'loader-utils'; -import cc from 'camelcase'; -import { getImportItemCode } from '../utils'; +import { getExportItemCode, getImportItemCode } from '../utils'; const pluginName = 'postcss-icss-parser'; @@ -17,56 +16,6 @@ function hasImportMessage(messages, url) { ); } -function camelCase(str) { - return cc(str); -} - -function dashesCamelCase(str) { - return str.replace(/-+(\w)/g, (match, firstLetter) => - firstLetter.toUpperCase() - ); -} - -function getExportItem(key, value, localsStyle) { - let targetKey; - const items = []; - - function addEntry(k) { - items.push(`\t${JSON.stringify(k)}: ${JSON.stringify(value)}`); - } - - switch (localsStyle) { - case 'camelCase': - addEntry(key); - targetKey = camelCase(key); - - if (targetKey !== key) { - addEntry(targetKey); - } - break; - case 'camelCaseOnly': - addEntry(camelCase(key)); - break; - case 'dashes': - addEntry(key); - targetKey = dashesCamelCase(key); - - if (targetKey !== key) { - addEntry(targetKey); - } - break; - case 'dashesOnly': - addEntry(dashesCamelCase(key)); - break; - case 'asIs': - default: - addEntry(key); - break; - } - - return items; -} - export default postcss.plugin( pluginName, (options = {}) => @@ -118,9 +67,7 @@ export default postcss.plugin( result.messages.push({ pluginName, - export: getExportItem(name, value, options.exportLocalsStyle).join( - ',\n' - ), + export: getExportItemCode(name, value, options.exportLocalsStyle), type: 'export', item: { name, value }, }); diff --git a/src/plugins/postcss-import-parser.js b/src/plugins/postcss-import-parser.js index f4d531fb..36bb3796 100644 --- a/src/plugins/postcss-import-parser.js +++ b/src/plugins/postcss-import-parser.js @@ -1,7 +1,7 @@ import postcss from 'postcss'; import valueParser from 'postcss-value-parser'; -import { getImportItemCode } from '../utils'; +import { uniqWith, getImportItemCode } from '../utils'; const pluginName = 'postcss-import-parser'; @@ -86,22 +86,15 @@ function walkAtRules(css, result, filter) { return items; } -function uniq(array) { - return array.reduce( - (acc, d) => - !acc.find((el) => el.url === d.url && el.media === d.media) - ? [...acc, d] - : acc, - [] - ); -} - export default postcss.plugin( pluginName, (options = {}) => function process(css, result) { const traversed = walkAtRules(css, result, options.filter); - const paths = uniq(traversed); + const paths = uniqWith( + traversed, + (value, other) => value.url === other.url && value.media === other.media + ); paths.forEach((item) => { result.messages.push({ diff --git a/src/plugins/postcss-url-parser.js b/src/plugins/postcss-url-parser.js index 552fbaf7..c499cdc9 100644 --- a/src/plugins/postcss-url-parser.js +++ b/src/plugins/postcss-url-parser.js @@ -1,7 +1,7 @@ import postcss from 'postcss'; import valueParser from 'postcss-value-parser'; -import { getUrlHelperCode, getUrlItemCode } from '../utils'; +import { uniqWith, flatten, getUrlHelperCode, getUrlItemCode } from '../utils'; const pluginName = 'postcss-url-parser'; @@ -104,21 +104,6 @@ function walkDeclsWithUrl(css, result, filter) { return items; } -function uniqWith(array, comparator) { - return array.reduce( - (acc, d) => (!acc.some((item) => comparator(d, item)) ? [...acc, d] : acc), - [] - ); -} - -function flatten(array) { - return array.reduce((a, b) => a.concat(b), []); -} - -function isEqual(value, other) { - return value.url === other.url && value.needQuotes === other.needQuotes; -} - export default postcss.plugin( pluginName, (options = {}) => @@ -126,7 +111,8 @@ export default postcss.plugin( const traversed = walkDeclsWithUrl(css, result, options.filter); const paths = uniqWith( flatten(traversed.map((item) => item.urls)), - isEqual + (value, other) => + value.url === other.url && value.needQuotes === other.needQuotes ); if (paths.length === 0) { diff --git a/src/utils.js b/src/utils.js index 050961a9..1ddb4451 100644 --- a/src/utils.js +++ b/src/utils.js @@ -15,6 +15,24 @@ import modulesValues from 'postcss-modules-values'; import localByDefault from 'postcss-modules-local-by-default'; import extractImports from 'postcss-modules-extract-imports'; import modulesScope from 'postcss-modules-scope'; +import camelCase from 'camelcase'; + +function uniqWith(array, comparator) { + return array.reduce( + (acc, d) => (!acc.some((item) => comparator(d, item)) ? [...acc, d] : acc), + [] + ); +} + +function flatten(array) { + return array.reduce((a, b) => a.concat(b), []); +} + +function dashesCamelCase(str) { + return str.replace(/-+(\w)/g, (match, firstLetter) => + firstLetter.toUpperCase() + ); +} function getImportPrefix(loaderContext, importLoaders) { if (importLoaders === false) { @@ -206,9 +224,8 @@ function getUrlItemCode(item, loaderContext) { )})${hash ? ` + ${hash}` : ''}${needQuotes ? ', true' : ''});`; } -function getApiCode(loaderContext, sourceMap, importItems, moduleCode) { - // No imports and no module code - if (importItems.length === 0 && moduleCode.length === 0) { +function getApiCode(loaderContext, sourceMap, onlyLocals) { + if (onlyLocals) { return ''; } @@ -236,6 +253,46 @@ function getModuleCode(result, sourceMap, onlyLocals) { )}, ""${sourceMap && result.map ? `,${result.map}` : ''}]);\n`; } +function getExportItemCode(key, value, localsStyle) { + let targetKey; + const items = []; + + function addEntry(k) { + items.push(`\t${JSON.stringify(k)}: ${JSON.stringify(value)}`); + } + + switch (localsStyle) { + case 'camelCase': + addEntry(key); + targetKey = camelCase(key); + + if (targetKey !== key) { + addEntry(targetKey); + } + break; + case 'camelCaseOnly': + addEntry(camelCase(key)); + break; + case 'dashes': + addEntry(key); + targetKey = dashesCamelCase(key); + + if (targetKey !== key) { + addEntry(targetKey); + } + break; + case 'dashesOnly': + addEntry(dashesCamelCase(key)); + break; + case 'asIs': + default: + addEntry(key); + break; + } + + return items.join(',\n'); +} + function getExportCode(exportItems, onlyLocals) { if (exportItems.length === 0) { return ''; @@ -317,6 +374,9 @@ function prepareCode(file, messages, loaderContext, importPrefix, onlyLocals) { } export { + uniqWith, + flatten, + dashesCamelCase, getImportPrefix, getLocalIdent, getFilter, @@ -328,6 +388,7 @@ export { getApiCode, getImportCode, getModuleCode, + getExportItemCode, getExportCode, prepareCode, }; diff --git a/test/__snapshots__/exportOnlyLocals-option.test.js.snap b/test/__snapshots__/exportOnlyLocals-option.test.js.snap index f9f56480..3e3eff6f 100644 --- a/test/__snapshots__/exportOnlyLocals-option.test.js.snap +++ b/test/__snapshots__/exportOnlyLocals-option.test.js.snap @@ -3,8 +3,7 @@ exports[`modules true (mode: local): errors 1`] = `Array []`; exports[`modules true (mode: local): module 1`] = ` -"exports = module.exports = require(\\"../../../src/runtime/api.js\\")(false); -// Exports +"// Exports module.exports = { \\"v-def\\": \\"\\" + require(\\"-!../../../src/index.js??ref--4-0!./values.css\\")[\\"v-def\\"] + \\"\\", \\"v-other\\": \\"\\" + require(\\"-!../../../src/index.js??ref--4-0!./values.css\\")[\\"v-other\\"] + \\"\\",