-
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathsvelte.config.js
More file actions
171 lines (149 loc) · 6.21 KB
/
Copy pathsvelte.config.js
File metadata and controls
171 lines (149 loc) · 6.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import { readdir, readFile, writeFile, glob, copyFile } from 'node:fs/promises'
import { join, basename, resolve } from 'node:path'
import process from 'node:process'
import staticAdapter from '@sveltejs/adapter-static'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
/**
* Custom adapter wrapper that extends @sveltejs/adapter-static
* to inject font preload links after the build is complete
*
* @param {import('@sveltejs/adapter-static').AdapterOptions & {fontNames?: string[], formats?: string[]}} options
* @returns {import('@sveltejs/kit').Adapter}
*/
const adapterWithFontPreload = (options = {}) => {
const { fontNames = ['nunito'], formats = ['woff2', 'woff'], ...staticOptions } = options
const baseAdapter = staticAdapter(staticOptions)
return {
name: 'adapter-static-with-font-preload-and-workers',
async adapt (builder) {
await baseAdapter.adapt(builder)
const outDir = './build' // Static adapter always writes to 'build' directory
try {
const assetsDir = join(outDir, '_app/immutable/assets')
const assetFiles = await readdir(assetsDir)
const fontFiles = assetFiles.filter(file => {
const lowerFileName = file.toLowerCase()
return formats.some(format => lowerFileName.endsWith(`.${format}`)) &&
fontNames.some(name => lowerFileName.includes(name.toLowerCase()))
})
if (fontFiles.length === 0) return
console.log('Found fonts to preload:', fontFiles)
const preloadLinks = fontFiles.map(fontFile => {
const format = fontFile.split('.').pop()
return `\t<link rel="preload" href="/_app/immutable/assets/${fontFile}" as="font" type="font/${format}" crossorigin>`
}).join('\n')
const htmlPath = join(outDir, '/index.html')
try {
const html = /** @type {string} */ (await readFile(htmlPath, 'utf-8'))
const headPattern = '</head>'
const replacement = `${preloadLinks}\n${headPattern}`
const updated = html.replace(headPattern, replacement)
if (updated !== html) {
await writeFile(htmlPath, updated, 'utf-8')
console.log(`Added font preload links to ${htmlPath}`)
}
} catch (error) {
console.log(`Could not process ${htmlPath}:`, error)
}
} catch (error) {
console.error('Error injecting font preloads:', error)
}
// find service worker, and replace JASSUB-WORKER-URLS with actual URLs
// this for offline support of JASSUB web workers, because vite does not expose workers in the build manifest
// if they are loaded from a dependency... wonderful
try {
const swPath = join(outDir, 'service-worker.js')
let swCode = /** @type {string} */ (await readFile(swPath, 'utf-8'))
const assetFiles = []
for await (const file of glob(join(outDir, '_app/immutable/workers/*.js'))) {
assetFiles.push(basename(file))
}
const workerUrls = assetFiles.map(file => `/_app/immutable/workers/${file}`)
if (workerUrls.length === 0) return
swCode = swCode
.replace("'JASSUB-WORKER-URLS'", `"${workerUrls.join('", "')}"`)
.replace('"JASSUB-WORKER-URLS"', `"${workerUrls.join('", "')}"`)
.replace('`JASSUB-WORKER-URLS`', `"${workerUrls.join('", "')}"`)
await writeFile(swPath, swCode, 'utf-8')
console.log('Updated service worker with JASSUB worker URLs:', workerUrls)
} catch (error) {
console.error('Error updating service worker with JASSUB worker URLs:', error)
}
// copy index.html to offline.html for offline fallback for service worker
try {
const indexPath = join(outDir, 'index.html')
const offlinePath = join(outDir, 'offline.html')
await copyFile(indexPath, offlinePath)
console.log('Created offline.html for service worker offline fallback')
} catch (error) {
console.error('Error creating offline.html for service worker:', error)
}
// copy license file to build directory
try {
const src = resolve(import.meta.dirname, 'node_modules/.cache/license-deps.txt')
const dst = join(outDir, 'LICENSE.txt')
await copyFile(src, dst)
console.log('Copied license file to build directory')
} catch (error) {
console.error('Error copying license file to build directory:', error)
}
}
}
}
/** @type {import('@sveltejs/kit').Config} */
const config = {
compilerOptions: {
runes: false
},
onwarn: (warning, handler) => {
if (warning.code.includes('a11y')) return
if (warning.code === 'element_invalid_self_closing_tag') return
handler?.(warning)
},
preprocess: vitePreprocess(),
kit: {
csp: {
mode: 'hash',
directives: {
'default-src': ['self'],
'script-src': ['self', 'wasm-unsafe-eval', 'blob:', 'trusted-types-eval'],
'style-src': ['self', 'unsafe-inline'],
'style-src-attr': ['unsafe-inline'],
'img-src': ['self', 'blob:', 'https:', 'data:'],
'font-src': ['self'],
'connect-src': ['self', 'https:', 'wss:', 'cors:', 'http://localhost:*'],
'frame-src': ['self', 'https://www.youtube-nocookie.com'],
'worker-src': ['self', 'blob:'],
'media-src': ['self', 'https://v.animethemes.moe', 'http://localhost:*', 'blob:', 'https://remotion.media'],
'object-src': ['none'],
'base-uri': ['self'],
'form-action': ['self'],
'frame-ancestors': ['self'],
'manifest-src': ['self']
}
},
router: {
type: 'hash',
resolution: 'client'
},
adapter: adapterWithFontPreload({
// this fallback override is intentional, as otherwise the font preload isnt included
fallback: 'index.html',
fontNames: ['nunito-latin-wght'],
formats: ['woff2', 'woff']
}),
version: {
name: process.env.npm_package_version
},
alias: {
'lucide-svelte/dist/Icon.svelte': './node_modules/lucide-svelte/dist/Icon.svelte'
},
serviceWorker: {
files: (filepath) => {
return !['video.mkv', 'NotoSansHK.woff2', 'NotoSansJP.woff2', 'NotoSansKR.woff2'].includes(filepath)
}
}
},
runtime: ''
}
export default config