UNPKG

@twind/cli

Version:
8 lines (7 loc) 24.7 kB
{ "version": 3, "sources": ["../src/index.ts", "../node_modules/distilt/shim-node-cjs.js", "../src/cli.ts", "../src/run.ts", "../src/watch.ts", "../src/extract.ts", "../src/config.ts"], "sourcesContent": ["export * from './cli'\nexport * from './run'\n", "import { pathToFileURL } from 'url'\n\nexport const shim_import_meta_url = pathToFileURL(__filename)\n", "import { version } from '../package.json'\nimport sade from 'sade'\nimport { run } from './run'\nimport supportsColor from 'supports-color'\n\nexport const cli = (argv = process.argv) =>\n sade('twind [...globs=**/*.{htm,html,js,jsx,tsx,svelte,vue,mdx}]', /* single commmand */ true)\n .version(version)\n .option('-o, --output', 'Set output css file path (default print to console)')\n .option(\n '-c, --config',\n 'Set config file path (default twind.config.{[cm]js,ts} or tailwind.config.{[cm]js,ts})',\n )\n .option('-i, --ignore', 'Any file patterns to ignore')\n .option('-I, --ignore-file', 'gitignore like file', '.gitignore')\n .option('-b, --beautify', 'Generate beautified css file', false)\n .option('-C, --cwd', 'The current directory to resolve from', '.')\n .option('-w, --watch', 'Watch for changes', false)\n .option('--color', 'Print colorized output - to disable use --no-color', !!supportsColor.stderr)\n .action(async (globs, { _, ['ignore-file']: ignoreFile, ...options }) => {\n try {\n await run([globs, ..._], { ...options, ignoreFile })\n } catch (error) {\n console.error(error.stack || error.message)\n process.exit(1)\n }\n })\n .parse(argv)\n", "import type { Stats } from 'fs'\nimport fs from 'fs/promises'\nimport path from 'path'\n\nimport kleur from 'kleur'\nimport timeSpan from 'time-span'\nimport { transform } from 'esbuild'\n\nimport type { TW, Configuration, Mode } from 'twind'\nimport type { VirtualSheet } from 'twind/sheets'\nimport { create } from 'twind'\nimport { virtualSheet } from 'twind/sheets'\n\nimport { watch } from './watch'\nimport { extractRulesFromFile } from './extract'\nimport { findConfig, loadConfig as tryLoadConfig } from './config'\n\nexport interface RunOptions {\n config?: string\n output?: string\n cwd?: string\n color?: boolean\n watch?: boolean\n ignoreFile?: string\n beautify?: boolean\n}\n\nexport const run = async (globs: string[], options: RunOptions = {}): Promise<void> => {\n kleur.enabled = !!options.color\n\n options.cwd = path.resolve(options.cwd || '.')\n\n const configFile =\n (options.config && path.resolve(options.cwd, options.config)) || (await findConfig(options.cwd))\n\n // Track unknown rules\n const unknownRules = new Set<string>()\n const ignoreUnknownRules = (rule: string) => !unknownRules.has(rule)\n const mode: Mode = {\n unknown() {},\n report(info) {\n if (info.id == 'UNKNOWN_DIRECTIVE') {\n unknownRules.add(info.rule)\n }\n },\n }\n\n const watched = new Map<string, Stats>()\n const candidatesByFile = new Map<string, string[]>()\n let lastCandidates = new Set<string>(['' /* ensure an empty CSS may be generated */])\n\n // The initial run is not counted -> -1, initialRun=0, first run=1\n let runCount = -1\n\n const loadConfig = (): { sheet: VirtualSheet; tw: TW } => {\n let config: Configuration & { purge?: string[] | { content?: string[] } } = {}\n\n if (configFile) {\n const configEndTime = timeSpan()\n\n config = tryLoadConfig(configFile, options.cwd)\n\n console.error(\n kleur.green(\n `Loaded configuration from ${kleur.bold(\n path.relative(process.cwd(), configFile),\n )} in ${kleur.bold(configEndTime.rounded() + ' ms')}`,\n ),\n )\n\n if (runCount < 1 && config.purge) {\n if (Array.isArray(config.purge)) {\n globs = [...globs, ...config.purge]\n } else if (Array.isArray(config.purge.content)) {\n globs = [...globs, ...config.purge.content]\n }\n }\n }\n\n unknownRules.clear()\n lastCandidates = new Set<string>(['' /* ensure an empty CSS may be generated */])\n\n const sheet = virtualSheet()\n\n return {\n sheet,\n tw: create({ ...config, sheet, mode, hash: false }).tw,\n }\n }\n\n let { sheet, tw } = await loadConfig()\n\n const outputFile = options.output && path.resolve(options.cwd, options.output)\n\n globs = globs.filter(Boolean)\n if (!globs.length) {\n globs.push('**/*.{htm,html,js,jsx,tsx,svelte,vue,mdx}')\n }\n\n console.error(\n kleur.dim(`Using the following patterns: ${kleur.bold(JSON.stringify(globs).slice(1, -1))}`),\n )\n\n for await (const changes of watch(configFile ? [configFile, ...globs] : globs, options)) {\n runCount++\n // console.error([...changes.keys()])\n console.error(\n kleur.cyan(\n `Processing ${kleur.bold(changes.size)}${options.watch ? ' changed' : ''} file${\n changes.size == 1 ? '' : 's'\n }`,\n ),\n )\n\n const endTime = timeSpan()\n const pendingDetections: Promise<unknown>[] = []\n let hasChanged = false\n for (const [file, stats] of changes.entries()) {\n if (file == configFile) {\n if (runCount) {\n ;({ sheet, tw } = await loadConfig())\n hasChanged = true\n }\n } else if (stats) {\n const watchedStats = watched.get(file)\n if (\n !watchedStats ||\n watchedStats.size !== stats.size ||\n watchedStats.mtimeMs !== stats.mtimeMs ||\n watchedStats.ino !== stats.ino\n ) {\n pendingDetections.push(\n extractRulesFromFile(file).then((candidates) => {\n // console.error({file, candidates})\n watched.set(file, stats)\n candidatesByFile.set(file, candidates)\n if (!hasChanged) {\n for (let index = candidates.length; index--; ) {\n if (!lastCandidates.has(candidates[index])) {\n hasChanged = true\n break\n }\n }\n }\n }),\n )\n }\n } else {\n watched.delete(file)\n candidatesByFile.delete(file)\n hasChanged = true\n }\n }\n\n await Promise.all(pendingDetections)\n\n const nextCandidates = new Set<string>()\n const addCandidate = (candidate: string): void => {\n nextCandidates.add(candidate)\n }\n candidatesByFile.forEach((candidates) => {\n candidates.forEach(addCandidate)\n })\n\n console.error(\n kleur.gray(\n `Extracted ${kleur.bold(nextCandidates.size)} candidate${\n nextCandidates.size == 1 ? '' : 's'\n } from ${watched.size} file${watched.size == 1 ? '' : 's'} in ${kleur.bold(\n endTime.rounded() + ' ms',\n )}`,\n ),\n )\n\n if (hasChanged || !equals(lastCandidates, nextCandidates)) {\n const twEndTime = timeSpan()\n sheet.reset()\n tw([...nextCandidates].filter(ignoreUnknownRules).sort().join(' '))\n // console.error([...nextCandidates].sort().join(' '))\n console.error(\n kleur.gray(\n `Generated ${kleur.bold(sheet.target.length)} CSS rule${\n sheet.target.length == 1 ? '' : 's'\n } in ${kleur.bold(twEndTime.rounded() + ' ms')}`,\n ),\n )\n\n lastCandidates = nextCandidates\n\n // Beautify or Minify\n let css = sheet.target.join('\\n')\n if (options.beautify || !options.watch) {\n const cssEndTime = timeSpan()\n const result = await transform(css, {\n minify: !options.beautify,\n loader: 'css',\n sourcemap: false,\n })\n\n css = result.code\n console.error(\n kleur.gray(\n `${options.beautify ? 'Beautified' : 'Minimized'} CSS in ${kleur.bold(\n cssEndTime.rounded() + ' ms',\n )}`,\n ),\n )\n }\n\n // Write to file or console\n if (outputFile) {\n await fs.mkdir(path.dirname(outputFile), { recursive: true })\n await fs.writeFile(outputFile, css)\n console.error(\n kleur.green(\n `Finished ${kleur.bold(path.relative(process.cwd(), outputFile))} in ${kleur.bold(\n endTime.rounded() + ' ms',\n )}`,\n ),\n )\n } else {\n console.error(kleur.green(`Finished in ${kleur.bold(endTime.rounded() + ' ms')}`))\n console.log(css)\n }\n } else {\n console.error(kleur.green().dim(`No new classes detected - skipped generating CSS`))\n }\n\n if (options.watch) {\n console.error('\\n' + kleur.dim('Waiting for file changes...'))\n }\n }\n\n if (runCount < 0) {\n console.error(kleur.yellow(`No matching files found...`))\n }\n}\n\nfunction equals(a: Set<unknown>, b: Set<unknown>) {\n return a.size === b.size && every(b, (value: unknown) => a.has(value))\n}\n\nfunction every<T>(as: Iterable<T>, predicate: (value: T) => unknown): boolean {\n for (const a of as) {\n if (!predicate(a)) {\n return false\n }\n }\n\n return true\n}\n", "import fs from 'fs'\nimport path from 'path'\nimport chokidar from 'chokidar'\nimport ignore from 'ignore'\nimport pEvent from 'p-event'\nimport pDebounce from 'p-debounce'\nimport findUp from 'find-up'\n\nexport type WatchResult = Map<string, fs.Stats | undefined>\n\nconst readIgnoreFile = (file: string, cwd: string): string => {\n try {\n const path = findUp.sync(file, { cwd })\n return path ? fs.readFileSync(path, { encoding: 'utf-8' }) : ''\n } catch {\n return ''\n }\n}\nexport function watch(\n globs: string[],\n { cwd = '.', watch, ignoreFile }: { cwd?: string; watch?: boolean; ignoreFile?: string },\n): AsyncIterableIterator<WatchResult> {\n cwd = path.resolve(cwd)\n\n const isNotIgnored = ignore()\n .add(ignoreFile ? readIgnoreFile(ignoreFile, cwd) : '')\n .add(['**/.git*/**', '**/node_modules/**'])\n .createFilter()\n\n const watcher = chokidar.watch(globs, {\n cwd,\n ignored: (file: string) => {\n if (path.isAbsolute(file)) {\n file = path.relative(cwd, file)\n }\n return file ? !isNotIgnored(file) : false\n },\n persistent: !!watch,\n ignoreInitial: false,\n alwaysStat: true,\n followSymlinks: true,\n awaitWriteFinish: {\n stabilityThreshold: 120,\n pollInterval: 20,\n },\n })\n\n let changed: WatchResult = new Map()\n let isDone = false\n\n const nextQueue: {\n resolve: (x: IteratorResult<WatchResult>) => void\n reject: (error: any) => void\n }[] = []\n\n let onReady: Promise<unknown> | null = pEvent(watcher, 'ready').then(async () => {\n if (!watch) {\n isDone = true\n return watcher.close()\n }\n })\n\n const notify = pDebounce(() => {\n if (isDone || changed.size) {\n const next = nextQueue.shift()\n\n if (next) {\n next.resolve(\n isDone && !changed.size\n ? { done: true, value: undefined }\n : { done: false, value: changed },\n )\n changed = new Map()\n }\n }\n }, 50)\n\n let pendingError: any\n\n watcher\n .on('error', (error) => {\n const next = nextQueue.shift()\n if (next) {\n next.reject(error)\n } else {\n pendingError = error\n }\n })\n .on('add', (file, stats) => {\n changed.set(path.resolve(cwd, file), stats)\n notify()\n })\n .on('change', (file, stats) => {\n changed.set(path.resolve(cwd, file), stats)\n notify()\n })\n .on('unlink', (file) => {\n changed.set(path.resolve(cwd, file), undefined)\n notify()\n })\n\n return {\n [Symbol.asyncIterator]() {\n return this\n },\n async next() {\n if (pendingError) {\n throw pendingError\n }\n\n if (onReady) {\n await onReady\n onReady = null\n }\n\n return new Promise((resolve, reject) => {\n nextQueue.push({ resolve, reject })\n notify()\n })\n },\n async return(value) {\n isDone = true\n await watcher.close()\n return { done: true, value }\n },\n async throw(error) {\n isDone = true\n await watcher.close()\n throw error\n },\n }\n}\n", "import { match } from 'assert'\nimport { readFile } from 'fs/promises'\n\nconst cleanCandidate = (candidate: string): string => {\n // 1. remove leading class: (svelte)\n return candidate.replace(/^class:/, '')\n}\n\nconst COMMON_INVALID_CANDIDATES = new Set([\n '!DOCTYPE',\n 'true',\n 'false',\n 'null',\n 'undefined',\n 'class',\n 'className',\n 'currentColor',\n])\n\nconst removeInvalidCandidate = (candidate: string): boolean => {\n return !(\n COMMON_INVALID_CANDIDATES.has(candidate) ||\n // Remove candiate if it matches the following rules\n // - no lower case char\n !/[a-z]/.test(candidate) ||\n // - Starts with an uppercase char\n // - ending with -, /, @, $, &\n // - white space only\n /^[A-Z]|[-/@$&]$|^\\s*$/.test(candidate) ||\n // Either of the following two must match\n // support @sm:..., >sm:..., <sm:..., [lang]:\n /^[@<>[][^:]+:/.test(candidate) !=\n // - starts with <:#.,;?\\d\\]%/$&@_\n // - v-*: (vue)\n // - aria-*\n // - url like\n /^-?[<:#.,;?\\d[\\]%/$&@_]|^v-[^:]+:|^aria-|^https?:\\/\\/|^mailto:|^tel:/.test(candidate)\n )\n}\n\nexport const extractRulesFromString = (content: string): string[] => {\n return (\n content.match(/(?:\\[[^[]+]:|[^>\"'`\\s(){}\\]=])[^<>\"'`\\s()[]*(?:\\[[^[]+]|[^<>\"'`\\s(){}=:.,])/g) ||\n []\n )\n .map(cleanCandidate)\n .filter(removeInvalidCandidate)\n}\n\nexport const extractRulesFromFile = async (file: string): Promise<string[]> => {\n try {\n return extractRulesFromString(await readFile(file, { encoding: 'utf-8' }))\n } catch (error) {\n // TODO log error\n return []\n }\n}\n", "import * as Path from 'path'\nimport Module from 'module'\nimport { fileURLToPath } from 'url'\n\nimport type { Configuration } from 'twind'\nimport locatePath from 'locate-path'\nimport kleur from 'kleur'\n\nconst TWIND_CONFIG_FILES = [\n 'twind.config.ts',\n 'twind.config.mjs',\n 'twind.config.js',\n 'twind.config.cjs',\n]\n\nconst TAILWIND_CONFIG_FILES = [\n 'tailwind.config.ts',\n 'tailwind.config.mjs',\n 'tailwind.config.js',\n 'tailwind.config.cjs',\n]\n\nexport const findConfig = async (cwd = process.cwd()): Promise<string | undefined> => {\n return locatePath(\n [\n ...TWIND_CONFIG_FILES,\n ...TWIND_CONFIG_FILES.map((file) => Path.join('config', file)),\n ...TWIND_CONFIG_FILES.map((file) => Path.join('src', file)),\n ...TWIND_CONFIG_FILES.map((file) => Path.join('public', file)),\n ...TAILWIND_CONFIG_FILES,\n ].map((file) => Path.resolve(cwd, file)),\n )\n}\n\nexport const loadFile = <T>(file: string, cwd = process.cwd()): T => {\n const moduleId = Path.resolve(cwd, file)\n\n try {\n const require = Module.createRequire?.(moduleId) || Module.createRequireFromPath(moduleId)\n\n require('sucrase/register')\n\n delete require.cache[moduleId]\n\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require(moduleId) as T\n } catch (error) {\n console.error(\n kleur.red(\n `Failed to to load ${kleur.bold(Path.relative(process.cwd(), moduleId))}: ${error.message}`,\n ),\n )\n\n return {} as T\n }\n}\n\nexport type TConfiguration = Configuration & { purge?: string[] | { content?: string[] } }\n\nexport const loadConfig = (configFile: string, cwd = process.cwd()): TConfiguration => {\n const exports = loadFile<{ default: Configuration } & Configuration>(configFile, cwd)\n\n const config = exports.default || exports || {}\n\n // could be tailwind config\n if (\n (Array.isArray(config.plugins) ||\n // Twind has variants as {key: string}; Tailwind array or object\n Object.values(config.variants || {}).some((value) => typeof value == 'object') ||\n typeof config.prefix == 'string',\n 'presets' in config ||\n 'separator' in config ||\n 'variantOrder' in config ||\n 'corePlugins' in config ||\n 'purge' in config)\n ) {\n console.error(\n kleur.red(\n `${kleur.bold(\n Path.relative(process.cwd(), configFile),\n )} is a tailwindcss configuration file – ${kleur.bold(\n 'only',\n )} the theme, darkMode, purge files are used`,\n ),\n )\n\n return {\n theme: config.theme,\n darkMode: config.darkMode,\n purge: (config as any).purge,\n }\n }\n\n return config\n}\n\nexport const getConfig = async (\n cwd = process.cwd(),\n configFile?: string,\n): Promise<TConfiguration & { configFile: string | undefined }> => {\n configFile ??= await findConfig(cwd)\n\n return {\n ...(configFile ? loadConfig(Path.resolve(cwd, configFile), cwd) : {}),\n configFile,\n }\n}\n"], "mappings": "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", "names": [] }