Skip to content

Commit

Permalink
refactor: future build @import (#1390)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Oct 26, 2021
1 parent 8946be4 commit 897e7dd
Show file tree
Hide file tree
Showing 16 changed files with 259 additions and 78 deletions.
4 changes: 2 additions & 2 deletions src/index.js
Expand Up @@ -71,7 +71,8 @@ export default async function loader(content, map, meta) {
if (shouldUseImportPlugin(options)) {
plugins.push(
importParser({
isSupportAbsoluteURL,
isSupportAbsoluteURL: false,
isSupportDataURL: false,
isCSSStyleSheet: options.exportType === "css-style-sheet",
loaderContext: this,
imports: importPluginImports,
Expand Down Expand Up @@ -100,7 +101,6 @@ export default async function loader(content, map, meta) {
context: this.context,
rootContext: this.rootContext,
filter: getFilter(options.url.filter, this.resourcePath),
needToResolveURL,
resolver: needToResolveURL
? this.getResolve({ mainFiles: [], extensions: [] })
: // eslint-disable-next-line no-undefined
Expand Down
41 changes: 28 additions & 13 deletions src/plugins/postcss-import-parser.js
Expand Up @@ -3,12 +3,12 @@ import valueParser from "postcss-value-parser";
import {
normalizeUrl,
resolveRequests,
isUrlRequestable,
isURLRequestable,
requestify,
WEBPACK_IGNORE_COMMENT_REGEXP,
} from "../utils";

function parseNode(atRule, key) {
function parseNode(atRule, key, options) {
// Convert only top-level @import
if (atRule.parent.type !== "root") {
return;
Expand Down Expand Up @@ -97,10 +97,11 @@ function parseNode(atRule, key) {

url = normalizeUrl(url, isStringValue);

const isRequestable = isUrlRequestable(url);
const { requestable, needResolve } = isURLRequestable(url, options);

let prefix;

if (isRequestable) {
if (requestable && needResolve) {
const queryParts = url.split("!");

if (queryParts.length > 1) {
Expand Down Expand Up @@ -165,7 +166,16 @@ function parseNode(atRule, key) {
}

// eslint-disable-next-line consistent-return
return { atRule, prefix, url, layer, supports, media, isRequestable };
return {
atRule,
prefix,
url,
layer,
supports,
media,
requestable,
needResolve,
};
}

const plugin = (options = {}) => {
Expand All @@ -189,10 +199,15 @@ const plugin = (options = {}) => {
return;
}

const { isSupportDataURL, isSupportAbsoluteURL } = options;

let parsedAtRule;

try {
parsedAtRule = parseNode(atRule, "params", result);
parsedAtRule = parseNode(atRule, "params", {
isSupportAbsoluteURL,
isSupportDataURL,
});
} catch (error) {
result.warn(error.message, { node: error.node });
}
Expand Down Expand Up @@ -223,7 +238,8 @@ const plugin = (options = {}) => {
parsedAtRules.map(async (parsedAtRule) => {
const {
atRule,
isRequestable,
requestable,
needResolve,
prefix,
url,
layer,
Expand All @@ -245,7 +261,7 @@ const plugin = (options = {}) => {
}
}

if (isRequestable) {
if (needResolve) {
const request = requestify(url, loaderContext.rootContext);
const resolvedUrl = await resolveRequests(
resolver,
Expand All @@ -272,14 +288,14 @@ const plugin = (options = {}) => {
supports,
media,
prefix,
isRequestable,
requestable,
};
}

atRule.remove();

// eslint-disable-next-line consistent-return
return { url, layer, supports, media, prefix, isRequestable };
return { url, layer, supports, media, prefix, requestable };
})
);

Expand All @@ -293,10 +309,9 @@ const plugin = (options = {}) => {
continue;
}

const { url, isRequestable, layer, supports, media } =
resolvedAtRule;
const { url, requestable, layer, supports, media } = resolvedAtRule;

if (!isRequestable) {
if (!requestable) {
options.api.push({ url, layer, supports, media, index });

// eslint-disable-next-line no-continue
Expand Down
83 changes: 49 additions & 34 deletions src/plugins/postcss-url-parser.js
Expand Up @@ -4,8 +4,7 @@ import {
resolveRequests,
normalizeUrl,
requestify,
isUrlRequestable,
isDataUrl,
isURLRequestable,
WEBPACK_IGNORE_COMMENT_REGEXP,
} from "../utils";

Expand Down Expand Up @@ -48,30 +47,16 @@ function getWebpackIgnoreCommentValue(index, nodes, inBetween) {
return matched && matched[2] === "true";
}

function shouldHandleURL(url, declaration, result, options = {}) {
function shouldHandleURL(url, declaration, result, options) {
if (url.length === 0) {
result.warn(`Unable to find uri in '${declaration.toString()}'`, {
node: declaration,
});

return false;
return { requestable: false, needResolve: false };
}

if (isDataUrl(url) && options.isSupportDataURL) {
try {
decodeURIComponent(url);
} catch (ignoreError) {
return false;
}

return true;
}

if (!isUrlRequestable(url, options.isSupportAbsoluteURL)) {
return false;
}

return true;
return isURLRequestable(url, options);
}

function parseDeclaration(declaration, key, result, options) {
Expand Down Expand Up @@ -138,15 +123,24 @@ function parseDeclaration(declaration, key, result, options) {
const { nodes } = valueNode;
const isStringValue = nodes.length !== 0 && nodes[0].type === "string";
let url = isStringValue ? nodes[0].value : valueParser.stringify(nodes);

url = normalizeUrl(url, isStringValue);

const { requestable, needResolve } = shouldHandleURL(
url,
declaration,
result,
options
);

// Do not traverse inside `url`
if (!shouldHandleURL(url, declaration, result, options)) {
if (!requestable) {
// eslint-disable-next-line consistent-return
return false;
}

const queryParts = url.split("!");

let prefix;

if (queryParts.length > 1) {
Expand All @@ -161,6 +155,7 @@ function parseDeclaration(declaration, key, result, options) {
prefix,
url,
needQuotes: false,
needResolve,
});

// eslint-disable-next-line consistent-return
Expand Down Expand Up @@ -194,15 +189,24 @@ function parseDeclaration(declaration, key, result, options) {
let url = isStringValue
? nodes[0].value
: valueParser.stringify(nodes);

url = normalizeUrl(url, isStringValue);

const { requestable, needResolve } = shouldHandleURL(
url,
declaration,
result,
options
);

// Do not traverse inside `url`
if (!shouldHandleURL(url, declaration, result, options)) {
if (!requestable) {
// eslint-disable-next-line consistent-return
return false;
}

const queryParts = url.split("!");

let prefix;

if (queryParts.length > 1) {
Expand All @@ -217,6 +221,7 @@ function parseDeclaration(declaration, key, result, options) {
prefix,
url,
needQuotes: false,
needResolve,
});
} else if (type === "string") {
needIgnore = getWebpackIgnoreCommentValue(
Expand All @@ -239,13 +244,21 @@ function parseDeclaration(declaration, key, result, options) {

let url = normalizeUrl(value, true);

const { requestable, needResolve } = shouldHandleURL(
url,
declaration,
result,
options
);

// Do not traverse inside `url`
if (!shouldHandleURL(url, declaration, result, options)) {
if (!requestable) {
// eslint-disable-next-line consistent-return
return false;
}

const queryParts = url.split("!");

let prefix;

if (queryParts.length > 1) {
Expand All @@ -260,6 +273,7 @@ function parseDeclaration(declaration, key, result, options) {
prefix,
url,
needQuotes: true,
needResolve,
});
}
}
Expand Down Expand Up @@ -301,7 +315,7 @@ const plugin = (options = {}) => {

const resolvedDeclarations = await Promise.all(
parsedDeclarations.map(async (parsedDeclaration) => {
const { url } = parsedDeclaration;
const { url, needResolve } = parsedDeclaration;

if (options.filter) {
const needKeep = await options.filter(url);
Expand All @@ -312,7 +326,7 @@ const plugin = (options = {}) => {
}
}

if (isDataUrl(url)) {
if (!needResolve) {
// eslint-disable-next-line consistent-return
return parsedDeclaration;
}
Expand All @@ -323,30 +337,31 @@ const plugin = (options = {}) => {
let hash = query ? "?" : "";
hash += hashOrQuery ? `#${hashOrQuery}` : "";

const { needToResolveURL, rootContext } = options;
const { resolver, rootContext } = options;
const request = requestify(
pathname,
rootContext,
needToResolveURL
Boolean(resolver)
);

if (!needToResolveURL) {
if (!resolver) {
// eslint-disable-next-line consistent-return
return { ...parsedDeclaration, url: request, hash };
}

const { resolver, context } = options;
const resolvedUrl = await resolveRequests(resolver, context, [
...new Set([request, url]),
]);
const resolvedURL = await resolveRequests(
resolver,
options.context,
[...new Set([request, url])]
);

if (!resolvedUrl) {
if (!resolvedURL) {
// eslint-disable-next-line consistent-return
return;
}

// eslint-disable-next-line consistent-return
return { ...parsedDeclaration, url: resolvedUrl, hash };
return { ...parsedDeclaration, url: resolvedURL, hash };
})
);

Expand Down Expand Up @@ -391,7 +406,7 @@ const plugin = (options = {}) => {
options.imports.push({
type: "url",
importName,
url: options.needToResolveURL
url: options.resolver
? options.urlHandler(newUrl)
: JSON.stringify(newUrl),
index,
Expand Down

0 comments on commit 897e7dd

Please sign in to comment.