1
1
import { buildModuleIdFilter , buildModuleIdParser } from '../utils/id.js' ;
2
2
import * as svelteCompiler from 'svelte/compiler' ;
3
- import { logCompilerWarnings } from '../utils/log.js' ;
3
+ import { log , logCompilerWarnings } from '../utils/log.js' ;
4
4
import { toRollupError } from '../utils/error.js' ;
5
5
6
6
/**
@@ -16,6 +16,12 @@ export function compileModule(api) {
16
16
* @type {import("../types/id.js").ModuleIdParser }
17
17
*/
18
18
let idParser ;
19
+
20
+ /**
21
+ * @type {import('svelte/compiler').ModuleCompileOptions }
22
+ */
23
+ let staticModuleCompileOptions ;
24
+
19
25
/** @type {import('vite').Plugin } */
20
26
const plugin = {
21
27
name : 'vite-plugin-svelte:compile-module' ,
@@ -25,6 +31,7 @@ export function compileModule(api) {
25
31
//@ts -expect-error transform defined below but filter not in type
26
32
plugin . transform . filter = buildModuleIdFilter ( options ) ;
27
33
idParser = buildModuleIdParser ( options ) ;
34
+ staticModuleCompileOptions = filterNonModuleCompilerOptions ( options . compilerOptions ) ;
28
35
} ,
29
36
transform : {
30
37
async handler ( code , id ) {
@@ -33,12 +40,52 @@ export function compileModule(api) {
33
40
if ( ! moduleRequest ) {
34
41
return ;
35
42
}
43
+ const filename = moduleRequest . filename ;
44
+ /** @type {import('svelte/compiler').CompileOptions } */
45
+ const compileOptions = {
46
+ ...staticModuleCompileOptions ,
47
+ dev : ! this . environment . config . isProduction ,
48
+ generate : ssr ? 'server' : 'client' ,
49
+ filename
50
+ } ;
51
+ const dynamicCompileOptions = await options ?. dynamicCompileOptions ?. ( {
52
+ filename,
53
+ code,
54
+ compileOptions
55
+ } ) ;
56
+ if ( dynamicCompileOptions && log . debug . enabled ) {
57
+ log . debug (
58
+ `dynamic compile options for ${ filename } : ${ JSON . stringify ( dynamicCompileOptions ) } ` ,
59
+ undefined ,
60
+ 'compileModule'
61
+ ) ;
62
+ }
63
+ const finalCompileOptions = dynamicCompileOptions
64
+ ? {
65
+ ...compileOptions ,
66
+ ...dynamicCompileOptions
67
+ }
68
+ : compileOptions ;
69
+ // @ts -expect-error experimental not typed yet
70
+ if ( dynamicCompileOptions . experimental ) {
71
+ // @ts -expect-error experimental not typed yet
72
+ finalCompileOptions . experimental = {
73
+ // @ts -expect-error experimental not typed yet
74
+ ...compileOptions . experimental ,
75
+ // @ts -expect-error experimental not typed yet
76
+ ...dynamicCompileOptions . experimental
77
+ } ;
78
+ }
79
+ const finalModuleCompileOptions = filterNonModuleCompilerOptions ( finalCompileOptions ) ;
80
+ if ( log . debug . enabled ) {
81
+ log . debug (
82
+ `final ModuleCompileOptions for ${ filename } : ${ JSON . stringify ( finalModuleCompileOptions ) } ` ,
83
+ undefined ,
84
+ 'compileModule'
85
+ ) ;
86
+ }
36
87
try {
37
- const compileResult = svelteCompiler . compileModule ( code , {
38
- dev : ! this . environment . config . isProduction ,
39
- generate : ssr ? 'server' : 'client' ,
40
- filename : moduleRequest . filename
41
- } ) ;
88
+ const compileResult = svelteCompiler . compileModule ( code , finalModuleCompileOptions ) ;
42
89
logCompilerWarnings ( moduleRequest , compileResult . warnings , options ) ;
43
90
return compileResult . js ;
44
91
} catch ( e ) {
@@ -49,3 +96,46 @@ export function compileModule(api) {
49
96
} ;
50
97
return plugin ;
51
98
}
99
+
100
+ /**
101
+ *
102
+ * @param {import('svelte/compiler').CompileOptions } compilerOptions
103
+ * @return {import('svelte/compiler').ModuleCompileOptions }
104
+ */
105
+ function filterNonModuleCompilerOptions ( compilerOptions ) {
106
+ /** @type {Array<keyof import('svelte/compiler').ModuleCompileOptions> } */
107
+ const knownModuleCompileOptionNames = [
108
+ 'dev' ,
109
+ 'generate' ,
110
+ 'filename' ,
111
+ 'rootDir' ,
112
+ 'warningFilter' ,
113
+ // @ts -expect-error will only be defined after svelte aysnc is released
114
+ 'experimental'
115
+ ] ;
116
+ // TODO type /** @type {Array<keyof import('svelte/compiler').ModuleCompileOptions['experimental']> } */
117
+ const experimentalModuleCompilerOptionNames = [ 'async' ] ;
118
+
119
+ /** @type {import('svelte/compiler').ModuleCompileOptions } */
120
+ const filtered = filterByPropNames ( compilerOptions , knownModuleCompileOptionNames ) ;
121
+ // @ts -expect-error experimental not typed yet
122
+ if ( filtered . experimental ) {
123
+ // @ts -expect-error experimental not typed yet
124
+ filtered . experimental = filterByPropNames (
125
+ // @ts -expect-error experimental not typed yet
126
+ filtered . experimental ,
127
+ experimentalModuleCompilerOptionNames
128
+ ) ;
129
+ }
130
+ return filtered ;
131
+ }
132
+
133
+ /**
134
+ *
135
+ * @param {object } o
136
+ * @param {string[] } names
137
+ * @returns {object }
138
+ */
139
+ function filterByPropNames ( o , names ) {
140
+ return Object . fromEntries ( Object . entries ( o ) . filter ( ( [ name ] ) => names . includes ( name ) ) ) ;
141
+ }
0 commit comments