Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit 22cb81a

Browse files
committed
reactor(server): rewrte bundler(WIP)
1 parent df0495f commit 22cb81a

File tree

2 files changed

+190
-133
lines changed

2 files changed

+190
-133
lines changed

server/app.ts

Lines changed: 98 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ImportMap, TransformOptions } from '../compiler/mod.ts'
1+
import { ImportMap, SourceType, TransformOptions } from '../compiler/mod.ts'
22
import { buildChecksum, transform } from '../compiler/mod.ts'
33
import { colors, createHash, ensureDir, path, walk } from '../deps.ts'
44
import { EventEmitter } from '../framework/core/events.ts'
@@ -280,6 +280,35 @@ export class Application implements ServerApplication {
280280
}
281281
}
282282

283+
private isScopedModule(url: string) {
284+
for (const ext of moduleExts) {
285+
if (url.endsWith('.' + ext)) {
286+
if (url.startsWith('/pages/') || url.startsWith('/api/')) {
287+
return true
288+
}
289+
switch (trimModuleExt(url)) {
290+
case '/404':
291+
case '/app':
292+
return true
293+
}
294+
}
295+
}
296+
297+
// is page module by plugin
298+
if (this.config.plugins.some(p => p.type === 'loader' && p.test.test(url) && p.allowPage)) {
299+
return true
300+
}
301+
302+
// is dep
303+
for (const { deps } of this.#modules.values()) {
304+
if (deps.some(dep => dep.url === url)) {
305+
return true
306+
}
307+
}
308+
309+
return false
310+
}
311+
283312
get isDev() {
284313
return this.mode === 'development'
285314
}
@@ -478,8 +507,8 @@ export class Application implements ServerApplication {
478507

479508
if (bundleMode) {
480509
return [
481-
`var bootstrap=__ALEPH.pack["${alephPkgUri}/framework/${framework}/bootstrap.ts"].default;`,
482-
`bootstrap(${JSON.stringify(config)});`
510+
`__ALEPH.baseURL = ${JSON.stringify(baseURL)};`,
511+
`__ALEPH.pack["${alephPkgUri}/framework/${framework}/bootstrap.ts"].default(${JSON.stringify(config)});`
483512
].join('\n')
484513
}
485514

@@ -683,31 +712,24 @@ export class Application implements ServerApplication {
683712
url: string,
684713
sourceContent: Uint8Array,
685714
contentType: string | null
686-
): Promise<[string, 'js' | 'jsx' | 'ts' | 'tsx'] | null> {
715+
): Promise<[string, SourceType] | null> {
687716
let sourceCode = (new TextDecoder).decode(sourceContent)
688-
let sourceType = path.extname(url).slice(1)
689-
690-
if (sourceType == 'mjs') {
691-
sourceType = 'js'
692-
}
717+
let sourceType: SourceType = SourceType.Unknown
693718

694719
if (contentType !== null) {
695720
switch (contentType.split(';')[0].trim()) {
696721
case 'application/javascript':
697722
case 'text/javascript':
698-
sourceType = 'js'
723+
sourceType = SourceType.JS
699724
break
700725
case 'text/typescript':
701-
sourceType = 'ts'
726+
sourceType = SourceType.TS
702727
break
703728
case 'text/jsx':
704-
sourceType = 'jsx'
729+
sourceType = SourceType.JSX
705730
break
706731
case 'text/tsx':
707-
sourceType = 'tsx'
708-
break
709-
default:
710-
sourceType = 'js'
732+
sourceType = SourceType.TSX
711733
break
712734
}
713735
}
@@ -719,19 +741,42 @@ export class Application implements ServerApplication {
719741
{ url, content: sourceContent }
720742
)
721743
sourceCode = code
722-
sourceType = type
744+
switch (type) {
745+
case 'js':
746+
sourceType = SourceType.JS
747+
break
748+
case 'jsx':
749+
sourceType = SourceType.JSX
750+
break
751+
case 'ts':
752+
sourceType = SourceType.TS
753+
break
754+
case 'tsx':
755+
sourceType = SourceType.TSX
756+
break
757+
}
723758
break
724759
}
725760
}
726761

727-
switch (sourceType) {
728-
case 'js':
729-
case 'jsx':
730-
case 'ts':
731-
case 'tsx':
732-
break
733-
default:
734-
return null
762+
if (sourceType === SourceType.Unknown) {
763+
switch (path.extname(url).slice(1).toLowerCase()) {
764+
case 'mjs':
765+
case 'js':
766+
sourceType = SourceType.JS
767+
break
768+
case 'jsx':
769+
sourceType = SourceType.JSX
770+
break
771+
case 'ts':
772+
sourceType = SourceType.TS
773+
break
774+
case 'tsx':
775+
sourceType = SourceType.TSX
776+
break
777+
default:
778+
return null
779+
}
735780
}
736781

737782
return [sourceCode, sourceType]
@@ -943,30 +988,27 @@ export class Application implements ServerApplication {
943988

944989
/** create bundle chunks for production. */
945990
private async bundle() {
946-
const sharedScopeMods = new Set<string>()
947991
const sharedEntryMods = new Set<string>()
948-
const entryMods = new Map<string, boolean>()
992+
const entryMods = new Map<string[], boolean>()
949993
const refCounter = new Map<string, Set<string>>()
950994
const concatAllEntries = () => [
951-
Array.from(entryMods.entries()).map(([url, shared]) => ({ url, shared })),
995+
Array.from(entryMods.entries()).map(([urls, shared]) => urls.map(url => ({ url, shared }))),
952996
Array.from(sharedEntryMods).map(url => ({ url, shared: true })),
953-
].flat()
997+
].flat(2)
954998

955999
// add framwork bootstrap module as shared entry
956-
entryMods.set(`${getAlephPkgUri()}/framework/${this.config.framework}/bootstrap.ts`, true)
1000+
entryMods.set(
1001+
[`${getAlephPkgUri()}/framework/${this.config.framework}/bootstrap.ts`],
1002+
true
1003+
)
1004+
1005+
entryMods.set(Array.from(this.#modules.keys()).filter(url => ['/app', '/404'].includes(trimModuleExt(url))), true)
9571006

9581007
this.#modules.forEach(mod => {
959-
switch (trimModuleExt(mod.url)) {
960-
case '/app':
961-
case '/404':
962-
// add custom app/404 module as shared entry
963-
entryMods.set(mod.url, true)
964-
break
965-
}
9661008
mod.deps.forEach(({ url, isDynamic }) => {
9671009
if (isDynamic) {
9681010
// add dynamic imported module as entry
969-
entryMods.set(url, false)
1011+
entryMods.set([url], false)
9701012
}
9711013
return url
9721014
})
@@ -983,44 +1025,34 @@ export class Application implements ServerApplication {
9831025

9841026
// add page module entries
9851027
this.#pageRouting.lookup(routes => {
986-
routes.forEach(({ module: { url } }) => entryMods.set(url, false))
1028+
routes.forEach(({ module: { url } }) => entryMods.set([url], false))
9871029
})
9881030

9891031
refCounter.forEach((refers, url) => {
9901032
if (refers.size > 1) {
991-
for (const [key, shared] of entryMods.entries()) {
992-
if ((!shared || !util.isLikelyHttpURL(key)) && refers.has(key)) {
993-
// add shared module entry
994-
sharedEntryMods.add(url)
995-
break
1033+
let shared = 0
1034+
for (const mods of entryMods.keys()) {
1035+
const some = mods.some(u => {
1036+
let scoped = false
1037+
this.lookupDeps(u, dep => {
1038+
if (!dep.isDynamic && refers.has(dep.url)) {
1039+
scoped = true
1040+
return false
1041+
}
1042+
})
1043+
return scoped
1044+
})
1045+
if (some) {
1046+
shared++
9961047
}
9971048
}
998-
}
999-
})
1000-
1001-
// some modules are shared deeply
1002-
const entries = concatAllEntries()
1003-
entries.forEach(({ url, shared }) => {
1004-
if (shared) {
1005-
this.lookupDeps(url, dep => {
1006-
if (!dep.isDynamic) {
1007-
sharedScopeMods.add(dep.url)
1008-
}
1009-
})
1010-
}
1011-
})
1012-
refCounter.forEach((refers, url) => {
1013-
if (refers.size > 1) {
1014-
const scopedMods = [
1015-
...Array.from(sharedScopeMods),
1016-
...entries.map(({ url }) => url)
1017-
]
1018-
if (scopedMods.every(url => !refers.has(url))) {
1049+
if (shared > 1) {
10191050
sharedEntryMods.add(url)
10201051
}
10211052
}
10221053
})
10231054

1055+
log.info('- bundle')
10241056
await this.#bundler.bundle(concatAllEntries())
10251057
}
10261058

@@ -1130,37 +1162,8 @@ export class Application implements ServerApplication {
11301162
return ssr
11311163
}
11321164

1133-
private isScopedModule(url: string) {
1134-
for (const ext of moduleExts) {
1135-
if (url.endsWith('.' + ext)) {
1136-
if (url.startsWith('/pages/') || url.startsWith('/api/')) {
1137-
return true
1138-
}
1139-
switch (trimModuleExt(url)) {
1140-
case '/404':
1141-
case '/app':
1142-
return true
1143-
}
1144-
}
1145-
}
1146-
1147-
// is page module by plugin
1148-
if (this.config.plugins.some(p => p.type === 'loader' && p.test.test(url) && p.allowPage)) {
1149-
return true
1150-
}
1151-
1152-
// is dep
1153-
for (const { deps } of this.#modules.values()) {
1154-
if (deps.some(dep => dep.url === url)) {
1155-
return true
1156-
}
1157-
}
1158-
1159-
return false
1160-
}
1161-
11621165
/** lookup deps recurively. */
1163-
private lookupDeps(
1166+
lookupDeps(
11641167
url: string,
11651168
callback: (dep: DependencyDescriptor) => false | void,
11661169
__tracing: Set<string> = new Set()

0 commit comments

Comments
 (0)