You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1 line
16 KiB
Plaintext

{"version":3,"sources":["../src/index.ts","../src/extractors/regex.ts","../src/extractors/default-extractor.ts"],"sourcesContent":["import { PurgeCSS } from 'purgecss';\nimport { defaultExtractor } from './extractors/default-extractor';\nimport { walk } from 'estree-walker';\nimport { join } from 'path';\nimport type { ResolvedConfig, Plugin } from 'vite';\nimport type { ComplexSafelist, StringRegExpArray, UserDefinedOptions } from 'purgecss';\n\ntype Extractor = (content: string) => string[];\n\ntype Options = Partial<UserDefinedOptions> & {\n\tsafelist?: ComplexSafelist;\n};\ntype PurgeOptions = Omit<Options, 'css'>;\n\nconst EXT_CSS = /\\.(css)$/;\nconst MAX_STRING_LITERAL_LENGTH = 50_000;\n\nexport function purgeCss(purgeOptions?: PurgeOptions): Plugin {\n\tlet viteConfig: ResolvedConfig;\n\tconst selectors = new Set<string>();\n\tconst standard: StringRegExpArray = [\n\t\t'*',\n\t\t'html',\n\t\t'body',\n\t\t/aria-current/,\n\t\t// fix for pseudo-class functions that begin with `:` getting purged (e.g. `:is`)\n\t\t// see: https://github.com/FullHuman/purgecss/issues/978\n\t\t/^\\:[-a-z]+$/,\n\t\t...(purgeOptions?.safelist?.standard ?? []),\n\t];\n\tconst extractor = (purgeOptions?.defaultExtractor as Extractor) ?? defaultExtractor();\n\tconst moduleIds = new Set<string>();\n\n\treturn {\n\t\tname: 'vite-plugin-tailwind-purgecss',\n\t\tapply: 'build',\n\t\tenforce: 'post',\n\n\t\tload(id) {\n\t\t\tif (EXT_CSS.test(id)) return;\n\t\t\tmoduleIds.add(id);\n\t\t},\n\n\t\tconfigResolved(config) {\n\t\t\tviteConfig = config;\n\t\t},\n\n\t\tasync generateBundle(options, bundle) {\n\t\t\ttype ChunkOrAsset = (typeof bundle)[string];\n\t\t\ttype Asset = Extract<ChunkOrAsset, { type: 'asset' }>;\n\t\t\tconst assets: Record<string, Asset> = {};\n\n\t\t\tfor (const id of moduleIds) {\n\t\t\t\tconst info = this.getModuleInfo(id);\n\t\t\t\tif (info?.isIncluded !== true || info.code === null) continue;\n\n\t\t\t\tconst ast = this.parse(info.code);\n\n\t\t\t\t// @ts-expect-error mismatched node types\n\t\t\t\twalk(ast, {\n\t\t\t\t\tenter(node, parent, key, index) {\n\t\t\t\t\t\tif (node.type === 'Literal' && typeof node.value === 'string') {\n\t\t\t\t\t\t\tnode.value.split(/\\s+/).forEach((word) => {\n\t\t\t\t\t\t\t\tif (word.length < MAX_STRING_LITERAL_LENGTH) {\n\t\t\t\t\t\t\t\t\textractor(word).forEach((selector) => selectors.add(selector));\n\t\t\t\t\t\t\t\t} else selectors.add(word);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (node.type === 'Identifier') {\n\t\t\t\t\t\t\tselectors.add(node.name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (node.type === 'TemplateElement') {\n\t\t\t\t\t\t\tconst value = node.value.cooked ?? node.value.raw;\n\t\t\t\t\t\t\tvalue.split(/\\s+/).forEach((word) => {\n\t\t\t\t\t\t\t\tif (word.length < MAX_STRING_LITERAL_LENGTH) {\n\t\t\t\t\t\t\t\t\textractor(word).forEach((selector) => selectors.add(selector));\n\t\t\t\t\t\t\t\t} else selectors.add(word);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfor (const [fileName, chunkOrAsset] of Object.entries(bundle)) {\n\t\t\t\tif (chunkOrAsset.type === 'asset' && EXT_CSS.test(fileName)) {\n\t\t\t\t\tassets[fileName] = chunkOrAsset;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const selector of selectors) {\n\t\t\t\tstandard.push(selector);\n\t\t\t}\n\n\t\t\tfor (const [fileName, asset] of Object.entries(assets)) {\n\t\t\t\tconst purgeCSSResult = await new PurgeCSS().purge({\n\t\t\t\t\t...purgeOptions,\n\t\t\t\t\tcontent: [join(viteConfig.root, '**/*.html'), ...(purgeOptions?.content ?? [])],\n\t\t\t\t\tcss: [{ raw: (asset.source as string).trim(), name: fileName }],\n\t\t\t\t\trejected: true,\n\t\t\t\t\trejectedCss: true,\n\t\t\t\t\tsafelist: {\n\t\t\t\t\t\t...purgeOptions?.safelist,\n\t\t\t\t\t\tstandard,\n\t\t\t\t\t\tgreedy: [/svelte-/, /data-theme/, ...(purgeOptions?.safelist?.greedy ?? [])],\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tif (purgeCSSResult[0]) {\n\t\t\t\t\t// prevent the original from being written\n\t\t\t\t\tdelete bundle[asset.fileName];\n\n\t\t\t\t\t// emit the newly purged css file\n\t\t\t\t\tthis.emitFile({\n\t\t\t\t\t\t...asset,\n\t\t\t\t\t\ttype: 'asset',\n\t\t\t\t\t\tsource: purgeCSSResult[0].css,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport default purgeCss;\n","const REGEX_SPECIAL = /[\\\\^$.*+?()[\\]{}|]/g;\nconst REGEX_HAS_SPECIAL = RegExp(REGEX_SPECIAL.source);\n\nfunction toSource(source: string | RegExp | Array<string | RegExp>) {\n\tsource = Array.isArray(source) ? source : [source];\n\n\tsource = source.map((item) => (item instanceof RegExp ? item.source : item));\n\n\treturn source.join('');\n}\n\nexport function pattern(source: string | RegExp | Array<string | RegExp>) {\n\treturn new RegExp(toSource(source), 'g');\n}\n\nexport function withoutCapturing(source: string | RegExp | Array<string | RegExp>) {\n\treturn new RegExp(`(?:${toSource(source)})`, 'g');\n}\n\nexport function any(sources: Array<string | RegExp>) {\n\treturn `(?:${sources.map(toSource).join('|')})`;\n}\n\nexport function optional(source: string | RegExp) {\n\treturn `(?:${toSource(source)})?`;\n}\n\nexport function zeroOrMore(source: string | RegExp | Array<string | RegExp>) {\n\treturn `(?:${toSource(source)})*`;\n}\n\n/**\n * Generate a RegExp that matches balanced brackets for a given depth\n * We have to specify a depth because JS doesn't support recursive groups using ?R\n *\n * Based on https://stackoverflow.com/questions/17759004/how-to-match-string-within-parentheses-nested-in-java/17759264#17759264\n */\nexport function nestedBrackets(open: string, close: string, depth = 1): RegExp {\n\treturn withoutCapturing([\n\t\tescape(open),\n\t\t/[^\\s]*/,\n\t\tdepth === 1\n\t\t\t? `[^${escape(open)}${escape(close)}\\s]*`\n\t\t\t: any([`[^${escape(open)}${escape(close)}\\s]*`, nestedBrackets(open, close, depth - 1)]),\n\t\t/[^\\s]*/,\n\t\tescape(close),\n\t]);\n}\n\nexport function escape(str: string) {\n\treturn str && REGEX_HAS_SPECIAL.test(str) ? str.replace(REGEX_SPECIAL, '\\\\$&') : str || '';\n}\n","// Sourced from Tailwindcss\nimport * as regex from './regex';\n\nexport function defaultExtractor() {\n\tlet patterns = Array.from(buildRegExps());\n\n\treturn (content: string) => {\n\t\tlet results: string[] = [];\n\n\t\tfor (let pattern of patterns) {\n\t\t\tresults = [...results, ...(content.match(pattern) ?? [])];\n\t\t}\n\n\t\treturn results.filter((v) => v !== undefined).map(clipAtBalancedParens);\n\t};\n}\n\nfunction* buildRegExps() {\n\tlet separator = ':';\n\tlet prefix = '';\n\n\tlet utility = regex.any([\n\t\t// Arbitrary properties (without square brackets)\n\t\t/\\[[^\\s:'\"`]+:[^\\s\\[\\]]+\\]/,\n\n\t\t// Arbitrary properties with balanced square brackets\n\t\t// This is a targeted fix to continue to allow theme()\n\t\t// with square brackets to work in arbitrary properties\n\t\t// while fixing a problem with the regex matching too much\n\t\t/\\[[^\\s:'\"`]+:[^\\s]+?\\[[^\\s]+\\][^\\s]+?\\]/,\n\n\t\t// Utilities\n\t\tregex.pattern([\n\t\t\t// Utility Name / Group Name\n\t\t\t/-?(?:\\w+)/,\n\n\t\t\t// Normal/Arbitrary values\n\t\t\tregex.optional(\n\t\t\t\tregex.any([\n\t\t\t\t\tregex.pattern([\n\t\t\t\t\t\t// Arbitrary values\n\t\t\t\t\t\t/-(?:\\w+-)*\\[[^\\s:]+\\]/,\n\n\t\t\t\t\t\t// Not immediately followed by an `{[(`\n\t\t\t\t\t\t/(?![{([]])/,\n\n\t\t\t\t\t\t// optionally followed by an opacity modifier\n\t\t\t\t\t\t/(?:\\/[^\\s'\"`\\\\><$]*)?/,\n\t\t\t\t\t]),\n\n\t\t\t\t\tregex.pattern([\n\t\t\t\t\t\t// Arbitrary values\n\t\t\t\t\t\t/-(?:\\w+-)*\\[[^\\s]+\\]/,\n\n\t\t\t\t\t\t// Not immediately followed by an `{[(`\n\t\t\t\t\t\t/(?![{([]])/,\n\n\t\t\t\t\t\t// optionally followed by an opacity modifier\n\t\t\t\t\t\t/(?:\\/[^\\s'\"`\\\\$]*)?/,\n\t\t\t\t\t]),\n\n\t\t\t\t\t// Normal values w/o quotes — may include an opacity modifier\n\t\t\t\t\t/[-\\/][^\\s'\"`\\\\$={><]*/,\n\t\t\t\t])\n\t\t\t),\n\t\t]),\n\t]);\n\n\tlet variantPatterns = [\n\t\t// Without quotes\n\t\tregex.any([\n\t\t\t// This is here to provide special support for the `@` variant\n\t\t\tregex.pattern([/@\\[[^\\s\"'`]+\\](\\/[^\\s\"'`]+)?/, separator]),\n\n\t\t\tregex.pattern([/([^\\s\"'`\\[\\\\]+-)?\\[[^\\s\"'`]+\\]/, separator]),\n\t\t\tregex.pattern([/[^\\s\"'`\\[\\\\]+/, separator]),\n\t\t]),\n\n\t\t// With quotes allowed\n\t\tregex.any([\n\t\t\tregex.pattern([/([^\\s\"'`\\[\\\\]+-)?\\[[^\\s`]+\\]/, separator]),\n\t\t\tregex.pattern([/[^\\s`\\[\\\\]+/, separator]),\n\t\t]),\n\t];\n\n\tfor (const variantPattern of variantPatterns) {\n\t\tyield regex.pattern([\n\t\t\t// Variants\n\t\t\t'((?=((',\n\t\t\tvariantPattern,\n\t\t\t')+))\\\\2)?',\n\n\t\t\t// Important (optional)\n\t\t\t/!?/,\n\n\t\t\tprefix,\n\t\t\tutility,\n\t\t]);\n\t}\n\n\t// 5. Inner matches\n\tyield /[^<>\"'`\\s.(){}[\\]#=%$]*[^<>\"'`\\s.(){}[\\]#=%:$]/g;\n}\n\n// We want to capture any \"special\" characters\n// AND the characters immediately following them (if there is one)\nlet SPECIALS = /([\\[\\]'\"`])([^\\[\\]'\"`])?/g;\nlet ALLOWED_CLASS_CHARACTERS = /[^\"'`\\s<>\\]]+/;\n\n/**\n * Clips a string ensuring that parentheses, quotes, etc… are balanced\n * Used for arbitrary values only\n *\n * We will go past the end of the balanced parens until we find a non-class character\n *\n * Depth matching behavior:\n * w-[calc(100%-theme('spacing[some_key][1.5]'))]']\n * ┬ ┬ ┬┬ ┬ ┬┬ ┬┬┬┬┬┬┬\n * 1 2 3 4 34 3 210 END\n * ╰────┴──────────┴────────┴────────┴┴───┴─┴┴┴\n *\n */\nfunction clipAtBalancedParens(input: string) {\n\t// We are care about this for arbitrary values\n\tif (!input.includes('-[')) {\n\t\treturn input;\n\t}\n\n\tlet depth = 0;\n\tlet openStringTypes: string[] = [];\n\n\t// Find all parens, brackets, quotes, etc\n\t// Stop when we end at a balanced pair\n\t// This is naive and will treat mismatched parens as balanced\n\t// This shouldn't be a problem in practice though\n\tlet matches = input.matchAll(SPECIALS);\n\n\t// We can't use lookbehind assertions because we have to support Safari\n\t// So, instead, we've emulated it using capture groups and we'll re-work the matches to accommodate\n\tconst matched = Array.from(matches).flatMap((match) => {\n\t\tconst [, ...groups] = match;\n\n\t\treturn groups.map((group, idx) =>\n\t\t\tObject.assign([], match, {\n\t\t\t\t// @ts-expect-error\n\t\t\t\tindex: match.index + idx,\n\t\t\t\t0: group,\n\t\t\t})\n\t\t);\n\t});\n\n\tfor (let match of matched) {\n\t\tlet char = match[0];\n\t\tlet inStringType = openStringTypes.at(-1);\n\n\t\tif (char === inStringType) {\n\t\t\topenStringTypes.pop();\n\t\t} else if (char === \"'\" || char === '\"' || char === '`') {\n\t\t\topenStringTypes.push(char);\n\t\t}\n\n\t\tif (inStringType) {\n\t\t\tcontinue;\n\t\t} else if (char === '[') {\n\t\t\tdepth++;\n\t\t\tcontinue;\n\t\t} else if (char === ']') {\n\t\t\tdepth--;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// We've gone one character past the point where we should stop\n\t\t// This means that there was an extra closing `]`\n\t\t// We'll clip to just before it\n\t\tif (depth < 0) {\n\t\t\treturn input.substring(0, match.index - 1);\n\t\t}\n\n\t\t// We've finished balancing the brackets but there still may be characters that can be included\n\t\t// For example in the class `text-[#336699]/[.35]`\n\t\t// The depth goes to `0` at the closing `]` but goes up again at the `[`\n\n\t\t// If we're at zero and encounter a non-class character then we clip the class there\n\t\tif (depth === 0 && !ALLOWED_CLASS_CHARACTERS.test(char)) {\n\t\t\treturn input.substring(0, match.index);\n\t\t}\n\t}\n\n\treturn input;\n}\n\n// Regular utilities\n// {{modifier}:}*{namespace}{-{suffix}}*{/{opacityModifier}}?\n\n// Arbitrary values\n// {{modifier}:}*{namespace}-[{arbitraryValue}]{/{opacityModifier}}?\n// arbitraryValue: no whitespace, balanced quotes unless within quotes, balanced brackets unless within quotes\n\n// Arbitrary properties\n// {{modifier}:}*[{validCssPropertyName}:{arbitraryValue}]\n"],"mappings":"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","names":["pattern","_a"]}