1
- import { log } from './log' ;
2
1
import path from 'path' ;
3
- import fs from 'fs' ;
4
- import { createRequire } from 'module' ;
2
+ import fs from 'fs/promises' ;
3
+ // eslint-disable-next-line node/no-missing-import
4
+ import { findDepPkgJsonPath } from 'vitefu' ;
5
5
6
- export function findRootSvelteDependencies ( root : string , cwdFallback = true ) : SvelteDependency [ ] {
7
- log . debug ( `findSvelteDependencies: searching svelte dependencies in ${ root } ` ) ;
8
- const pkgFile = path . join ( root , 'package.json' ) ;
9
- if ( ! fs . existsSync ( pkgFile ) ) {
10
- if ( cwdFallback ) {
11
- const cwd = process . cwd ( ) ;
12
- if ( root !== cwd ) {
13
- log . debug ( `no package.json found in vite root ${ root } ` ) ;
14
- return findRootSvelteDependencies ( cwd , false ) ;
15
- }
16
- }
17
- log . warn ( `no package.json found, findRootSvelteDependencies failed` ) ;
18
- return [ ] ;
19
- }
20
-
21
- const pkg = parsePkg ( root ) ;
22
- if ( ! pkg ) {
23
- return [ ] ;
24
- }
25
-
26
- const deps = [
27
- ...Object . keys ( pkg . dependencies || { } ) ,
28
- ...Object . keys ( pkg . devDependencies || { } )
29
- ] . filter ( ( dep ) => ! is_common_without_svelte_field ( dep ) ) ;
30
-
31
- return getSvelteDependencies ( deps , root ) ;
32
- }
33
-
34
- function getSvelteDependencies (
35
- deps : string [ ] ,
36
- pkgDir : string ,
37
- path : string [ ] = [ ]
38
- ) : SvelteDependency [ ] {
39
- const result = [ ] ;
40
- const localRequire = createRequire ( `${ pkgDir } /package.json` ) ;
41
- const resolvedDeps = deps
42
- . map ( ( dep ) => resolveDependencyData ( dep , localRequire ) )
43
- . filter ( Boolean ) as DependencyData [ ] ;
44
- for ( const { pkg, dir } of resolvedDeps ) {
45
- const type = getSvelteDependencyType ( pkg ) ;
46
- if ( ! type ) continue ;
47
- result . push ( { name : pkg . name , type, pkg, dir, path } ) ;
48
- // continue crawling for component libraries so we can optimize them, js libraries are fine
49
- if ( type === 'component-library' && pkg . dependencies ) {
50
- let dependencyNames = Object . keys ( pkg . dependencies ) ;
51
- const circular = dependencyNames . filter ( ( name ) => path . includes ( name ) ) ;
52
- if ( circular . length > 0 ) {
53
- log . warn . enabled &&
54
- log . warn (
55
- `skipping circular svelte dependencies in automated vite optimizeDeps handling` ,
56
- circular . map ( ( x ) => path . concat ( x ) . join ( '>' ) )
57
- ) ;
58
- dependencyNames = dependencyNames . filter ( ( name ) => ! path . includes ( name ) ) ;
59
- }
60
- if ( path . length === 3 ) {
61
- log . debug . once ( `encountered deep svelte dependency tree: ${ path . join ( '>' ) } ` ) ;
62
- }
63
- result . push ( ...getSvelteDependencies ( dependencyNames , dir , path . concat ( pkg . name ) ) ) ;
64
- }
65
- }
66
- return result ;
6
+ interface DependencyData {
7
+ dir : string ;
8
+ pkg : Record < string , any > ;
67
9
}
68
10
69
- export function resolveDependencyData (
11
+ export async function resolveDependencyData (
70
12
dep : string ,
71
- localRequire : NodeRequire
72
- ) : DependencyData | void {
73
- try {
74
- const pkgJson = `${ dep } /package.json` ;
75
- const pkg = localRequire ( pkgJson ) ;
76
- const dir = path . dirname ( localRequire . resolve ( pkgJson ) ) ;
77
- return { dir, pkg } ;
78
- } catch ( e ) {
79
- log . debug . once ( `dependency ${ dep } does not export package.json` , e ) ;
80
- // walk up from default export until we find package.json with name=dep
81
- try {
82
- let dir = path . dirname ( localRequire . resolve ( dep ) ) ;
83
- while ( dir ) {
84
- const pkg = parsePkg ( dir , true ) ;
85
- if ( pkg && pkg . name === dep ) {
86
- return { dir, pkg } ;
87
- }
88
- const parent = path . dirname ( dir ) ;
89
- if ( parent === dir ) {
90
- break ;
91
- }
92
- dir = parent ;
93
- }
94
- } catch ( e ) {
95
- log . debug . once ( `error while trying to find package.json of ${ dep } ` , e ) ;
96
- }
97
- }
98
- log . debug . once ( `failed to resolve ${ dep } ` ) ;
99
- }
100
-
101
- function parsePkg ( dir : string , silent = false ) : Pkg | void {
102
- const pkgFile = path . join ( dir , 'package.json' ) ;
13
+ parent : string
14
+ ) : Promise < DependencyData | undefined > {
15
+ const depDataPath = await findDepPkgJsonPath ( dep , parent ) ;
16
+ if ( ! depDataPath ) return undefined ;
103
17
try {
104
- return JSON . parse ( fs . readFileSync ( pkgFile , 'utf-8' ) ) ;
105
- } catch ( e ) {
106
- ! silent && log . warn . enabled && log . warn ( `failed to parse ${ pkgFile } ` , e ) ;
107
- }
108
- }
109
-
110
- function getSvelteDependencyType ( pkg : Pkg ) : SvelteDependencyType | undefined {
111
- if ( isSvelteComponentLib ( pkg ) ) {
112
- return 'component-library' ;
113
- } else if ( isSvelteLib ( pkg ) ) {
114
- return 'js-library' ;
115
- } else {
18
+ return {
19
+ dir : path . dirname ( depDataPath ) ,
20
+ pkg : JSON . parse ( await fs . readFile ( depDataPath , 'utf-8' ) )
21
+ } ;
22
+ } catch {
116
23
return undefined ;
117
24
}
118
25
}
119
26
120
- function isSvelteComponentLib ( pkg : Pkg ) {
121
- return ! ! pkg . svelte ;
122
- }
123
-
124
- function isSvelteLib ( pkg : Pkg ) {
125
- return ! ! pkg . dependencies ?. svelte || ! ! pkg . peerDependencies ?. svelte ;
126
- }
127
-
128
27
const COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD = [
129
28
'@lukeed/uuid' ,
130
29
'@playwright/test' ,
@@ -173,7 +72,7 @@ const COMMON_PREFIXES_WITHOUT_SVELTE_FIELD = [
173
72
* @param dependency {string}
174
73
* @returns {boolean } true if it is a dependency without a svelte field
175
74
*/
176
- export function is_common_without_svelte_field ( dependency : string ) : boolean {
75
+ export function isCommonDepWithoutSvelteField ( dependency : string ) : boolean {
177
76
return (
178
77
COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD . includes ( dependency ) ||
179
78
COMMON_PREFIXES_WITHOUT_SVELTE_FIELD . some (
@@ -184,58 +83,3 @@ export function is_common_without_svelte_field(dependency: string): boolean {
184
83
)
185
84
) ;
186
85
}
187
-
188
- export function needsOptimization ( dep : string , localRequire : NodeRequire ) : boolean {
189
- const depData = resolveDependencyData ( dep , localRequire ) ;
190
- if ( ! depData ) return false ;
191
- const pkg = depData . pkg ;
192
- // only optimize if is cjs, using the below as heuristic
193
- // see https://github.com/sveltejs/vite-plugin-svelte/issues/162
194
- const hasEsmFields = pkg . module || pkg . exports ;
195
- if ( hasEsmFields ) return false ;
196
- if ( pkg . main ) {
197
- // ensure entry is js so vite can prebundle it
198
- // see https://github.com/sveltejs/vite-plugin-svelte/issues/233
199
- const entryExt = path . extname ( pkg . main ) ;
200
- return ! entryExt || entryExt === '.js' || entryExt === '.cjs' ;
201
- } else {
202
- // check if has implicit index.js entrypoint
203
- // https://github.com/sveltejs/vite-plugin-svelte/issues/281
204
- try {
205
- localRequire . resolve ( `${ dep } /index.js` ) ;
206
- return true ;
207
- } catch {
208
- return false ;
209
- }
210
- }
211
- }
212
-
213
- interface DependencyData {
214
- dir : string ;
215
- pkg : Pkg ;
216
- }
217
-
218
- export interface SvelteDependency {
219
- name : string ;
220
- type : SvelteDependencyType ;
221
- dir : string ;
222
- pkg : Pkg ;
223
- path : string [ ] ;
224
- }
225
-
226
- // component-library => exports svelte components
227
- // js-library => only uses svelte api, no components
228
- export type SvelteDependencyType = 'component-library' | 'js-library' ;
229
-
230
- export interface Pkg {
231
- name : string ;
232
- svelte ?: string ;
233
- dependencies ?: DependencyList ;
234
- devDependencies ?: DependencyList ;
235
- peerDependencies ?: DependencyList ;
236
- [ key : string ] : any ;
237
- }
238
-
239
- export interface DependencyList {
240
- [ key : string ] : string ;
241
- }
0 commit comments