UNPKG

vite-plugin-inline-source

Version:
1 lines 12 kB
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { minify as minifyCss } from \"csso\";\nimport * as esbuild from \"esbuild\";\nimport type { TransformPluginContext } from \"rollup\";\nimport * as sass from \"sass\";\nimport { optimize as optimizeSvg } from \"svgo\";\nimport { minify as minifyJs } from \"terser\";\nimport {\n\ttype ConfigEnv,\n\ttype IndexHtmlTransformContext,\n\tloadEnv,\n\ttype Plugin,\n\ttype ResolvedConfig,\n} from \"vite\";\nimport z from \"zod\";\n\nconst { compileString: compileSass } = sass;\n\nconst InlineSourceOptionsSchema = z\n\t.object({\n\t\treplaceTags: z\n\t\t\t.array(z.string())\n\t\t\t.default([\"svg\", \"math\"])\n\t\t\t.describe(\n\t\t\t\t\"Tags that should be replaced entirely when inlining elements. The default behavior is to preserve the tags and place the content from the source file inside them.\",\n\t\t\t),\n\t\toptimizeSvgs: z\n\t\t\t.boolean()\n\t\t\t.default(true)\n\t\t\t.describe(\"Whether or not to optimize SVGs using svgo\"),\n\t\tcompileSass: z\n\t\t\t.boolean()\n\t\t\t.default(false)\n\t\t\t.describe(\"Whether or not to compile SASS using sass\"),\n\t\toptimizeCss: z\n\t\t\t.boolean()\n\t\t\t.default(false)\n\t\t\t.describe(\"Whether or not to optimize CSS using csso\"),\n\t\tcompileTs: z\n\t\t\t.boolean()\n\t\t\t.default(true)\n\t\t\t.describe(\n\t\t\t\t\"Whether or not to transform TypeScript to JavaScript using esbuild\",\n\t\t\t),\n\t\toptimizeJs: z\n\t\t\t.boolean()\n\t\t\t.default(false)\n\t\t\t.describe(\"Whether or not to optimize JS using terser\"),\n\t\tsvgoOptions: z.object({}).passthrough().default({}),\n\t\tsassOptions: z.object({}).passthrough().default({}),\n\t\tcssoOptions: z.object({}).passthrough().default({}),\n\t\tterserOptions: z.object({}).passthrough().default({}),\n\t})\n\t.default({});\n\ntype InlineSourceOptions = z.input<typeof InlineSourceOptionsSchema>;\n\nconst PATTERN =\n\t/<([A-z0-9-]+)\\s+([^>]*?)src\\s*=\\s*\"([^>]*?)\"([^>]*?)\\s*((\\/>)|(>\\s*<\\/\\s*\\1\\s*>))/gi;\n\nexport default function VitePluginInlineSource(\n\topts?: InlineSourceOptions,\n): Plugin {\n\tconst options = InlineSourceOptionsSchema.parse(opts);\n\tlet root = \"\";\n\n\tasync function transformHtml(\n\t\tsource: string,\n\t\tctx: TransformPluginContext | IndexHtmlTransformContext,\n\t) {\n\t\tconst result = [];\n\t\tconst tokens = source.matchAll(PATTERN);\n\t\tlet prevPos = 0;\n\t\tfor (const token of tokens) {\n\t\t\tconst [matched, tagName, preAttributes, fileName, postAttributes] = token;\n\t\t\tconst { index } = token;\n\t\t\tconst isSvgFile = path.extname(fileName).toLowerCase() === \".svg\";\n\t\t\tconst isSassFile = path.extname(fileName).toLowerCase() === \".scss\";\n\t\t\tconst isCssFile = path.extname(fileName).toLowerCase() === \".css\";\n\t\t\tconst isJsFile = path.extname(fileName).toLowerCase() === \".js\";\n\t\t\tconst isTsFile = path.extname(fileName).toLowerCase() === \".ts\";\n\t\t\tconst isImg = tagName.toLowerCase() === \"img\";\n\t\t\tconst shouldInline = /\\binline-source\\b/.test(\n\t\t\t\tpreAttributes + \" \" + postAttributes,\n\t\t\t);\n\n\t\t\tif ((isImg && !isSvgFile) || !shouldInline) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst filePath = root ? path.join(root, fileName) : fileName;\n\n\t\t\tlet fileContent: string = (ctx as IndexHtmlTransformContext).server\n\t\t\t\t? (await readFile(`${filePath}`)).toString()\n\t\t\t\t: // @ts-expect-error don't know these types aren't right\n\t\t\t\t\t(await ctx.load({ id: `${filePath}?raw` })).ast?.body?.[0].declaration\n\t\t\t\t\t\t.value;\n\t\t\tif (isSvgFile && options.optimizeSvgs) {\n\t\t\t\tfileContent = optimizeSvg(fileContent, options.svgoOptions).data;\n\t\t\t} else if (isCssFile && options.optimizeCss) {\n\t\t\t\tconst minifiedCode = minifyCss(fileContent, options.cssoOptions).css;\n\t\t\t\tif (minifiedCode.length === 0 && fileContent.length !== 0) {\n\t\t\t\t\tthrow new Error(\"Failed to minify CSS\");\n\t\t\t\t}\n\t\t\t\tfileContent = minifiedCode;\n\t\t\t} else if (isSassFile && options.compileSass) {\n\t\t\t\tconst css = compileSass(fileContent, options.sassOptions).css;\n\t\t\t\tfileContent = options.optimizeCss\n\t\t\t\t\t? minifyCss(css, options.cssoOptions).css\n\t\t\t\t\t: css;\n\t\t\t} else if (isJsFile && options.optimizeJs) {\n\t\t\t\tconst minifiedCode = (\n\t\t\t\t\tawait minifyJs(fileContent, options.terserOptions)\n\t\t\t\t).code;\n\t\t\t\tif (minifiedCode) {\n\t\t\t\t\tfileContent = minifiedCode;\n\t\t\t\t}\n\t\t\t} else if (isTsFile && options.compileTs) {\n\t\t\t\ttry {\n\t\t\t\t\tconst envVars = loadEnv(env.mode, process.cwd());\n\t\t\t\t\tconst envVarDefines = Object.entries(envVars).reduce<\n\t\t\t\t\t\tRecord<string, string>\n\t\t\t\t\t>((prev, [key, value]) => {\n\t\t\t\t\t\tif (key.startsWith(\"VITE\")) prev[`import.meta.env.${key}`] = value;\n\t\t\t\t\t\treturn prev;\n\t\t\t\t\t}, {});\n\n\t\t\t\t\tconst transformResult = await esbuild.transform(fileContent, {\n\t\t\t\t\t\tloader: \"ts\",\n\t\t\t\t\t\tdefine: {\n\t\t\t\t\t\t\t\"import.meta.env.MODE\": `\"${env.mode}\"`,\n\t\t\t\t\t\t\t\"import.meta.env.BASE_URL\": `\"${config.base ?? \"/\"}\"`,\n\t\t\t\t\t\t\t\"import.meta.env.PROD\": `${process.env.NODE_ENV == \"production\"}`,\n\t\t\t\t\t\t\t\"import.meta.env.DEV\": `${process.env.NODE_ENV != \"production\"}`,\n\t\t\t\t\t\t\t\"import.meta.env.SSR\": `${env.isSsrBuild}`,\n\t\t\t\t\t\t\t...envVarDefines,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tfileContent = transformResult.code;\n\n\t\t\t\t\tif (options.optimizeJs) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst minifiedResult = await minifyJs(\n\t\t\t\t\t\t\t\tfileContent,\n\t\t\t\t\t\t\t\toptions.terserOptions,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (minifiedResult.code) {\n\t\t\t\t\t\t\t\tfileContent = minifiedResult.code;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// If minification returns empty/undefined, keep the original compiled code\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconsole.warn(\"Failed to minify compiled TypeScript:\", error);\n\t\t\t\t\t\t\t// Keep the original compiled code if minification fails\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"Failed to compile TypeScript:\", error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfileContent = fileContent.replace(/^<!DOCTYPE(.*?[^?])?>/, \"\");\n\n\t\t\tif (index !== prevPos) {\n\t\t\t\tresult.push(source.slice(prevPos, index));\n\t\t\t}\n\t\t\tif (options.replaceTags.includes(tagName)) {\n\t\t\t\tresult.push(\n\t\t\t\t\tfileContent.replace(\n\t\t\t\t\t\tnew RegExp(`^<\\\\s*${tagName}`),\n\t\t\t\t\t\t`<${tagName} ${preAttributes.replace(\n\t\t\t\t\t\t\t/inline-source/g,\n\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t)} ${postAttributes.replace(/inline-source/g, \"\")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tresult.push(\n\t\t\t\t\t`<${tagName}\n ${preAttributes.replace(\n\t\t\t\t\t\t\t/inline-source/g,\n\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t)} ${postAttributes.replace(/inline-source/g, \"\")}\n >${fileContent}</${tagName}>`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tprevPos = index! + matched.length;\n\t\t}\n\t\tresult.push(source.slice(prevPos));\n\t\treturn result.join(\"\");\n\t}\n\n\tlet env: ConfigEnv;\n\tlet config: ResolvedConfig;\n\n\treturn {\n\t\tname: \"vite-plugin-inline-source\",\n\t\tconfigResolved(_config) {\n\t\t\troot = _config.root ?? \"\";\n\t\t\tconfig = _config;\n\t\t},\n\t\tconfig(_, e) {\n\t\t\tenv = e;\n\t\t},\n\t\ttransform(source, id) {\n\t\t\tif (id && !id.endsWith(\".html\")) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn transformHtml(source, this);\n\t\t},\n\t\ttransformIndexHtml(source, ctx) {\n\t\t\treturn transformHtml(source, ctx);\n\t\t},\n\t};\n}\n"],"mappings":"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","names":["z","path","optimizeSvg","minifyCss","minifyJs"]}