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

Commit 79829bd

Browse files
author
Wenjie Xia
committed
refactor: simplify import map
1 parent b275e48 commit 79829bd

File tree

5 files changed

+71
-91
lines changed

5 files changed

+71
-91
lines changed

compiler/src/import_map.rs

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use indexmap::IndexMap;
44
use serde::Deserialize;
55
use std::collections::HashMap;
66

7-
type SpecifierHashMap = HashMap<String, Vec<String>>;
8-
type SpecifierMap = IndexMap<String, Vec<String>>;
7+
type SpecifierHashMap = HashMap<String, String>;
8+
type SpecifierMap = IndexMap<String, String>;
99

1010
#[derive(Clone, Debug, Deserialize)]
1111
#[serde(deny_unknown_fields)]
@@ -36,14 +36,14 @@ impl ImportMap {
3636
let mut imports: SpecifierMap = IndexMap::new();
3737
let mut scopes = IndexMap::new();
3838
for (k, v) in map.imports.iter() {
39-
imports.insert(k.into(), v.to_vec());
39+
imports.insert(k.into(), v.into());
4040
}
4141
for (k, v) in map.scopes.iter() {
42-
let mut imports_: SpecifierMap = IndexMap::new();
43-
for (k_, v_) in v.iter() {
44-
imports_.insert(k_.into(), v_.to_vec());
42+
let mut map: SpecifierMap = IndexMap::new();
43+
for (k, v) in v.iter() {
44+
map.insert(k.into(), v.into());
4545
}
46-
scopes.insert(k.into(), imports_);
46+
scopes.insert(k.into(), map);
4747
}
4848
ImportMap { imports, scopes }
4949
}
@@ -53,42 +53,30 @@ impl ImportMap {
5353
if prefix.ends_with("/") && specifier.starts_with(prefix) {
5454
match scope_imports.get(url) {
5555
Some(alias) => {
56-
let n = alias.len();
57-
if n > 0 {
58-
return alias[n - 1].to_owned();
59-
}
56+
return alias.to_owned();
6057
}
6158
_ => {}
6259
};
6360
for (k, alias) in scope_imports.iter() {
6461
if k.ends_with("/") && url.starts_with(k) {
65-
let n = alias.len();
66-
if n > 0 {
67-
let mut alias = alias[n - 1].to_owned();
68-
alias.push_str(url[k.len()..].into());
69-
return alias;
70-
}
62+
let mut alias = alias.to_owned();
63+
alias.push_str(url[k.len()..].into());
64+
return alias;
7165
}
7266
}
7367
}
7468
}
7569
match self.imports.get(url) {
7670
Some(alias) => {
77-
let n = alias.len();
78-
if n > 0 {
79-
return alias[n - 1].to_owned();
80-
}
71+
return alias.to_owned();
8172
}
8273
_ => {}
8374
};
8475
for (k, alias) in self.imports.iter() {
8576
if k.ends_with("/") && url.starts_with(k) {
86-
let n = alias.len();
87-
if n > 0 {
88-
let mut alias = alias[n - 1].to_owned();
89-
alias.push_str(url[k.len()..].into());
90-
return alias;
91-
}
77+
let mut alias = alias.to_owned();
78+
alias.push_str(url[k.len()..].into());
79+
return alias;
9280
}
9381
}
9482
url.into()
@@ -104,16 +92,13 @@ mod tests {
10492
let mut imports: SpecifierHashMap = HashMap::new();
10593
let mut scopes: HashMap<String, SpecifierHashMap> = HashMap::new();
10694
let mut scope_imports: SpecifierHashMap = HashMap::new();
107-
imports.insert("react".into(), vec!["https://esm.sh/react".into()]);
108-
imports.insert(
109-
"react-dom/".into(),
110-
vec!["https://esm.sh/react-dom/".into()],
111-
);
95+
imports.insert("react".into(), "https://esm.sh/react".into());
96+
imports.insert("react-dom/".into(), "https://esm.sh/react-dom/".into());
11297
imports.insert(
11398
"https://deno.land/x/aleph/".into(),
114-
vec!["http://localhost:9006/".into()],
99+
"http://localhost:9006/".into(),
115100
);
116-
scope_imports.insert("react".into(), vec!["https://esm.sh/[email protected]".into()]);
101+
scope_imports.insert("react".into(), "https://esm.sh/[email protected]".into());
117102
scopes.insert("/scope/".into(), scope_imports);
118103
let import_map = ImportMap::from_hashmap(ImportHashMap { imports, scopes });
119104
assert_eq!(

compiler/src/resolve.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -836,15 +836,12 @@ mod tests {
836836

837837
#[test]
838838
fn test_resolve_local() {
839-
let mut imports: HashMap<String, Vec<String>> = HashMap::new();
840-
imports.insert("react".into(), vec!["https://esm.sh/react".into()]);
841-
imports.insert(
842-
"react-dom/".into(),
843-
vec!["https://esm.sh/react-dom/".into()],
844-
);
839+
let mut imports: HashMap<String, String> = HashMap::new();
840+
imports.insert("react".into(), "https://esm.sh/react".into());
841+
imports.insert("react-dom/".into(), "https://esm.sh/react-dom/".into());
845842
imports.insert(
846843
"https://deno.land/x/aleph/".into(),
847-
vec!["http://localhost:9006/".into()],
844+
"http://localhost:9006/".into(),
848845
);
849846
let mut resolver = Resolver::new(
850847
"/pages/index.tsx",

server/app.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import util from '../shared/util.ts'
1111
import type { Config, DependencyDescriptor, ImportMap, Module, RenderResult, RouterURL, ServerRequest } from '../types.ts'
1212
import { VERSION } from '../version.ts'
1313
import { Request } from './api.ts'
14-
import { AlephRuntimeCode, cleanupCompilation, createHtml, fixImportMap, fixImportUrl, formatBytesWithColor, getAlephPkgUrl, getRelativePath, respondError } from './util.ts'
14+
import { AlephRuntimeCode, cleanupCompilation, createHtml, fixImportMap, fixImportUrl, formatBytesWithColor, getAlephPkgUrl, getRelativePath, respondErrorJSON } from './util.ts'
1515

1616
/**
1717
* The Aleph Server Appliaction class.
@@ -20,7 +20,7 @@ export class Appliaction {
2020
readonly workingDir: string
2121
readonly mode: 'development' | 'production'
2222
readonly config: Readonly<Required<Config>>
23-
readonly importMap: Readonly<{ imports: ImportMap, scopes: Record<string, ImportMap> }>
23+
readonly importMap: ImportMap
2424
readonly ready: Promise<void>
2525

2626
#denoCacheDir = ''
@@ -171,15 +171,15 @@ export class Appliaction {
171171
if (util.isFunction(handle)) {
172172
await handle(new Request(req, url.pathname, url.params, url.query))
173173
} else {
174-
respondError(req, 500, 'handle not found')
174+
respondErrorJSON(req, 500, 'handle not found')
175175
}
176176
} catch (err) {
177-
respondError(req, 500, err.message)
177+
respondErrorJSON(req, 500, err.message)
178178
log.error('invoke API:', err)
179179
}
180180
}
181181
} else {
182-
respondError(req, 404, 'page not found')
182+
respondErrorJSON(req, 404, 'page not found')
183183
}
184184
}
185185

@@ -340,22 +340,26 @@ export class Appliaction {
340340

341341
/** load config from `aleph.config.(json|mjs|js|ts)` */
342342
private async loadConfig() {
343-
const importMapFile = path.join(this.workingDir, 'import_map.json')
344-
if (existsFileSync(importMapFile)) {
345-
const importMap = JSON.parse(await Deno.readTextFile(importMapFile))
346-
const imports: ImportMap = fixImportMap(importMap.imports)
347-
const scopes: Record<string, ImportMap> = {}
348-
if (util.isPlainObject(importMap.scopes)) {
349-
Object.entries(importMap.scopes).forEach(([key, imports]) => {
350-
scopes[key] = fixImportMap(imports)
351-
})
343+
// load import maps
344+
for (const filename of Array.from(['import_map', 'import-map', 'importmap']).map(name => `${name}.json`)) {
345+
const importMapFile = path.join(this.workingDir, filename)
346+
if (existsFileSync(importMapFile)) {
347+
const importMap = JSON.parse(await Deno.readTextFile(importMapFile))
348+
const imports: Record<string, string> = fixImportMap(importMap.imports)
349+
const scopes: Record<string, Record<string, string>> = {}
350+
if (util.isPlainObject(importMap.scopes)) {
351+
Object.entries(importMap.scopes).forEach(([key, imports]) => {
352+
scopes[key] = fixImportMap(imports)
353+
})
354+
}
355+
Object.assign(this.importMap, { imports, scopes })
356+
break
352357
}
353-
Object.assign(this.importMap, { imports, scopes })
354358
}
355359

356360
const config: Record<string, any> = {}
357361

358-
for (const name of Array.from(['ts', 'js', 'mjs', 'json']).map(ext => `aleph.config.${ext}`)) {
362+
for (const name of Array.from(['ts', 'js', 'json']).map(ext => 'aleph.config.' + ext)) {
359363
const p = path.join(this.workingDir, name)
360364
if (existsFileSync(p)) {
361365
log.info('config loaded from', name)
@@ -455,24 +459,20 @@ export class Appliaction {
455459
}
456460
}
457461

458-
// update import map
462+
// update import map for alephjs dev env
459463
const { __ALEPH_DEV_PORT: devPort } = globalThis as any
460464
if (devPort) {
461465
const alias = `http://localhost:${devPort}/`
462466
const imports = {
463-
'https://deno.land/x/aleph/': [alias],
464-
[`https://deno.land/x/aleph@v${VERSION}/`]: [alias],
465-
'aleph': [`${alias}mod.ts`],
466-
'aleph/': [alias],
467+
'https://deno.land/x/aleph/': alias,
468+
[`https://deno.land/x/aleph@v${VERSION}/`]: alias,
469+
'aleph': `${alias}mod.ts`,
470+
'aleph/': alias,
471+
'react': `https://esm.sh/react@${this.config.reactVersion}`,
472+
'react-dom': `https://esm.sh/react-dom@${this.config.reactVersion}`,
467473
}
468-
Object.assign(this.importMap, { imports: Object.assign({}, this.importMap.imports, imports) })
474+
Object.assign(this.importMap.imports, imports)
469475
}
470-
Object.assign(this.importMap, {
471-
imports: Object.assign({}, {
472-
'react': [`https://esm.sh/react@${this.config.reactVersion}`],
473-
'react-dom': [`https://esm.sh/react-dom@${this.config.reactVersion}`],
474-
}, this.importMap.imports)
475-
})
476476

477477
// create page routing
478478
this.#pageRouting = new Routing([], this.config.baseUrl, this.config.defaultLocale, this.config.locales)

server/util.ts

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { colors, path } from '../deps.ts'
2-
import { MB, reHashJs, reModuleExt, reStyleModuleExt } from '../shared/constants.ts'
2+
import { reHashJs, reModuleExt, reStyleModuleExt } from '../shared/constants.ts'
33
import { existsDirSync } from '../shared/fs.ts'
44
import log from '../shared/log.ts'
55
import util from '../shared/util.ts'
6-
import type { ImportMap, ServerRequest } from '../types.ts'
6+
import type { ServerRequest } from '../types.ts'
77
import { VERSION } from '../version.ts'
88

99
export const AlephRuntimeCode = `
@@ -76,30 +76,25 @@ export async function cleanupCompilation(jsFile: string) {
7676

7777
/** fix import map */
7878
export function fixImportMap(v: any) {
79-
const imports: ImportMap = {}
79+
const imports: Record<string, string> = {}
8080
if (util.isPlainObject(v)) {
8181
Object.entries(v).forEach(([key, value]) => {
82-
if (key == "" || key == "/") {
82+
if (key == '' || key == '/') {
8383
return
8484
}
8585
const isPrefix = key.endsWith('/')
86-
const tmp: string[] = []
87-
if (util.isNEString(value)) {
88-
if (isPrefix && !value.endsWith('/')) {
89-
return
90-
}
91-
tmp.push(value)
86+
const y = (v: string) => util.isNEString(v) && (!isPrefix || v.endsWith('/'))
87+
if (y(value)) {
88+
imports[key] = value
89+
return
9290
} else if (util.isNEArray(value)) {
93-
value.forEach(v => {
94-
if (util.isNEString(v)) {
95-
if (isPrefix && !v.endsWith('/')) {
96-
return
97-
}
98-
tmp.push(v)
91+
for (const v of value) {
92+
if (y(v)) {
93+
imports[key] = v
94+
return
9995
}
100-
})
96+
}
10197
}
102-
imports[key] = tmp
10398
})
10499
}
105100
return imports
@@ -140,16 +135,16 @@ export function fixImportUrl(importUrl: string): string {
140135
*/
141136
export function formatBytesWithColor(bytes: number) {
142137
let cf = colors.dim
143-
if (bytes > 10 * MB) {
138+
if (bytes > 10 << 20) { // 10MB
144139
cf = colors.red
145-
} else if (bytes > MB) {
140+
} else if (bytes > 1 << 20) { // 1MB
146141
cf = colors.yellow
147142
}
148143
return cf(util.formatBytes(bytes))
149144
}
150145

151146
/** Reponse an error jons to the request */
152-
export function respondError(req: ServerRequest, status: number, message: string) {
147+
export function respondErrorJSON(req: ServerRequest, status: number, message: string) {
153148
req.respond({
154149
status,
155150
headers: new Headers({ 'Content-Type': 'application/json; charset=utf-8' }),

types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,7 @@ export type FormFile = {
224224
/**
225225
* The ES Import maps.
226226
*/
227-
export type ImportMap = Record<string, ReadonlyArray<string>>
227+
export type ImportMap = {
228+
imports: Record<string, string>,
229+
scopes: Record<string, Record<string, string>>
230+
}

0 commit comments

Comments
 (0)