@@ -10,20 +10,19 @@ import {
10
10
DEFAULT_LOADER_LIST_WITH_ORDER ,
11
11
LOADER_NAME_META ,
12
12
} from '../constant' ;
13
- import { Manifest , ManifestItem } from '../loader' ;
13
+ import { LoaderFactory , Manifest , ManifestItem } from '../loader' ;
14
14
import { ScannerOptions , WalkOptions } from './types' ;
15
15
import ConfigurationHandler , { ConfigObject } from '../configuration' ;
16
- import { ConfigLoader } from '../loader/impl' ;
17
16
import { FrameworkConfig , FrameworkHandler } from '../framework' ;
18
17
import { BasePlugin , PluginFactory } from '../plugin' ;
19
18
import { ScanUtils } from './utils' ;
20
19
21
20
export class Scanner {
22
21
private moduleExtensions = [ '.js' , '.json' , '.node' ] ;
23
22
private options : ScannerOptions ;
24
- private itemMap : Map < string , ManifestItem [ ] > ;
25
- private configList : ConfigObject [ ] ;
26
- private configHandle : ConfigurationHandler ;
23
+ private itemMap : Map < string , ManifestItem [ ] > = new Map ( ) ;
24
+ private tmpConfigStore : Map < string , ConfigObject [ ] > = new Map ( ) ;
25
+ private configHandle : ConfigurationHandler = new ConfigurationHandler ( ) ;
27
26
28
27
constructor ( options : Partial < ScannerOptions > = { } ) {
29
28
this . options = {
@@ -36,7 +35,9 @@ export class Scanner {
36
35
excluded : DEFAULT_EXCLUDES . concat ( options . excluded ?? [ ] ) ,
37
36
extensions : [ ...new Set ( this . moduleExtensions . concat ( options . extensions ?? [ ] , [ '.yaml' ] ) ) ] ,
38
37
} ;
38
+ }
39
39
40
+ private async initItemMap ( ) : Promise < void > {
40
41
this . itemMap = new Map (
41
42
this . options . loaderListGenerator ( DEFAULT_LOADER_LIST_WITH_ORDER ) . map ( loaderNameOrClazz => {
42
43
if ( typeof loaderNameOrClazz === 'string' ) {
@@ -50,8 +51,6 @@ export class Scanner {
50
51
return [ loaderName , [ ] ] ;
51
52
} )
52
53
) ;
53
- this . configList = [ ] ;
54
- this . configHandle = new ConfigurationHandler ( ) ;
55
54
}
56
55
57
56
private async scanEnvList ( root : string ) : Promise < string [ ] > {
@@ -87,6 +86,9 @@ export class Scanner {
87
86
}
88
87
89
88
private async scanManifestByEnv ( root : string , env : string ) : Promise < Manifest > {
89
+ // 0. init clean itemMap
90
+ await this . initItemMap ( ) ;
91
+
90
92
const config = await this . getAllConfig ( root , env ) ;
91
93
92
94
// 1. scan all file in framework
@@ -95,8 +97,12 @@ export class Scanner {
95
97
await this . walk ( frameworkDir , this . formatWalkOptions ( 'framework' , frameworkDir ) ) ;
96
98
}
97
99
100
+
98
101
// 2. scan all file in plugin
99
- this . configList . forEach ( config => this . configHandle . setConfig ( env , config ) ) ;
102
+ if ( this . tmpConfigStore . has ( env ) ) {
103
+ const configList = this . tmpConfigStore . get ( env ) ?? [ ] ;
104
+ configList . forEach ( config => this . configHandle . setConfig ( env , config ) ) ;
105
+ }
100
106
const { plugin } = this . configHandle . getMergedConfig ( env ) ;
101
107
const pluginSortedList = await PluginFactory . createFromConfig ( plugin || { } ) ;
102
108
for ( const plugin of pluginSortedList . reverse ( ) ) {
@@ -134,28 +140,48 @@ export class Scanner {
134
140
} ) ;
135
141
}
136
142
137
- private async getAllConfig ( root : string , env : string ) {
138
- const configDir = this . getConfigDir ( root , this . options . configDir ) ;
143
+ private async getAllConfig ( baseDir : string , env : string ) {
144
+ const configDir = this . getConfigDir ( baseDir , this . options . configDir ) ;
139
145
if ( ! configDir ) {
140
146
return { } ;
141
147
}
142
- const configFileList = await fs . readdir ( path . resolve ( root , configDir ) ) ;
148
+ const root = path . resolve ( baseDir , configDir ) ;
149
+ const configFileList = await fs . readdir ( root ) ;
143
150
const container = new Container ( ArtusInjectEnum . DefaultContainerName ) ;
144
151
container . set ( { type : ConfigurationHandler } ) ;
145
- const configHandler = new ConfigLoader ( container ) ;
146
- for ( const pluginConfigFile of configFileList ) {
147
- const extname = path . extname ( pluginConfigFile ) ;
148
- if ( ScanUtils . isExclude ( pluginConfigFile , extname , this . options . excluded , this . options . extensions ) ) {
149
- continue ;
152
+ const loaderFactory = LoaderFactory . create ( container ) ;
153
+ const configItemList : ( ManifestItem | null ) [ ] = await Promise . all ( configFileList . map ( async filename => {
154
+ const extname = path . extname ( filename ) ;
155
+ if ( ScanUtils . isExclude ( filename , extname , this . options . excluded , this . options . extensions ) ) {
156
+ return null ;
150
157
}
151
- await configHandler . load ( {
152
- path : path . join ( root , configDir , pluginConfigFile ) ,
153
- extname : extname ,
154
- filename : pluginConfigFile ,
158
+ let loader = await loaderFactory . findLoaderName ( {
159
+ filename,
160
+ baseDir,
161
+ root,
162
+ configDir
155
163
} ) ;
164
+ if ( loader === 'framework-config' ) {
165
+ // SEEME: framework-config is a special loader, cannot be used when scan, need refactor later
166
+ loader = 'config' ;
167
+ }
168
+ return {
169
+ path : path . resolve ( root , filename ) ,
170
+ extname,
171
+ filename,
172
+ loader,
173
+ source : 'config' ,
174
+ } ;
175
+ } ) ) ;
176
+ await loaderFactory . loadItemList ( configItemList . filter ( v => v ) as ManifestItem [ ] ) ;
177
+ const configurationHandler = container . get ( ConfigurationHandler ) ;
178
+ const config = configurationHandler . getMergedConfig ( env ) ;
179
+ let configList = [ config ] ;
180
+ if ( this . tmpConfigStore . has ( env ) ) {
181
+ // equal unshift config to configList
182
+ configList = configList . concat ( this . tmpConfigStore . get ( env ) ?? [ ] ) ;
156
183
}
157
- const config = container . get ( ConfigurationHandler ) . getMergedConfig ( env ) ;
158
- this . configList . unshift ( config ) ;
184
+ this . tmpConfigStore . set ( env , configList ) ;
159
185
return config ;
160
186
}
161
187
@@ -213,7 +239,10 @@ export class Scanner {
213
239
items = items . concat ( unitItems ) ;
214
240
}
215
241
relative && items . forEach ( item => ( item . path = path . relative ( appRoot , item . path ) ) ) ;
216
- return items ;
242
+ return items . filter ( item => (
243
+ // remove PluginConfig to avoid re-merge on application running
244
+ item . loader !== 'plugin-config'
245
+ ) ) ;
217
246
}
218
247
219
248
private async writeFile ( filename : string = 'manifest.json' , data : string ) {
0 commit comments