1
1
import { readFileSync } from 'node:fs' ;
2
2
import * as svelte from 'svelte/compiler' ;
3
3
import { log } from './log.js' ;
4
- import { toESBuildError } from './error.js' ;
4
+ import { toESBuildError , toRollupError } from './error.js' ;
5
5
import { safeBase64Hash } from './hash.js' ;
6
6
import { normalize } from './id.js' ;
7
7
8
8
/**
9
9
* @typedef {NonNullable<import('vite').DepOptimizationOptions['esbuildOptions']> } EsbuildOptions
10
10
* @typedef {NonNullable<EsbuildOptions['plugins']>[number] } EsbuildPlugin
11
11
*/
12
-
13
- export const facadeEsbuildSveltePluginName = 'vite-plugin-svelte:facade' ;
14
- export const facadeEsbuildSvelteModulePluginName = 'vite-plugin-svelte-module:facade' ;
12
+ /*
13
+ * @typedef {NonNullable<import('vite').DepOptimizationOptions['rollupOptions']> } RollupOptions
14
+ * @typedef {NonNullable<RollupOptions['plugins']>[number] } RolldownPlugin
15
+ */
16
+ // TODO type correctly when the above works
17
+ /**
18
+ * @typedef {{
19
+ * name: string,
20
+ * options: ()=>void,
21
+ * transform?:{
22
+ * filter: any
23
+ * handler: (code: string,id: string)=>Promise<any>
24
+ * },
25
+ * buildStart?:()=>void,
26
+ * buildEnd?:()=>void
27
+ * }} RolldownPlugin
28
+ */
29
+ export const facadeOptimizeSveltePluginName = 'vite-plugin-svelte:facade' ;
30
+ export const facadeOptimizeSvelteModulePluginName = 'vite-plugin-svelte-module:facade' ;
15
31
16
32
/**
17
33
* @param {import('../types/options.d.ts').ResolvedOptions } options
@@ -36,7 +52,10 @@ export function esbuildSveltePlugin(options) {
36
52
build . onLoad ( { filter } , async ( { path : filename } ) => {
37
53
const code = readFileSync ( filename , 'utf8' ) ;
38
54
try {
39
- const contents = await compileSvelte ( options , { filename, code } , statsCollection ) ;
55
+ const result = await compileSvelte ( options , { filename, code } , statsCollection ) ;
56
+ const contents = result . map
57
+ ? result . code + '//# sourceMappingURL=' + result . map . toUrl ( )
58
+ : result . code ;
40
59
return { contents } ;
41
60
} catch ( e ) {
42
61
return { errors : [ toESBuildError ( e , options ) ] } ;
@@ -49,11 +68,63 @@ export function esbuildSveltePlugin(options) {
49
68
} ;
50
69
}
51
70
71
+ /**
72
+ * @param {import('../types/options.d.ts').ResolvedOptions } options
73
+ * @returns {RolldownPlugin }
74
+ */
75
+ export function rolldownOptimizeSveltePlugin ( options ) {
76
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined } */
77
+ let statsCollection ;
78
+ /** @type {RolldownPlugin } */
79
+ const plugin = {
80
+ name : 'vite-plugin-svelte:rolldown-optimize-svelte' ,
81
+ // @ts -expect-error not typed in rolldown yet
82
+ options ( opts ) {
83
+ if (
84
+ opts . plugins ?. some ( ( /** @type {{ name: string; } } */ p ) =>
85
+ p . name . startsWith ( 'vite:dep-scan' )
86
+ )
87
+ ) {
88
+ delete plugin . transform ;
89
+ delete plugin . buildStart ;
90
+ delete plugin . buildEnd ;
91
+ }
92
+ } ,
93
+ transform : {
94
+ filter : {
95
+ // TODO: remove excludes once above options hook works
96
+ id : { include : [ / ^ [ ^ ? # ] + \. s v e l t e (?: [ ? # ] | $ ) / ] , exclude : [ / ^ v i r t u a l - m o d u l e : / ] } ,
97
+ code : { exclude : [ / (?: i m p o r t | e x p o r t ) [ ^ " \n ] + " v i r t u a l - m o d u l e : / ] }
98
+ } ,
99
+ /**
100
+ * @param {string } code
101
+ * @param {string } filename
102
+ */
103
+ async handler ( code , filename ) {
104
+ try {
105
+ return await compileSvelte ( options , { filename, code } , statsCollection ) ;
106
+ } catch ( e ) {
107
+ throw toRollupError ( e , options ) ;
108
+ }
109
+ }
110
+ } ,
111
+ buildStart ( ) {
112
+ statsCollection = options . stats ?. startCollection ( 'prebundle library components' , {
113
+ logResult : ( c ) => c . stats . length > 1
114
+ } ) ;
115
+ } ,
116
+ buildEnd ( ) {
117
+ statsCollection ?. finish ( ) ;
118
+ }
119
+ } ;
120
+ return plugin ;
121
+ }
122
+
52
123
/**
53
124
* @param {import('../types/options.d.ts').ResolvedOptions } options
54
125
* @param {{ filename: string, code: string } } input
55
126
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection } [statsCollection]
56
- * @returns {Promise<string > }
127
+ * @returns {Promise<import('../types/compile.d.ts').Code > }
57
128
*/
58
129
async function compileSvelte ( options , { filename, code } , statsCollection ) {
59
130
let css = options . compilerOptions . css ;
@@ -114,9 +185,10 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
114
185
if ( endStat ) {
115
186
endStat ( ) ;
116
187
}
117
- return compiled . js . map
118
- ? compiled . js . code + '//# sourceMappingURL=' + compiled . js . map . toUrl ( )
119
- : compiled . js . code ;
188
+ return {
189
+ ...compiled . js ,
190
+ moduleType : 'js'
191
+ } ;
120
192
}
121
193
122
194
/**
@@ -142,7 +214,10 @@ export function esbuildSvelteModulePlugin(options) {
142
214
build . onLoad ( { filter } , async ( { path : filename } ) => {
143
215
const code = readFileSync ( filename , 'utf8' ) ;
144
216
try {
145
- const contents = await compileSvelteModule ( options , { filename, code } , statsCollection ) ;
217
+ const result = await compileSvelteModule ( options , { filename, code } , statsCollection ) ;
218
+ const contents = result . map
219
+ ? result . code + '//# sourceMappingURL=' + result . map . toUrl ( )
220
+ : result . code ;
146
221
return { contents } ;
147
222
} catch ( e ) {
148
223
return { errors : [ toESBuildError ( e , options ) ] } ;
@@ -155,11 +230,63 @@ export function esbuildSvelteModulePlugin(options) {
155
230
} ;
156
231
}
157
232
233
+ /**
234
+ * @param {import('../types/options.d.ts').ResolvedOptions } options
235
+ * @returns {RolldownPlugin }
236
+ */
237
+ export function rolldownOptimizeSvelteModulePlugin ( options ) {
238
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined } */
239
+ let statsCollection ;
240
+ /** @type {RolldownPlugin } */
241
+ const plugin = {
242
+ name : 'vite-plugin-svelte:rolldown-optimize-svelte-module' ,
243
+ // @ts -expect-error not typed in rolldown yet
244
+ options ( opts ) {
245
+ if (
246
+ opts . plugins ?. some ( ( /** @type {{ name: string; } } */ p ) =>
247
+ p . name . startsWith ( 'vite:dep-scan' )
248
+ )
249
+ ) {
250
+ delete plugin . transform ;
251
+ delete plugin . buildStart ;
252
+ delete plugin . buildEnd ;
253
+ }
254
+ } ,
255
+ transform : {
256
+ filter : {
257
+ // TODO: remove excludes once above options hook works
258
+ id : { include : [ / ^ [ ^ ? # ] + \. s v e l t e \. j s (?: [ ? # ] | $ ) / ] , exclude : [ / ^ v i r t u a l - m o d u l e : / ] } ,
259
+ code : { exclude : [ / (?: i m p o r t | e x p o r t ) [ ^ " \n ] + " v i r t u a l - m o d u l e : / ] }
260
+ } ,
261
+ /**
262
+ * @param {string } code
263
+ * @param {string } filename
264
+ */
265
+ async handler ( code , filename ) {
266
+ try {
267
+ return await compileSvelteModule ( options , { filename, code } , statsCollection ) ;
268
+ } catch ( e ) {
269
+ throw toRollupError ( e , options ) ;
270
+ }
271
+ }
272
+ } ,
273
+ buildStart ( ) {
274
+ statsCollection = options . stats ?. startCollection ( 'prebundle library components' , {
275
+ logResult : ( c ) => c . stats . length > 1
276
+ } ) ;
277
+ } ,
278
+ buildEnd ( ) {
279
+ statsCollection ?. finish ( ) ;
280
+ }
281
+ } ;
282
+ return plugin ;
283
+ }
284
+
158
285
/**
159
286
* @param {import('../types/options.d.ts').ResolvedOptions } options
160
287
* @param {{ filename: string; code: string } } input
161
288
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection } [statsCollection]
162
- * @returns {Promise<string > }
289
+ * @returns {Promise<import('../types/compile.d.ts').Code > }
163
290
*/
164
291
async function compileSvelteModule ( options , { filename, code } , statsCollection ) {
165
292
const endStat = statsCollection ?. start ( filename ) ;
@@ -171,7 +298,8 @@ async function compileSvelteModule(options, { filename, code }, statsCollection)
171
298
if ( endStat ) {
172
299
endStat ( ) ;
173
300
}
174
- return compiled . js . map
175
- ? compiled . js . code + '//# sourceMappingURL=' + compiled . js . map . toUrl ( )
176
- : compiled . js . code ;
301
+ return {
302
+ ...compiled . js ,
303
+ moduleType : 'js'
304
+ } ;
177
305
}
0 commit comments