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

Commit 84b6229

Browse files
committed
refactor: improve remote module url resolve
1 parent a7a5bd6 commit 84b6229

File tree

4 files changed

+62
-32
lines changed

4 files changed

+62
-32
lines changed

compiler/src/resolve.rs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -149,35 +149,40 @@ impl Resolver {
149149
},
150150
None => "js",
151151
});
152-
match path.file_name() {
153-
Some(os_str) => match os_str.to_str() {
154-
Some(s) => {
155-
let mut file_name = s.trim_end_matches(ext.as_str()).to_owned();
156-
match url.query() {
157-
Some(q) => {
158-
file_name.push('_');
159-
file_name.push_str(q);
160-
}
161-
_ => {}
162-
};
152+
if let Some(os_str) = path.file_name() {
153+
if let Some(s) = os_str.to_str() {
154+
let mut file_name = "".to_owned();
155+
if let Some(q) = url.query() {
156+
file_name.push('[');
157+
file_name.push_str(
158+
base64::encode(q)
159+
.replace("+", "")
160+
.replace("/", "")
161+
.replace("=", "")
162+
.as_str(),
163+
);
164+
file_name.push(']');
165+
}
166+
file_name.push_str(s);
167+
if !file_name.ends_with(ext.as_str()) {
163168
file_name.push_str(ext.as_str());
164-
path_buf.set_file_name(file_name);
165169
}
166-
_ => {}
167-
},
168-
_ => {}
169-
};
170+
path_buf.set_file_name(file_name);
171+
}
172+
}
170173
let mut p = "/-/".to_owned();
171-
if url.scheme() == "http" {
174+
let scheme = url.scheme();
175+
if scheme == "http" {
172176
p.push_str("http_");
173177
}
174178
p.push_str(url.host_str().unwrap());
175-
match url.port() {
176-
Some(port) => {
179+
if let Some(port) = url.port() {
180+
if scheme == "http" && port == 80 {
181+
} else if scheme == "https" && port == 443 {
182+
} else {
177183
p.push('_');
178184
p.push_str(port.to_string().as_str());
179185
}
180-
_ => {}
181186
}
182187
p.push_str(path_buf.to_str().unwrap());
183188
p
@@ -387,7 +392,7 @@ mod tests {
387392
);
388393
assert_eq!(
389394
resolver.fix_import_url("https://esm.sh/[email protected]?target=es2015&dev"),
390-
"/-/esm.sh/[email protected].1_target=es2015&dev.js"
395+
"/-/esm.sh/[dGFyZ2V0PWVzMjAxNSZkZXY][email protected].1.js"
391396
);
392397
assert_eq!(
393398
resolver.fix_import_url("http://localhost:8080/mod"),

compiler/src/swc.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,11 @@ mod tests {
569569
None,
570570
None,
571571
true,
572-
vec!["/components/logo.ts".into(), "/shared/iife.ts".into()],
572+
vec![
573+
"https://esm.sh/react".into(),
574+
"/components/logo.ts".into(),
575+
"/shared/iife.ts".into(),
576+
],
573577
)));
574578
let (code, _) = module
575579
.transform(resolver.clone(), &EmitOptions::default())

server/helper.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { colors, createHash, path } from '../deps.ts'
22
import { existsDirSync } from '../shared/fs.ts'
33
import { moduleExts } from '../shared/constants.ts'
4-
import log from '../shared/log.ts'
54
import util from '../shared/util.ts'
65
import { VERSION } from '../version.ts'
76

@@ -81,22 +80,28 @@ export function trimModuleExt(url: string) {
8180

8281
/** fix remote import url to local */
8382
export function toLocalUrl(url: string): string {
84-
const isRemote = util.isLikelyHttpURL(url)
85-
if (isRemote) {
86-
let { hostname, pathname, port, protocol, searchParams } = new URL(url)
87-
let search = Array.from(searchParams.entries()).map(([key, value]) => value ? `${key}=${value}` : key)
88-
if (search.length > 0) {
89-
pathname += '_' + search.join(',')
83+
if (util.isLikelyHttpURL(url)) {
84+
let { hostname, pathname, port, protocol, search } = new URL(url)
85+
const isHttp = protocol === 'http:'
86+
if ((isHttp && port === '80') || (protocol === 'https:' && port === '443')) {
87+
port = ''
88+
}
89+
if (search !== '') {
90+
const a = util.splitPath(pathname)
91+
const searchKey = btoa(search.slice(1)).replace(/[+/=]/g, '')
92+
const basename = `[${searchKey}]${a.pop()}`
93+
a.push(basename)
94+
pathname = '/' + a.join('/')
9095
}
9196
return [
9297
'/-/',
93-
(protocol === 'http:' ? 'http_' : ''),
98+
(isHttp ? 'http_' : ''),
9499
hostname,
95100
(port ? '_' + port : ''),
96101
pathname
97102
].join('')
98103
}
99-
return url
104+
return util.trimPrefix(url, 'file://')
100105
}
101106

102107
/** compute hash of the content */
@@ -126,7 +131,7 @@ export async function clearCompilation(jsFile: string) {
126131
export function parsePortNumber(v: string): number {
127132
const num = parseInt(v)
128133
if (isNaN(num) || !Number.isInteger(num) || num <= 0 || num >= 1 << 16) {
129-
log.fatal(`invalid port '${v}'`)
134+
throw new Error(`invalid port '${v}'`)
130135
}
131136
return num
132137
}

server/helper_test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { assertEquals } from 'https://deno.land/[email protected]/testing/asserts.ts'
2+
import { toLocalUrl } from './helper.ts'
3+
4+
Deno.test(`server/helper`, async () => {
5+
// test toLocalUrl()
6+
{
7+
assertEquals(toLocalUrl('https://esm.sh/[email protected]'), '/-/esm.sh/[email protected]')
8+
assertEquals(toLocalUrl('https://esm.sh:443/[email protected]'), '/-/esm.sh/[email protected]')
9+
assertEquals(toLocalUrl('https://esm.sh/[email protected]?dev'), `/-/esm.sh/[${btoa('dev').replace(/[+/=]/g, '')}][email protected]`)
10+
assertEquals(toLocalUrl('https://esm.sh/[email protected]?target=es2015&dev'), `/-/esm.sh/[${btoa('target=es2015&dev').replace(/[+/=]/g, '')}][email protected]`)
11+
assertEquals(toLocalUrl('http://localhost/mod.ts'), '/-/http_localhost/mod.ts')
12+
assertEquals(toLocalUrl('http://localhost:80/mod.ts'), '/-/http_localhost/mod.ts')
13+
assertEquals(toLocalUrl('http://localhost:8080/mod.ts'), '/-/http_localhost_8080/mod.ts')
14+
assertEquals(toLocalUrl('file:///mod.ts'), '/mod.ts')
15+
}
16+
})

0 commit comments

Comments
 (0)