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

Commit 592e24b

Browse files
committed
refactor(server): add copyDist method
1 parent 39f0b62 commit 592e24b

File tree

1 file changed

+103
-73
lines changed

1 file changed

+103
-73
lines changed

server/app.ts

Lines changed: 103 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,15 @@ export class Appliaction {
265265
// ensure output dir
266266
await ensureDir(distDir)
267267

268-
// ssg, bundle & optimizing
269-
await this.bundle()
268+
// optimizing
270269
await this.optimize()
270+
271+
// ssg
271272
await this.ssg()
272273

274+
// copy bundle dist
275+
await this.copyDist()
276+
273277
// copy public assets
274278
const publicDir = path.join(this.workingDir, 'public')
275279
if (existsDirSync(publicDir)) {
@@ -342,15 +346,15 @@ export class Appliaction {
342346
private getScripts() {
343347
const baseUrl = path.join(this.config.baseUrl, '/_aleph/')
344348
const mainModule = this.#modules.get('/main.ts')!
345-
const depsModule = this.#modules.get('/deps.bundling.js')
346-
const sharedModule = this.#modules.get('/shared.bundling.js')
349+
const depsModule = this.#modules.get('/deps.js')
350+
const sharedModule = this.#modules.get('/shared.js')
347351
const polyfillModule = this.#modules.get('/polyfill.js')
348352

349353
return [
350-
polyfillModule ? { src: path.join(baseUrl, `polyfill.${util.shortHash(polyfillModule.sourceHash)}.js`) } : {},
351-
depsModule ? { src: path.join(baseUrl, `deps.${util.shortHash(depsModule.sourceHash)}.js`), } : {},
352-
sharedModule ? { src: path.join(baseUrl, `shared.${util.shortHash(sharedModule.sourceHash)}.js`), } : {},
353-
!this.isDev ? { src: path.join(baseUrl, `main.${util.shortHash(mainModule.sourceHash)}.js`), } : {},
354+
polyfillModule ? { src: path.join(baseUrl, `polyfill.bundle.${util.shortHash(polyfillModule.hash)}.js`) } : {},
355+
depsModule ? { src: path.join(baseUrl, `deps.bundle.${util.shortHash(depsModule.hash)}.js`), } : {},
356+
sharedModule ? { src: path.join(baseUrl, `shared.bundle.${util.shortHash(sharedModule.hash)}.js`), } : {},
357+
!this.isDev ? { src: path.join(baseUrl, `main.bundle.${util.shortHash(mainModule.hash)}.js`), } : {},
354358
this.isDev ? { src: path.join(baseUrl, `main.${util.shortHash(mainModule.hash)}.js`), type: 'module' } : {},
355359
this.isDev ? { src: path.join(baseUrl, `-/deno.land/x/aleph/nomodule.js`), nomodule: true } : {},
356360
]
@@ -548,6 +552,10 @@ export class Appliaction {
548552
})
549553
}
550554

555+
if (!this.isDev) {
556+
log.info("Building...")
557+
}
558+
551559
// check custom components
552560
for await (const { path: p, } of walk(this.srcDir, { ...walkOptions, maxDepth: 1, exts: [...walkOptions.exts, '.tsx', '.jsx'] })) {
553561
const name = path.basename(p)
@@ -615,6 +623,8 @@ export class Appliaction {
615623

616624
if (this.isDev) {
617625
this.watch()
626+
} else {
627+
await this.bundle()
618628
}
619629
}
620630

@@ -758,7 +768,7 @@ export class Appliaction {
758768
const sourceCode = [
759769
(this.config.framework === 'react' && this.isDev) && `import "${alephPkgUrl}/framework/react/refresh.ts"`,
760770
`import bootstrap from "${alephPkgUrl}/framework/${framework}/bootstrap.ts"`,
761-
`bootstrap(${JSON.stringify(config, undefined, 4)})`
771+
`bootstrap(${JSON.stringify(config, undefined, this.isDev ? 4 : undefined)})`
762772
].filter(Boolean).join('\n')
763773
await this.compile('/main.ts', { sourceCode })
764774
if (!this.isDev) {
@@ -1283,21 +1293,18 @@ export class Appliaction {
12831293
const lookup = (url: string) => {
12841294
if (this.#modules.has(url)) {
12851295
const { deps } = this.#modules.get(url)!
1286-
deps.forEach(({ url }) => {
1287-
if (!refCounter.has(url)) {
1288-
refCounter.set(url, 1)
1289-
} else {
1296+
new Set(deps.map(({ url }) => url)).forEach(url => {
1297+
if (refCounter.has(url)) {
12901298
refCounter.set(url, refCounter.get(url)! + 1)
1299+
} else {
1300+
refCounter.set(url, 1)
12911301
}
12921302
})
12931303
}
12941304
}
1295-
const appModule = Array.from(this.#modules.keys())
1296-
.filter(url => trimPageModuleExt(url) === '/app')
1297-
.map(url => this.#modules.get(url))[0]
1298-
const e404Module = Array.from(this.#modules.keys())
1299-
.filter(url => trimPageModuleExt(url) === '/404')
1300-
.map(url => this.#modules.get(url))[0]
1305+
const mods = Array.from(this.#modules.values())
1306+
const appModule = mods.find(({ url }) => trimPageModuleExt(url) == '/app')
1307+
const e404Module = mods.find(({ url }) => trimPageModuleExt(url) == '/404')
13011308
const pageModules: Module[] = []
13021309

13031310
lookup('/main.ts')
@@ -1322,6 +1329,8 @@ export class Appliaction {
13221329
}
13231330
}))
13241331

1332+
log.debug(refCounter)
1333+
13251334
const remoteDeps: string[] = []
13261335
const localSharedDeps: string[] = []
13271336
Array.from(refCounter.entries()).forEach(([url, count]) => {
@@ -1338,95 +1347,78 @@ export class Appliaction {
13381347
localSharedDeps.push(e404Module.url)
13391348
}
13401349

1341-
log.info('- Bundle')
1350+
log.info('- Bundling')
13421351
await this.createChunkBundle('deps', remoteDeps)
13431352
if (localSharedDeps.length > 0) {
13441353
await this.createChunkBundle('shared', localSharedDeps)
13451354
}
13461355

1347-
// copy main module
1348-
const mainModule = this.getModule('/main.ts')!
1349-
const mainJSFile = path.join(this.outputDir, '_aleph', `main.${util.shortHash(mainModule.sourceHash)}.js`)
1350-
const mainJSConent = await Deno.readTextFile(mainModule.bundlingFile)
1351-
await Deno.writeTextFile(mainJSFile, mainJSConent)
1352-
13531356
// create and copy polyfill
1354-
const polyfillMode = this.newModule('/polyfill.js')
1357+
const polyfillMod = this.newModule('/polyfill.js')
13551358
const hash = (new Sha1).update(buildChecksum).update(AlephRuntimeCode).update(`${this.config.buildTarget}-${VERSION}`).hex()
1356-
const polyfillFile = path.join(this.buildDir, `polyfill.${util.shortHash(hash)}.js`)
1359+
const polyfillFile = path.join(this.buildDir, `polyfill.bundle.${util.shortHash(hash)}.js`)
13571360
if (!existsFileSync(polyfillFile)) {
13581361
const rawPolyfillFile = `${alephPkgUrl}/compiler/polyfills/${this.config.buildTarget}/polyfill.js`
13591362
await this.runDenoBundle(rawPolyfillFile, polyfillFile, AlephRuntimeCode, true)
13601363
}
1361-
await Deno.copyFile(polyfillFile, path.join(this.outputDir, '_aleph', `polyfill.${util.shortHash(hash)}.js`))
1362-
1363-
polyfillMode.hash = polyfillMode.sourceHash = hash
1364-
this.#modules.set(polyfillMode.url, polyfillMode)
1364+
polyfillMod.hash = polyfillMod.sourceHash = hash
1365+
this.#modules.set(polyfillMod.url, polyfillMod)
1366+
log.info(` {} polyfill (${this.config.buildTarget.toUpperCase()}) ${colors.dim('• ' + util.formatBytes(Deno.statSync(polyfillFile).size))}`)
13651367

13661368
// bundle and copy page moudles
13671369
await Promise.all(pageModules.map(async mod => this.createPageBundle(mod, localSharedDeps)))
1370+
1371+
// create main.bundle.xxxxxxxxx.js
1372+
const mainModule = this.getModule('/main.ts')!
1373+
const bundleFile = path.join(this.buildDir, `main.bundle.${util.shortHash(mainModule.hash)}.js`)
1374+
await Deno.copyFile(mainModule.bundlingFile, bundleFile)
13681375
}
13691376

13701377
/** create chunk bundle. */
1371-
private async createChunkBundle(name: string, list: string[], header = '') {
1372-
const imports = list.map((url, i) => {
1378+
private async createChunkBundle(name: string, list: string[]) {
1379+
const bundlingCode = list.map((url, i) => {
13731380
const mod = this.#modules.get(url)
13741381
if (mod) {
1375-
return [
1376-
`import * as ${name}_mod_${i} from ${JSON.stringify(util.isLikelyHttpURL(mod.url) ? mod.jsFile : mod.bundlingFile)}`,
1382+
const importUrl = util.isLikelyHttpURL(mod.url) ? mod.jsFile : mod.bundlingFile
1383+
return importUrl ? [
1384+
`import * as ${name}_mod_${i} from ${JSON.stringify(importUrl)}`,
13771385
`__ALEPH.pack[${JSON.stringify(url)}] = ${name}_mod_${i}`
1378-
]
1386+
] : []
13791387
}
13801388
}).flat().join('\n')
1381-
const bundlingCode = imports
1382-
const mod = this.newModule(`/${name}.bundling.js`)
1383-
const hash = (new Sha1).update(buildChecksum).update(header).update(bundlingCode).hex()
1389+
const mod = this.newModule(`/${name}.js`)
1390+
const hash = (new Sha1).update(buildChecksum).update(bundlingCode).hex()
13841391
const bundlingFile = path.join(this.buildDir, mod.url)
13851392
const bundleFile = path.join(this.buildDir, `${name}.bundle.${util.shortHash(hash)}.js`)
1386-
const saveAs = path.join(this.outputDir, `_aleph/${name}.${util.shortHash(hash)}.js`)
1387-
1388-
mod.hash = mod.sourceHash = hash
13891393

1390-
if (existsFileSync(bundleFile)) {
1391-
this.#modules.set(mod.url, mod)
1392-
await Deno.rename(bundleFile, saveAs)
1393-
return
1394-
}
1395-
1396-
await Deno.writeTextFile(bundlingFile, bundlingCode)
1397-
const n = await this.runDenoBundle(bundlingFile, bundleFile, header)
1398-
if (n > 0) {
1399-
log.info(` {} ${name}.js ${colors.dim('• ' + util.formatBytes(n))}`)
1394+
if (!existsFileSync(bundleFile)) {
1395+
await Deno.writeTextFile(bundlingFile, bundlingCode)
1396+
await this.runDenoBundle(bundlingFile, bundleFile)
1397+
Deno.remove(bundlingFile)
14001398
}
14011399

1400+
mod.hash = mod.sourceHash = hash
14021401
this.#modules.set(mod.url, mod)
1403-
await Deno.rename(bundleFile, saveAs)
1404-
Deno.remove(bundlingFile)
1402+
1403+
log.info(` {} ${name} ${colors.dim('• ' + util.formatBytes(Deno.statSync(bundleFile).size))}`)
14051404
}
14061405

14071406
/** create page bundle. */
1408-
private async createPageBundle(mod: Module, bundledModules: string[], header = '') {
1407+
private async createPageBundle(mod: Module, bundledModules: string[]) {
14091408
const { bundlingFile, hash } = await this.compile(mod.url, { bundleMode: true, bundledModules })
14101409
const _tmp = util.trimSuffix(bundlingFile.replace(reHashJs, ''), '.bundling')
14111410
const _bundlingFile = _tmp + `.bundling.js`
14121411
const bundleFile = _tmp + `.bundle.${util.shortHash(hash)}.js`
1413-
const saveAs = path.join(this.outputDir, `/_aleph/`, util.trimPrefix(_tmp, this.buildDir) + `.${util.shortHash(hash)}.js`)
14141412

1415-
if (existsFileSync(bundleFile)) {
1416-
await ensureDir(path.dirname(saveAs))
1417-
await Deno.rename(bundleFile, saveAs)
1418-
return
1413+
if (!existsFileSync(bundleFile)) {
1414+
const bundlingCode = [
1415+
`import * as mod from ${JSON.stringify(bundlingFile)}`,
1416+
`__ALEPH.pack[${JSON.stringify(mod.url)}] = mod`
1417+
].join('\n')
1418+
await Deno.writeTextFile(_bundlingFile, bundlingCode)
1419+
await this.runDenoBundle(_bundlingFile, bundleFile)
1420+
Deno.remove(_bundlingFile)
14191421
}
1420-
1421-
const bundlingCode = [
1422-
`import * as mod from ${JSON.stringify(bundlingFile)}`,
1423-
`__ALEPH.pack[${JSON.stringify(mod.url)}] = mod`
1424-
].join('\n')
1425-
await Deno.writeTextFile(_bundlingFile, bundlingCode)
1426-
await this.runDenoBundle(_bundlingFile, bundleFile, header)
1427-
await ensureDir(path.dirname(saveAs))
1428-
await Deno.rename(bundleFile, saveAs)
1429-
Deno.remove(_bundlingFile)
14301422
}
14311423

14321424
/** run deno bundle and compess the output with terser. */
@@ -1478,7 +1470,43 @@ export class Appliaction {
14781470

14791471
await cleanupCompilation(bundleFile)
14801472
await Deno.writeTextFile(bundleFile, code)
1481-
return code.length
1473+
}
1474+
1475+
private async copyDist() {
1476+
const pageModules: Module[] = []
1477+
this.#pageRouting.lookup(routes => routes.forEach(({ module: { url } }) => {
1478+
const mod = this.getModule(url)
1479+
if (mod) {
1480+
pageModules.push(mod)
1481+
}
1482+
}))
1483+
1484+
await Promise.all([
1485+
(async () => {
1486+
const mainModule = this.getModule('/main.ts')!
1487+
const filename = `main.bundle.${util.shortHash(mainModule.hash)}.js`
1488+
const bundleFile = path.join(this.buildDir, filename)
1489+
const saveAs = path.join(this.outputDir, '_aleph', filename)
1490+
await Deno.copyFile(bundleFile, saveAs)
1491+
})(),
1492+
...['deps', 'shared', 'polyfill'].map(async name => {
1493+
const mod = this.#modules.get(`/${name}.js`)
1494+
if (mod) {
1495+
const { hash } = mod
1496+
const bundleFile = path.join(this.buildDir, `${name}.bundle.${util.shortHash(hash)}.js`)
1497+
const saveAs = path.join(this.outputDir, '_aleph', `${name}.bundle.${util.shortHash(hash)}.js`)
1498+
await Deno.copyFile(bundleFile, saveAs)
1499+
}
1500+
}),
1501+
...pageModules.map(async mod => {
1502+
const { bundlingFile, hash } = mod
1503+
const _tmp = util.trimSuffix(bundlingFile.replace(reHashJs, ''), '.bundling')
1504+
const bundleFile = _tmp + `.bundle.${util.shortHash(hash)}.js`
1505+
const saveAs = path.join(this.outputDir, `/_aleph/`, util.trimPrefix(_tmp, this.buildDir) + `.bundle.${util.shortHash(hash)}.js`)
1506+
await ensureDir(path.dirname(saveAs))
1507+
await Deno.copyFile(bundleFile, saveAs)
1508+
})
1509+
])
14821510
}
14831511

14841512
/** optimize for production. */
@@ -1606,7 +1634,9 @@ export class Appliaction {
16061634
ret.body = `<div id="__aleph">${body}</div>`
16071635
ret.data = data
16081636
this.#renderCache.get(url.pagePath)!.set(key, ret)
1609-
log.info(`render '${url.pathname}' in ${Math.round(performance.now() - start)}ms`)
1637+
if (this.isDev) {
1638+
log.info(`render '${url.pathname}' in ${Math.round(performance.now() - start)}ms`)
1639+
}
16101640
} catch (err) {
16111641
ret.status = 500
16121642
ret.head = ['<title>Error 500 - Aleph.js</title>']

0 commit comments

Comments
 (0)