@linaria/vite
Version:
Blazing fast zero-runtime CSS in JS library
1 lines • 10.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * This file contains a Rollup loader for Linaria.\n * It uses the transform.ts function to generate class names from source code,\n * returns transformed code without template literals and attaches generated source maps\n */\n\nimport { existsSync } from 'fs';\nimport path from 'path';\n\nimport { createFilter } from '@rollup/pluginutils';\nimport type { FilterPattern } from '@rollup/pluginutils';\nimport type { ModuleNode, Plugin, ResolvedConfig, ViteDevServer } from 'vite';\nimport { optimizeDeps } from 'vite';\n\nimport {\n transform,\n slugify,\n TransformCacheCollection,\n} from '@linaria/babel-preset';\nimport type { PluginOptions, Preprocessor } from '@linaria/babel-preset';\nimport { linariaLogger } from '@linaria/logger';\nimport type { IFileReporterOptions } from '@linaria/utils';\nimport { createFileReporter, getFileIdx, syncResolve } from '@linaria/utils';\n\ntype VitePluginOptions = {\n debug?: IFileReporterOptions | false | null | undefined;\n exclude?: FilterPattern;\n include?: FilterPattern;\n preprocessor?: Preprocessor;\n sourceMap?: boolean;\n} & Partial<PluginOptions>;\n\nexport { Plugin };\n\nexport default function linaria({\n debug,\n include,\n exclude,\n sourceMap,\n preprocessor,\n ...rest\n}: VitePluginOptions = {}): Plugin {\n const filter = createFilter(include, exclude);\n const cssLookup: { [key: string]: string } = {};\n const cssFileLookup: { [key: string]: string } = {};\n let config: ResolvedConfig;\n let devServer: ViteDevServer;\n\n const { emitter, onDone } = createFileReporter(debug ?? false);\n\n // <dependency id, targets>\n const targets: { dependencies: string[]; id: string }[] = [];\n const cache = new TransformCacheCollection();\n return {\n name: 'linaria',\n enforce: 'post',\n buildEnd() {\n onDone(process.cwd());\n },\n configResolved(resolvedConfig: ResolvedConfig) {\n config = resolvedConfig;\n },\n configureServer(_server) {\n devServer = _server;\n },\n load(url: string) {\n const [id] = url.split('?', 1);\n return cssLookup[id];\n },\n /* eslint-disable-next-line consistent-return */\n resolveId(importeeUrl: string) {\n const [id] = importeeUrl.split('?', 1);\n if (cssLookup[id]) return id;\n return cssFileLookup[id];\n },\n handleHotUpdate(ctx) {\n // it's module, so just transform it\n if (ctx.modules.length) return ctx.modules;\n\n // Select affected modules of changed dependency\n const affected = targets.filter(\n (x) =>\n // file is dependency of any target\n x.dependencies.some((dep) => dep === ctx.file) ||\n // or changed module is a dependency of any target\n x.dependencies.some((dep) => ctx.modules.some((m) => m.file === dep))\n );\n const deps = affected.flatMap((target) => target.dependencies);\n\n // eslint-disable-next-line no-restricted-syntax\n for (const depId of deps) {\n cache.invalidateForFile(depId);\n }\n\n return affected\n .map((target) => devServer.moduleGraph.getModuleById(target.id))\n .concat(ctx.modules)\n .filter((m): m is ModuleNode => !!m);\n },\n async transform(code: string, url: string) {\n const [id] = url.split('?', 1);\n\n // Do not transform ignored and generated files\n if (url.includes('node_modules') || !filter(url) || id in cssLookup)\n return;\n\n const log = linariaLogger.extend('vite');\n\n log('Vite transform', getFileIdx(id));\n\n const asyncResolve = async (\n what: string,\n importer: string,\n stack: string[]\n ) => {\n const resolved = await this.resolve(what, importer);\n if (resolved) {\n if (resolved.external) {\n // If module is marked as external, Rollup will not resolve it,\n // so we need to resolve it ourselves with default resolver\n const resolvedId = syncResolve(what, importer, stack);\n log(\"resolve ✅ '%s'@'%s -> %O\\n%s\", what, importer, resolved);\n return resolvedId;\n }\n\n log(\"resolve ✅ '%s'@'%s -> %O\\n%s\", what, importer, resolved);\n // Vite adds param like `?v=667939b3` to cached modules\n const resolvedId = resolved.id.split('?', 1)[0];\n\n if (resolvedId.startsWith('\\0')) {\n // \\0 is a special character in Rollup that tells Rollup to not include this in the bundle\n // https://rollupjs.org/guide/en/#outputexports\n return null;\n }\n\n if (!existsSync(resolvedId)) {\n await optimizeDeps(config);\n }\n\n return resolvedId;\n }\n\n log(\"resolve ❌ '%s'@'%s\", what, importer);\n throw new Error(`Could not resolve ${what}`);\n };\n\n const transformServices = {\n options: {\n filename: id,\n root: process.cwd(),\n preprocessor,\n pluginOptions: rest,\n },\n cache,\n eventEmitter: emitter,\n };\n\n const result = await transform(transformServices, code, asyncResolve);\n\n let { cssText, dependencies } = result;\n\n if (!cssText) return;\n dependencies ??= [];\n\n const slug = slugify(cssText);\n\n const cssFilename = path\n .normalize(`${id.replace(/\\.[jt]sx?$/, '')}_${slug}.css`)\n .replace(/\\\\/g, path.posix.sep);\n\n const cssRelativePath = path\n .relative(config.root, cssFilename)\n .replace(/\\\\/g, path.posix.sep);\n\n const cssId = `/${cssRelativePath}`;\n\n if (sourceMap && result.cssSourceMapText) {\n const map = Buffer.from(result.cssSourceMapText).toString('base64');\n cssText += `/*# sourceMappingURL=data:application/json;base64,${map}*/`;\n }\n\n cssLookup[cssFilename] = cssText;\n cssFileLookup[cssId] = cssFilename;\n\n result.code += `\\nimport ${JSON.stringify(cssFilename)};\\n`;\n if (devServer?.moduleGraph) {\n const module = devServer.moduleGraph.getModuleById(cssId);\n\n if (module) {\n devServer.moduleGraph.invalidateModule(module);\n module.lastHMRTimestamp =\n module.lastInvalidationTimestamp || Date.now();\n }\n }\n\n for (let i = 0, end = dependencies.length; i < end; i++) {\n // eslint-disable-next-line no-await-in-loop\n const depModule = await this.resolve(dependencies[i], url, {\n isEntry: false,\n });\n if (depModule) dependencies[i] = depModule.id;\n }\n const target = targets.find((t) => t.id === id);\n if (!target) targets.push({ id, dependencies });\n else target.dependencies = dependencies;\n /* eslint-disable-next-line consistent-return */\n return { code: result.code, map: result.sourceMap };\n },\n };\n}\n"],"mappings":"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","names":["resolvedId"]}