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

refactor: future build @import #1390

Merged
merged 1 commit into from Oct 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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