-
-
Notifications
You must be signed in to change notification settings - Fork 603
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
92fe103
commit b5c9379
Showing
5 changed files
with
490 additions
and
448 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,91 +1,99 @@ | ||
import postcss from 'postcss'; | ||
import { extractICSS, replaceValueSymbols, replaceSymbols } from 'icss-utils'; | ||
|
||
import { normalizeUrl, resolveRequests, requestify } from '../utils'; | ||
|
||
export default postcss.plugin( | ||
'postcss-icss-parser', | ||
(options) => async (css) => { | ||
const importReplacements = Object.create(null); | ||
const { icssImports, icssExports } = extractICSS(css); | ||
const imports = new Map(); | ||
const tasks = []; | ||
|
||
// eslint-disable-next-line guard-for-in | ||
for (const url in icssImports) { | ||
const tokens = icssImports[url]; | ||
|
||
if (Object.keys(tokens).length === 0) { | ||
// eslint-disable-next-line no-continue | ||
continue; | ||
const plugin = (options = {}) => { | ||
return { | ||
postcssPlugin: 'postcss-icss-parser', | ||
async OnceExit(root) { | ||
const importReplacements = Object.create(null); | ||
const { icssImports, icssExports } = extractICSS(root); | ||
const imports = new Map(); | ||
const tasks = []; | ||
|
||
// eslint-disable-next-line guard-for-in | ||
for (const url in icssImports) { | ||
const tokens = icssImports[url]; | ||
|
||
if (Object.keys(tokens).length === 0) { | ||
// eslint-disable-next-line no-continue | ||
continue; | ||
} | ||
|
||
let normalizedUrl = url; | ||
let prefix = ''; | ||
|
||
const queryParts = normalizedUrl.split('!'); | ||
|
||
if (queryParts.length > 1) { | ||
normalizedUrl = queryParts.pop(); | ||
prefix = queryParts.join('!'); | ||
} | ||
|
||
const request = requestify( | ||
normalizeUrl(normalizedUrl, true), | ||
options.rootContext | ||
); | ||
const doResolve = async () => { | ||
const { resolver, context } = options; | ||
const resolvedUrl = await resolveRequests(resolver, context, [ | ||
...new Set([normalizedUrl, request]), | ||
]); | ||
|
||
return { url: resolvedUrl, prefix, tokens }; | ||
}; | ||
|
||
tasks.push(doResolve()); | ||
} | ||
|
||
let normalizedUrl = url; | ||
let prefix = ''; | ||
const results = await Promise.all(tasks); | ||
|
||
const queryParts = normalizedUrl.split('!'); | ||
for (let index = 0; index <= results.length - 1; index++) { | ||
const { url, prefix, tokens } = results[index]; | ||
const newUrl = prefix ? `${prefix}!${url}` : url; | ||
const importKey = newUrl; | ||
let importName = imports.get(importKey); | ||
|
||
if (queryParts.length > 1) { | ||
normalizedUrl = queryParts.pop(); | ||
prefix = queryParts.join('!'); | ||
} | ||
if (!importName) { | ||
importName = `___CSS_LOADER_ICSS_IMPORT_${imports.size}___`; | ||
imports.set(importKey, importName); | ||
|
||
const request = requestify( | ||
normalizeUrl(normalizedUrl, true), | ||
options.rootContext | ||
); | ||
const doResolve = async () => { | ||
const { resolver, context } = options; | ||
const resolvedUrl = await resolveRequests(resolver, context, [ | ||
...new Set([normalizedUrl, request]), | ||
]); | ||
|
||
return { url: resolvedUrl, prefix, tokens }; | ||
}; | ||
|
||
tasks.push(doResolve()); | ||
} | ||
|
||
const results = await Promise.all(tasks); | ||
|
||
for (let index = 0; index <= results.length - 1; index++) { | ||
const { url, prefix, tokens } = results[index]; | ||
const newUrl = prefix ? `${prefix}!${url}` : url; | ||
const importKey = newUrl; | ||
let importName = imports.get(importKey); | ||
|
||
if (!importName) { | ||
importName = `___CSS_LOADER_ICSS_IMPORT_${imports.size}___`; | ||
imports.set(importKey, importName); | ||
|
||
options.imports.push({ | ||
importName, | ||
url: options.urlHandler(newUrl), | ||
icss: true, | ||
index, | ||
}); | ||
|
||
options.api.push({ importName, dedupe: true, index }); | ||
} | ||
options.imports.push({ | ||
importName, | ||
url: options.urlHandler(newUrl), | ||
icss: true, | ||
index, | ||
}); | ||
|
||
for (const [replacementIndex, token] of Object.keys(tokens).entries()) { | ||
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${index}_REPLACEMENT_${replacementIndex}___`; | ||
const localName = tokens[token]; | ||
options.api.push({ importName, dedupe: true, index }); | ||
} | ||
|
||
importReplacements[token] = replacementName; | ||
for (const [replacementIndex, token] of Object.keys(tokens).entries()) { | ||
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${index}_REPLACEMENT_${replacementIndex}___`; | ||
const localName = tokens[token]; | ||
|
||
options.replacements.push({ replacementName, importName, localName }); | ||
importReplacements[token] = replacementName; | ||
|
||
options.replacements.push({ replacementName, importName, localName }); | ||
} | ||
} | ||
} | ||
|
||
if (Object.keys(importReplacements).length > 0) { | ||
replaceSymbols(css, importReplacements); | ||
} | ||
if (Object.keys(importReplacements).length > 0) { | ||
replaceSymbols(root, importReplacements); | ||
} | ||
|
||
for (const name of Object.keys(icssExports)) { | ||
const value = replaceValueSymbols( | ||
icssExports[name], | ||
importReplacements | ||
); | ||
|
||
options.exports.push({ name, value }); | ||
} | ||
}, | ||
}; | ||
}; | ||
|
||
for (const name of Object.keys(icssExports)) { | ||
const value = replaceValueSymbols(icssExports[name], importReplacements); | ||
plugin.postcss = true; | ||
|
||
options.exports.push({ name, value }); | ||
} | ||
} | ||
); | ||
export default plugin; |
Oops, something went wrong.