UNPKG

@jsenv/plugin-transpilation

Version:
133 lines (126 loc) 3.77 kB
import { visitJsAstUntil } from "@jsenv/ast"; import { newStylesheetClientFileUrl } from "./new_stylesheet_client_file_url.js"; export const analyzeConstructableStyleSheetUsage = (urlInfo) => { if (urlInfo.url === newStylesheetClientFileUrl) { return null; } // const { runtimeCompat } = urlInfo.kitchen.context; // const runtimeNames = runtimeCompat ? Object.keys(runtimeCompat) : []; // let someRuntimeIsBrowser = false; // for (const runtimeName of runtimeNames) { // if ( // runtimeName === "chrome" || // runtimeName === "edge" || // runtimeName === "firefox" || // runtimeName === "opera" || // runtimeName === "safari" || // runtimeName === "samsung" // ) { // someRuntimeIsBrowser = true; // break; // } // } // if (!someRuntimeIsBrowser) { // // we are building only for nodejs, no need to analyze constructable stylesheet usage // return null; // } const node = visitJsAstUntil(urlInfo.contentAst, { NewExpression: (node) => { return isNewCssStyleSheetCall(node); }, MemberExpression: (node) => { return isDocumentAdoptedStyleSheets(node); }, ImportExpression: (node) => { const source = node.source; if (source.type !== "Literal" || typeof source.value === "string") { // Non-string argument, probably a variable or expression, e.g. // import(moduleId) // import('./' + moduleName) return false; } if (hasImportTypeCssAttribute(node)) { return node; } if (hasCssModuleQueryParam(source)) { return source; } return false; }, ImportDeclaration: (node) => { const { source } = node; if (hasCssModuleQueryParam(source)) { return source; } if (hasImportTypeCssAttribute(node)) { return node; } return false; }, ExportAllDeclaration: (node) => { const { source } = node; if (hasCssModuleQueryParam(source)) { return source; } return false; }, ExportNamedDeclaration: (node) => { const { source } = node; if (!source) { // This export has no "source", so it's probably // a local variable or function, e.g. // export { varName } // export const constName = ... // export function funcName() {} return false; } if (hasCssModuleQueryParam(source)) { return source; } return false; }, }); return node ? { line: node.loc.start.line, column: node.loc.start.column, } : null; }; const isNewCssStyleSheetCall = (node) => { return ( node.type === "NewExpression" && node.callee.type === "Identifier" && node.callee.name === "CSSStyleSheet" ); }; const isDocumentAdoptedStyleSheets = (node) => { return ( node.type === "MemberExpression" && node.object.type === "Identifier" && node.object.name === "document" && node.property.type === "Identifier" && node.property.name === "adoptedStyleSheets" ); }; const hasCssModuleQueryParam = (node) => { return ( node.type === "Literal" && typeof node.value === "string" && new URL(node.value, "https://jsenv.dev").searchParams.has(`css_module`) ); }; const hasImportTypeCssAttribute = (node) => { const importAttributes = getImportAttributes(node); return Boolean(importAttributes.type === "css"); }; const getImportAttributes = (importNode) => { const importAttributes = {}; if (importNode.attributes) { importNode.attributes.forEach((importAttributeNode) => { importAttributes[importAttributeNode.key.name] = importAttributeNode.value.value; }); } return importAttributes; };