Skip to content

Commit 5613470

Browse files
v2.3.0
1 parent 6baa705 commit 5613470

File tree

4 files changed

+48
-36
lines changed

4 files changed

+48
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@
6666
| 2025-03-09 | 2.2.0 | Respect Vite logging level (#107) |
6767
| | | Respect Vite base option (#103) |
6868
| 2025-07-01 | 2.2.1 | Allow for Vite 7, bump other dependencies. |
69+
| 2025-07-01 | 2.3.0 | Add config option `overrideConfig` to override recommended configuration (#109) |

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ generate a warning (same as any unrecognized assets).
100100

101101
Defaults to `true`, which deletes all inlined files that were inlined. A use case for turning this to `false` would be if you would like sourcemaps to be generated so you can upload them to an error tracking platform like Sentry.io.
102102

103+
### overrideConfig
104+
105+
The recommended configuration really is recommended, but if you need to tweak something it is doing, you can put your own partial rollup configuration in this object to override this plugin's defaults. For example, the default base URL for public non-inlined files is "./", but if you need it to be absolute, you can use `overrideConfig: { base: "/" }` to set it.
106+
103107
### Caveats
104108

105109
- Static resources in `public` folder (like `favicon`) are not inlined by Vite, and this plugin doesn't do that either. BUT the output single HTML file CAN work together with these resouces, using relative paths.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vite-plugin-singlefile",
3-
"version": "2.2.1",
3+
"version": "2.3.0",
44
"description": "Vite plugin for inlining all JavaScript and CSS resources",
55
"main": "dist/cjs/index.js",
66
"type": "module",

src/index.ts

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export type Config = {
2020
//
2121
// @default true
2222
deleteInlinedFiles?: boolean
23+
// If you need to override anything specific in the recommended build config, pass a sparse
24+
// object here. For example, use `{ base: "/" }` to override the default "./" base path for
25+
// non-inlined public files.
26+
overrideConfig?: Partial<UserConfig>
2327
}
2428

2529
const defaultConfig = { useRecommendedBuildConfig: true, removeViteModuleLoader: false, deleteInlinedFiles: true }
@@ -28,7 +32,7 @@ export function replaceScript(html: string, scriptFilename: string, scriptCode:
2832
const f = scriptFilename.replaceAll(".", "\\.")
2933
const reScript = new RegExp(`<script([^>]*?) src="(?:[^"]*?/)?${f}"([^>]*)></script>`)
3034
const preloadMarker = /"?__VITE_PRELOAD__"?/g
31-
const newCode = scriptCode.replace(preloadMarker, "void 0").replace(/<(\/script>|!--)/g, '\\x3C$1')
35+
const newCode = scriptCode.replace(preloadMarker, "void 0").replace(/<(\/script>|!--)/g, "\\x3C$1")
3236
const inlined = html.replace(reScript, (_, beforeSrc, afterSrc) => `<script${beforeSrc}${afterSrc}>${newCode.trim()}</script>`)
3337
return removeViteModuleLoader ? _removeViteModuleLoader(inlined) : inlined
3438
}
@@ -37,7 +41,7 @@ export function replaceCss(html: string, scriptFilename: string, scriptCode: str
3741
const f = scriptFilename.replaceAll(".", "\\.")
3842
const reStyle = new RegExp(`<link([^>]*?) href="(?:[^"]*?/)?${f}"([^>]*)>`)
3943
const newCode = scriptCode.replace(`@charset "UTF-8";`, "")
40-
const inlined = html.replace(reStyle, (_, beforeSrc, afterSrc) => `<style${beforeSrc}${afterSrc}>${newCode.trim()}</style>`);
44+
const inlined = html.replace(reStyle, (_, beforeSrc, afterSrc) => `<style${beforeSrc}${afterSrc}>${newCode.trim()}</style>`)
4145
return inlined
4246
}
4347

@@ -50,19 +54,53 @@ export function viteSingleFile({
5054
removeViteModuleLoader = false,
5155
inlinePattern = [],
5256
deleteInlinedFiles = true,
57+
overrideConfig = {},
5358
}: Config = defaultConfig): PluginOption {
59+
// Modifies the Vite build config to make this plugin work well.
60+
const _useRecommendedBuildConfig = (config: UserConfig) => {
61+
if (!config.build) config.build = {}
62+
// Ensures that even very large assets are inlined in your JavaScript.
63+
config.build.assetsInlineLimit = () => true
64+
// Avoid warnings about large chunks.
65+
config.build.chunkSizeWarningLimit = 100000000
66+
// Emit all CSS as a single file, which `vite-plugin-singlefile` can then inline.
67+
config.build.cssCodeSplit = false
68+
// We need relative path to support any static files in public folder,
69+
// which are copied to ${build.outDir} by vite.
70+
config.base = "./"
71+
// Make generated files in ${build.outDir}'s root, instead of default ${build.outDir}/assets.
72+
// Then the embedded resources can be loaded by relative path.
73+
config.build.assetsDir = ""
74+
75+
if (!config.build.rollupOptions) config.build.rollupOptions = {}
76+
if (!config.build.rollupOptions.output) config.build.rollupOptions.output = {}
77+
78+
const updateOutputOptions = (out: OutputOptions) => {
79+
// Ensure that as many resources as possible are inlined.
80+
out.inlineDynamicImports = true
81+
}
82+
83+
if (Array.isArray(config.build.rollupOptions.output)) {
84+
for (const o of config.build.rollupOptions.output) updateOutputOptions(o as OutputOptions)
85+
} else {
86+
updateOutputOptions(config.build.rollupOptions.output as OutputOptions)
87+
}
88+
89+
Object.assign(config, overrideConfig)
90+
}
91+
5492
return {
5593
name: "vite:singlefile",
5694
config: useRecommendedBuildConfig ? _useRecommendedBuildConfig : undefined,
5795
enforce: "post",
5896
generateBundle(_, bundle) {
59-
const warnNotInlined = ( filename: string ) => this.info( `NOTE: asset not inlined: ${ filename }` )
97+
const warnNotInlined = (filename: string) => this.info(`NOTE: asset not inlined: ${filename}`)
6098
this.info("\n")
6199
const files = {
62100
html: [] as string[],
63101
css: [] as string[],
64102
js: [] as string[],
65-
other: [] as string[]
103+
other: [] as string[],
66104
}
67105
for (const i of Object.keys(bundle)) {
68106
if (isHtmlFile.test(i)) {
@@ -124,34 +162,3 @@ export function viteSingleFile({
124162
// https://github.com/richardtallent/vite-plugin-singlefile/issues/57#issuecomment-1263950209
125163
const _removeViteModuleLoader = (html: string) =>
126164
html.replace(/(<script type="module" crossorigin>\s*)\(function(?: polyfill)?\(\)\s*\{[\s\S]*?\}\)\(\);/, '<script type="module">')
127-
128-
// Modifies the Vite build config to make this plugin work well.
129-
const _useRecommendedBuildConfig = (config: UserConfig) => {
130-
if (!config.build) config.build = {}
131-
// Ensures that even very large assets are inlined in your JavaScript.
132-
config.build.assetsInlineLimit = () => true
133-
// Avoid warnings about large chunks.
134-
config.build.chunkSizeWarningLimit = 100000000
135-
// Emit all CSS as a single file, which `vite-plugin-singlefile` can then inline.
136-
config.build.cssCodeSplit = false
137-
// We need relative path to support any static files in public folder,
138-
// which are copied to ${build.outDir} by vite.
139-
config.base = './'
140-
// Make generated files in ${build.outDir}'s root, instead of default ${build.outDir}/assets.
141-
// Then the embedded resources can be loaded by relative path.
142-
config.build.assetsDir = ''
143-
144-
if (!config.build.rollupOptions) config.build.rollupOptions = {}
145-
if (!config.build.rollupOptions.output) config.build.rollupOptions.output = {}
146-
147-
const updateOutputOptions = (out: OutputOptions) => {
148-
// Ensure that as many resources as possible are inlined.
149-
out.inlineDynamicImports = true
150-
}
151-
152-
if (Array.isArray(config.build.rollupOptions.output)) {
153-
for (const o of config.build.rollupOptions.output) updateOutputOptions(o as OutputOptions)
154-
} else {
155-
updateOutputOptions(config.build.rollupOptions.output as OutputOptions)
156-
}
157-
}

0 commit comments

Comments
 (0)