@@ -18,188 +18,189 @@ type Ref struct {
18
18
}
19
19
20
20
func (ctx * BuildContext ) analyzeSplitting () (err error ) {
21
- if ctx .bundleMode == BundleDefault && ctx .pkgJson .Exports .Len () > 1 {
22
- exportNames := set .New [string ]()
23
- for _ , exportName := range ctx .pkgJson .Exports .keys {
24
- exportName := stripEntryModuleExt (exportName )
25
- if (exportName == "." || (strings .HasPrefix (exportName , "./" ) && ! strings .ContainsRune (exportName , '*' ))) && ! endsWith (exportName , ".json" , ".css" , ".wasm" , ".d.ts" , ".d.mts" , ".d.cts" ) {
26
- v := ctx .pkgJson .Exports .values [exportName ]
27
- if s , ok := v .(string ); ok {
28
- if endsWith (s , ".json" , ".css" , ".wasm" , ".d.ts" , ".d.mts" , ".d.cts" ) {
29
- continue
30
- }
31
- } else if obj , ok := v .(JSONObject ); ok {
32
- // ignore types only exports
33
- if len (obj .keys ) == 1 && obj .keys [0 ] == "types" {
34
- continue
35
- }
36
- }
37
- if exportName == "." {
38
- exportNames .Add ("" )
39
- } else if strings .HasPrefix (exportName , "./" ) {
40
- exportNames .Add (exportName [2 :])
21
+ exportNames := set .New [string ]()
22
+
23
+ for _ , exportName := range ctx .pkgJson .Exports .keys {
24
+ exportName := stripEntryModuleExt (exportName )
25
+ if (exportName == "." || (strings .HasPrefix (exportName , "./" ) && ! strings .ContainsRune (exportName , '*' ))) && ! endsWith (exportName , ".json" , ".css" , ".wasm" , ".d.ts" , ".d.mts" , ".d.cts" ) {
26
+ v := ctx .pkgJson .Exports .values [exportName ]
27
+ if s , ok := v .(string ); ok {
28
+ if endsWith (s , ".json" , ".css" , ".wasm" , ".d.ts" , ".d.mts" , ".d.cts" ) {
29
+ continue
30
+ }
31
+ } else if obj , ok := v .(JSONObject ); ok {
32
+ // ignore types only exports
33
+ if len (obj .keys ) == 1 && obj .keys [0 ] == "types" {
34
+ continue
41
35
}
42
36
}
37
+ if exportName == "." {
38
+ exportNames .Add ("" )
39
+ } else if strings .HasPrefix (exportName , "./" ) {
40
+ exportNames .Add (exportName [2 :])
41
+ }
43
42
}
44
- if exportNames .Len () > 1 {
45
- splittingTxtPath := path .Join (ctx .wd , "splitting.txt" )
46
- readSplittingTxt := func () bool {
47
- f , err := os .Open (splittingTxtPath )
48
- if err != nil {
49
- return false
50
- }
51
- defer f .Close ()
43
+ }
44
+
45
+ if exportNames .Len () > 1 {
46
+ splittingTxtPath := path .Join (ctx .wd , "splitting.txt" )
47
+ readSplittingTxt := func () bool {
48
+ f , err := os .Open (splittingTxtPath )
49
+ if err != nil {
50
+ return false
51
+ }
52
+ defer f .Close ()
52
53
53
- var a []string
54
- var i int
55
- var r = bufio .NewReader (f )
56
- for {
57
- line , readErr := r .ReadString ('\n' )
58
- if readErr == nil || readErr == io .EOF {
59
- line = strings .TrimSpace (line )
60
- if line != "" {
61
- if a == nil {
62
- n , e := strconv .Atoi (line )
63
- if e != nil {
64
- break
65
- }
66
- a = make ([]string , n + 1 )
54
+ var a []string
55
+ var i int
56
+ var r = bufio .NewReader (f )
57
+ for {
58
+ line , readErr := r .ReadString ('\n' )
59
+ if readErr == nil || readErr == io .EOF {
60
+ line = strings .TrimSpace (line )
61
+ if line != "" {
62
+ if a == nil {
63
+ n , e := strconv .Atoi (line )
64
+ if e != nil {
65
+ break
67
66
}
68
- a [i ] = line
69
- i ++
67
+ a = make ([]string , n + 1 )
70
68
}
71
- }
72
- if readErr != nil {
73
- break
69
+ a [i ] = line
70
+ i ++
74
71
}
75
72
}
76
- if len (a ) > 0 {
77
- n , e := strconv .Atoi (a [0 ])
78
- if e == nil && n <= len (a )- 1 {
79
- ctx .splitting = set .NewReadOnly (a [1 : n + 1 ]... )
80
- if DEBUG {
81
- ctx .logger .Debugf ("build(%s): splitting.txt found with %d shared modules" , ctx .esm .Specifier (), ctx .splitting .Len ())
82
- }
83
- return true
73
+ if readErr != nil {
74
+ break
75
+ }
76
+ }
77
+ if len (a ) > 0 {
78
+ n , e := strconv .Atoi (a [0 ])
79
+ if e == nil && n <= len (a )- 1 {
80
+ ctx .splitting = set .NewReadOnly (a [1 : n + 1 ]... )
81
+ if DEBUG {
82
+ ctx .logger .Debugf ("build(%s): splitting.txt found with %d shared modules" , ctx .esm .Specifier (), ctx .splitting .Len ())
84
83
}
84
+ return true
85
85
}
86
- return false
87
86
}
87
+ return false
88
+ }
88
89
89
- // check if the splitting has been analyzed
90
- if readSplittingTxt () {
91
- return
92
- }
90
+ // check if the splitting has been analyzed
91
+ if readSplittingTxt () {
92
+ return
93
+ }
93
94
94
- // only one analyze process is allowed at the same time for the same package
95
- unlock := installMutex .Lock (splittingTxtPath )
96
- defer unlock ()
95
+ // only one analyze process is allowed at the same time for the same package
96
+ unlock := installMutex .Lock (splittingTxtPath )
97
+ defer unlock ()
97
98
98
- // skip analyze if the package has been analyzed by another request
99
- if readSplittingTxt () {
100
- return
101
- }
99
+ // skip analyze if the package has been analyzed by another request
100
+ if readSplittingTxt () {
101
+ return
102
+ }
102
103
103
- defer func () {
104
- splitting := []string {}
105
- if ctx .splitting != nil {
106
- splitting = ctx .splitting .Values ()
107
- }
108
- // write the splitting result to 'splitting.txt'
109
- sizeStr := strconv .FormatUint (uint64 (len (splitting )), 10 )
110
- bufSize := len (sizeStr ) + 1
111
- for _ , s := range splitting {
112
- bufSize += len (s ) + 1
113
- }
114
- buf := make ([]byte , bufSize )
115
- i := copy (buf , sizeStr )
104
+ defer func () {
105
+ splitting := []string {}
106
+ if ctx .splitting != nil {
107
+ splitting = ctx .splitting .Values ()
108
+ }
109
+ // write the splitting result to 'splitting.txt'
110
+ sizeStr := strconv .FormatUint (uint64 (len (splitting )), 10 )
111
+ bufSize := len (sizeStr ) + 1
112
+ for _ , s := range splitting {
113
+ bufSize += len (s ) + 1
114
+ }
115
+ buf := make ([]byte , bufSize )
116
+ i := copy (buf , sizeStr )
117
+ buf [i ] = '\n'
118
+ i ++
119
+ for _ , s := range splitting {
120
+ i += copy (buf [i :], s )
116
121
buf [i ] = '\n'
117
122
i ++
118
- for _ , s := range splitting {
119
- i += copy (buf [i :], s )
120
- buf [i ] = '\n'
121
- i ++
122
- }
123
- os .WriteFile (splittingTxtPath , buf [0 :bufSize - 1 ], 0644 )
124
- }()
123
+ }
124
+ os .WriteFile (splittingTxtPath , buf [0 :bufSize - 1 ], 0644 )
125
+ }()
125
126
126
- refs := map [string ]Ref {}
127
- for _ , exportName := range exportNames .Values () {
128
- esm := ctx .esm
129
- esm .SubPath = exportName
130
- esm .SubModuleName = stripEntryModuleExt (exportName )
131
- b := & BuildContext {
132
- npmrc : ctx .npmrc ,
133
- logger : ctx .logger ,
134
- db : ctx .db ,
135
- storage : ctx .storage ,
136
- esm : esm ,
137
- args : ctx .args ,
138
- externalAll : ctx .externalAll ,
139
- target : ctx .target ,
140
- dev : ctx .dev ,
141
- wd : ctx .wd ,
142
- pkgJson : ctx .pkgJson ,
143
- }
144
- _ , includes , err := b .buildModule (true )
145
- if err != nil {
146
- return fmt .Errorf ("failed to analyze %s: %v" , esm .Specifier (), err )
147
- }
148
- for _ , include := range includes {
149
- module , importer := include [0 ], include [1 ]
150
- ref , ok := refs [module ]
151
- if ! ok {
152
- ref = Ref {entries : set .New [string ](), importers : set .New [string ]()}
153
- refs [module ] = ref
154
- }
155
- ref .importers .Add (importer )
156
- ref .entries .Add (exportName )
157
- }
127
+ refs := map [string ]Ref {}
128
+ for _ , exportName := range exportNames .Values () {
129
+ esm := ctx .esm
130
+ esm .SubPath = exportName
131
+ esm .SubModuleName = stripEntryModuleExt (exportName )
132
+ b := & BuildContext {
133
+ npmrc : ctx .npmrc ,
134
+ logger : ctx .logger ,
135
+ db : ctx .db ,
136
+ storage : ctx .storage ,
137
+ esm : esm ,
138
+ args : ctx .args ,
139
+ externalAll : ctx .externalAll ,
140
+ target : ctx .target ,
141
+ dev : ctx .dev ,
142
+ wd : ctx .wd ,
143
+ pkgJson : ctx .pkgJson ,
158
144
}
159
- shared := set .New [string ]()
160
- for mod , ref := range refs {
161
- if ref .entries .Len () > 1 && ref .importers .Len () > 1 {
162
- shared .Add (mod )
163
- }
145
+ _ , includes , err := b .buildModule (true )
146
+ if err != nil {
147
+ return fmt .Errorf ("failed to analyze %s: %v" , esm .Specifier (), err )
148
+ }
149
+ for _ , include := range includes {
150
+ module , importer := include [0 ], include [1 ]
151
+ ref , ok := refs [module ]
152
+ if ! ok {
153
+ ref = Ref {entries : set .New [string ](), importers : set .New [string ]()}
154
+ refs [module ] = ref
155
+ }
156
+ ref .importers .Add (importer )
157
+ ref .entries .Add (exportName )
158
+ }
159
+ }
160
+ shared := set .New [string ]()
161
+ for mod , ref := range refs {
162
+ if ref .entries .Len () > 1 && ref .importers .Len () > 1 {
163
+ shared .Add (mod )
164
164
}
165
- var bubble func (modulePath string , f func (string ), mark * set.Set [string ])
166
- bubble = func (modulePath string , f func (string ), mark * set.Set [string ]) {
167
- hasMark := mark != nil
168
- if ! hasMark {
169
- mark = set .New [string ]()
170
- } else if mark .Has (modulePath ) {
165
+ }
166
+ var bubble func (modulePath string , f func (string ), mark * set.Set [string ])
167
+ bubble = func (modulePath string , f func (string ), mark * set.Set [string ]) {
168
+ hasMark := mark != nil
169
+ if ! hasMark {
170
+ mark = set .New [string ]()
171
+ } else if mark .Has (modulePath ) {
172
+ return
173
+ }
174
+ mark .Add (modulePath )
175
+ ref , ok := refs [modulePath ]
176
+ if ok {
177
+ if shared .Has (modulePath ) && hasMark {
178
+ f (modulePath )
171
179
return
172
180
}
173
- mark .Add (modulePath )
174
- ref , ok := refs [modulePath ]
175
- if ok {
176
- if shared .Has (modulePath ) && hasMark {
177
- f (modulePath )
178
- return
179
- }
180
- for _ , importer := range ref .importers .Values () {
181
- bubble (importer , f , mark )
182
- }
183
- } else {
184
- // modulePath is an entry module
185
- f (modulePath )
181
+ for _ , importer := range ref .importers .Values () {
182
+ bubble (importer , f , mark )
186
183
}
184
+ } else {
185
+ // modulePath is an entry module
186
+ f (modulePath )
187
187
}
188
- if shared .Len () > 0 {
189
- splitting := set .New [string ]()
190
- for _ , modulePath := range shared .Values () {
191
- refBy := set .New [string ]()
192
- bubble (modulePath , func (importer string ) { refBy .Add (importer ) }, nil )
193
- if refBy .Len () > 1 {
194
- splitting .Add (modulePath )
195
- }
196
- }
197
- ctx .splitting = splitting .ReadOnly ()
198
- if DEBUG {
199
- ctx .logger .Debugf ("build(%s): found %d shared modules from %d modules" , ctx .esm .Specifier (), shared .Len (), len (refs ))
188
+ }
189
+ if shared .Len () > 0 {
190
+ splitting := set .New [string ]()
191
+ for _ , modulePath := range shared .Values () {
192
+ refBy := set .New [string ]()
193
+ bubble (modulePath , func (importer string ) { refBy .Add (importer ) }, nil )
194
+ if refBy .Len () > 1 {
195
+ splitting .Add (modulePath )
200
196
}
201
197
}
198
+ ctx .splitting = splitting .ReadOnly ()
199
+ if DEBUG {
200
+ ctx .logger .Debugf ("build(%s): found %d shared modules from %d modules" , ctx .esm .Specifier (), shared .Len (), len (refs ))
201
+ }
202
202
}
203
203
}
204
+
204
205
return
205
206
}
0 commit comments