@@ -4,7 +4,7 @@ import { colors, createHash, ensureDir, minify, path, walk } from '../deps.ts'
4
4
import { EventEmitter } from '../framework/core/events.ts'
5
5
import type { RouteModule } from '../framework/core/routing.ts'
6
6
import { createBlankRouterURL , isModuleURL , Routing , toPagePath } from '../framework/core/routing.ts'
7
- import { defaultReactVersion , minDenoVersion , hashShortLength } from '../shared/constants.ts'
7
+ import { defaultReactVersion , minDenoVersion , moduleExts , hashShortLength } from '../shared/constants.ts'
8
8
import { ensureTextFile , existsDirSync , existsFileSync } from '../shared/fs.ts'
9
9
import log from '../shared/log.ts'
10
10
import util from '../shared/util.ts'
@@ -71,9 +71,8 @@ export class Application implements ServerApplication {
71
71
private async init ( reload : boolean ) {
72
72
const t = performance . now ( )
73
73
const alephPkgUri = getAlephPkgUri ( )
74
- const mode = this . mode
75
74
const { env, framework, plugins, ssr } = this . config
76
- const walkOptions = { includeDirs : false , exts : [ 'tsx' , 'jsx' , 'ts' , 'js' , 'mjs' ] , skip : [ / ^ \ ./ , / \. d \. t s $ / i, / \. ( t e s t | s p e c | e 2 e ) \. m ? ( j | t ) s x ? $ / i] }
75
+ const walkOptions = { includeDirs : false , skip : [ / ( ^ | \/ | \\ ) \ ./ , / \. d \. t s $ / i, / ( \. | _ ) ( t e s t | s p e c | e 2 e ) \. ( t s x ? | j s x ? | m j s ) ? $ / i] }
77
76
const apiDir = path . join ( this . srcDir , 'api' )
78
77
const pagesDir = path . join ( this . srcDir , 'pages' )
79
78
@@ -122,14 +121,12 @@ export class Application implements ServerApplication {
122
121
for ( const plugin of plugins ) {
123
122
if ( plugin . type === 'server' ) {
124
123
await plugin . onInit ( this )
125
- Object . assign ( this , { mode } ) // to avoid plugin from changing the mode
126
124
}
127
125
}
128
126
129
127
// init framework
130
128
const { init } = await import ( `../framework/${ framework } /init.ts` )
131
129
await init ( this )
132
- Object . assign ( this , { mode } ) // to avoid framework from changing the mode
133
130
134
131
if ( ! this . isDev ) {
135
132
log . info ( 'Building...' )
@@ -150,33 +147,46 @@ export class Application implements ServerApplication {
150
147
this . #renderer = await import ( 'file://' + jsFile )
151
148
}
152
149
153
- // check custom components
154
- for await ( const { path : p , } of walk ( this . srcDir , { ...walkOptions , maxDepth : 1 } ) ) {
155
- const name = path . basename ( p )
156
- switch ( trimModuleExt ( name ) ) {
157
- case 'app' :
158
- case '404' :
159
- case 'loading' :
160
- await this . compile ( '/' + name )
150
+ // compile custom components
151
+ for ( const name of [ 'app' , '404' , 'loading' ] ) {
152
+ for ( const ext of moduleExts ) {
153
+ if ( existsFileSync ( path . join ( this . srcDir , name + '.' + ext ) ) ) {
154
+ await this . compile ( '/' + name + '.' + ext )
161
155
break
156
+ }
157
+ }
158
+ }
159
+
160
+ // update page routing
161
+ this . #pageRouting. config ( this . config )
162
+ for await ( const { path : p } of walk ( pagesDir , walkOptions ) ) {
163
+ const url = util . cleanPath ( '/pages/' + util . trimPrefix ( p , pagesDir ) )
164
+ let validated = moduleExts . some ( ext => p . endsWith ( '.' + ext ) )
165
+ if ( ! validated ) {
166
+ validated = this . config . plugins . some ( p => p . type === 'loader' && p . test . test ( url ) && p . allowPage )
167
+ }
168
+ if ( validated ) {
169
+ const mod = await this . compile ( url )
170
+ this . #pageRouting. update ( this . getRouteModule ( mod ) )
162
171
}
163
172
}
164
173
165
174
// update api routing
166
175
if ( existsDirSync ( apiDir ) ) {
167
- for await ( const { path : p } of walk ( apiDir , walkOptions ) ) {
168
- const mod = await this . compile ( util . cleanPath ( '/api/' + util . trimPrefix ( p , apiDir ) ) )
176
+ for await ( const { path : p } of walk ( apiDir , { ...walkOptions , exts : moduleExts } ) ) {
177
+ const url = util . cleanPath ( '/api/' + util . trimPrefix ( p , apiDir ) )
178
+ let mod : Module
179
+ if ( this . isDev ) {
180
+ // in dev mode, we pre-compile the api code to support re-import the api module
181
+ // when it is changed.
182
+ mod = await this . compile ( url )
183
+ } else {
184
+ mod = { url, hash : '' , sourceHash : '' , deps : [ ] , jsFile : p }
185
+ }
169
186
this . #apiRouting. update ( this . getRouteModule ( mod ) )
170
187
}
171
188
}
172
189
173
- // update page routing
174
- this . #pageRouting. config ( this . config )
175
- for await ( const { path : p } of walk ( pagesDir , { ...walkOptions } ) ) {
176
- const mod = await this . compile ( util . cleanPath ( '/pages/' + util . trimPrefix ( p , pagesDir ) ) )
177
- this . #pageRouting. update ( this . getRouteModule ( mod ) )
178
- }
179
-
180
190
// pre-bundle
181
191
if ( ! this . isDev ) {
182
192
await this . bundle ( )
@@ -221,13 +231,13 @@ export class Application implements ServerApplication {
221
231
222
232
// is dep
223
233
for ( const { deps } of this . #modules. values ( ) ) {
224
- if ( deps . findIndex ( dep => dep . url === url ) > - 1 ) {
234
+ if ( deps . some ( dep => dep . url === url ) ) {
225
235
return true
226
236
}
227
237
}
228
238
229
239
// is loaded by plugin
230
- return this . config . plugins . findIndex ( p => p . type === 'loader' && p . test . test ( url ) ) > - 1
240
+ return this . config . plugins . some ( p => p . type === 'loader' && p . test . test ( url ) )
231
241
}
232
242
233
243
if ( validated ( ) ) {
@@ -455,7 +465,7 @@ export class Application implements ServerApplication {
455
465
if ( ! this . isDev ) {
456
466
return false
457
467
}
458
- for ( const ext of [ 'tsx' , 'jsx' , 'ts' , 'js' , 'mjs' ] ) {
468
+ for ( const ext of moduleExts ) {
459
469
if ( url . endsWith ( '.' + ext ) ) {
460
470
return url . startsWith ( '/pages/' ) ||
461
471
url . startsWith ( '/components/' ) ||
0 commit comments