Skip to content

Commit fbb01a6

Browse files
authored
Merge pull request #1454 from stealjs/https
Allow loading modules from http(s) specifiers
2 parents 79a5651 + 80e1242 commit fbb01a6

18 files changed

+520
-138
lines changed

Gruntfile.js

+3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ module.exports = function (grunt) {
101101
"src/extension-stack-trace.js",
102102
"src/extension-pretty-name.js",
103103
"src/extension-tree-shaking.js",
104+
"src/extension-mjs.js",
104105
"src/trace/trace.js",
105106
"src/json/json.js",
106107
"src/cache-bust/cache-bust.js",
@@ -132,6 +133,7 @@ module.exports = function (grunt) {
132133
"src/extension-stack-trace.js",
133134
"src/extension-pretty-name.js",
134135
"src/extension-tree-shaking.js",
136+
"src/extension-mjs.js",
135137
"src/trace/trace.js",
136138
"src/json/json.js",
137139
"src/cache-bust/cache-bust.js",
@@ -160,6 +162,7 @@ module.exports = function (grunt) {
160162
"src/extension-stack-trace.js",
161163
"src/extension-pretty-name.js",
162164
"src/extension-tree-shaking.js",
165+
"src/extension-mjs.js",
163166
"src/trace/trace.js",
164167
"src/json/json.js",
165168
"src/cache-bust/cache-bust.js",

main.js

+22
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,28 @@ addStealExtension(function(loader) {
12761276
};
12771277
});
12781278

1279+
addStealExtension(function(loader){
1280+
var mjsExp = /\.mjs$/;
1281+
var jsExp = /\.js$/;
1282+
1283+
var locate = loader.locate;
1284+
loader.locate = function(load){
1285+
var isMJS = mjsExp.test(load.name);
1286+
var p = locate.apply(this, arguments);
1287+
1288+
if(isMJS) {
1289+
return Promise.resolve(p).then(function(address) {
1290+
if(jsExp.test(address)) {
1291+
return address.substr(0, address.length - 3);
1292+
}
1293+
return address;
1294+
});
1295+
}
1296+
1297+
return p;
1298+
};
1299+
});
1300+
12791301
addStealExtension(function applyTraceExtension(loader) {
12801302
if(loader._extensions) {
12811303
loader._extensions.push(applyTraceExtension);

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"http-server": "^0.10.0",
6060
"jquery": "^3.1.1",
6161
"live-reload-testing": "^6.0.0",
62+
"nock": "^9.4.3",
6263
"qunitjs": "^2.3.0",
6364
"regenerator-runtime": "^0.10.3",
6465
"saucelabs": "^1.3.0",

src/extension-mjs.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
addStealExtension(function(loader){
2+
var mjsExp = /\.mjs$/;
3+
var jsExp = /\.js$/;
4+
5+
var locate = loader.locate;
6+
loader.locate = function(load){
7+
var isMJS = mjsExp.test(load.name);
8+
var p = locate.apply(this, arguments);
9+
10+
if(isMJS) {
11+
return Promise.resolve(p).then(function(address) {
12+
if(jsExp.test(address)) {
13+
return address.substr(0, address.length - 3);
14+
}
15+
return address;
16+
});
17+
}
18+
19+
return p;
20+
};
21+
});

src/loader/lib/system.js

+49-22
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,16 @@
4242
});
4343
return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
4444
}
45+
var doubleSlash = /^\/\//;
4546
function toAbsoluteURL(inBase, inHref) {
4647
var href = inHref;
4748
var base = inBase
4849

50+
if(doubleSlash.test(inHref)) {
51+
// Default to http
52+
return 'http:' + inHref;
53+
}
54+
4955
if (isWindows)
5056
href = href.replace(/\\/g, '/');
5157

@@ -115,28 +121,49 @@
115121
}
116122
}
117123
else if (typeof require != 'undefined') {
118-
var fs, fourOhFourFS = /ENOENT/;
124+
var fs, http, https, fourOhFourFS = /ENOENT/;
119125
fetchTextFromURL = function(rawUrl, fulfill, reject) {
120-
if (rawUrl.substr(0, 5) != 'file:')
121-
throw 'Only file URLs of the form file: allowed running in Node.';
122-
fs = fs || require('fs');
123-
var url = rawUrl.substr(5);
124-
if (isWindows)
125-
url = url.replace(/\//g, '\\');
126-
return fs.readFile(url, function(err, data) {
127-
if (err) {
128-
// Mark this error as a 404, so that the npm extension
129-
// will know to retry.
130-
if(fourOhFourFS.test(err.message)) {
131-
err.statusCode = 404;
132-
err.url = rawUrl;
133-
}
126+
if (rawUrl.substr(0, 5) === 'file:') {
127+
fs = fs || require('fs');
128+
var url = rawUrl.substr(5);
129+
if (isWindows)
130+
url = url.replace(/\//g, '\\');
131+
return fs.readFile(url, function(err, data) {
132+
if (err) {
133+
// Mark this error as a 404, so that the npm extension
134+
// will know to retry.
135+
if(fourOhFourFS.test(err.message)) {
136+
err.statusCode = 404;
137+
err.url = rawUrl;
138+
}
134139

135-
return reject(err);
136-
} else {
137-
fulfill(data + '');
138-
}
139-
});
140+
return reject(err);
141+
} else {
142+
fulfill(data + '');
143+
}
144+
});
145+
} else if(rawUrl.substr(0, 4) === 'http') {
146+
var h;
147+
if(rawUrl.substr(0, 6) === 'https:') {
148+
h = https = https || require('https');
149+
} else {
150+
h = http = http || require('http');
151+
}
152+
return h.get(rawUrl, function(res) {
153+
if(res.statusCode !== 200) {
154+
reject(new Error('Request failed. Status: ' + res.statusCode));
155+
} else {
156+
var rawData = "";
157+
res.setEncoding("utf8");
158+
res.on("data", function(chunk) {
159+
rawData += chunk;
160+
});
161+
res.on("end", function(){
162+
fulfill(rawData);
163+
});
164+
}
165+
})
166+
}
140167
}
141168
}
142169
else if(typeof fetch === 'function') {
@@ -255,11 +282,11 @@
255282
dotdots = i;
256283
}
257284

258-
for (var j = i; j < segments.length; j++) {
285+
/*for (var j = i; j < segments.length; j++) {
259286
var segment = segments[j];
260287
if (segment == '' || segment == '.' || segment == '..')
261288
throw new TypeError('Illegal module name "' + name + '"');
262-
}
289+
}*/
263290

264291
if (!rel)
265292
return name;

src/loader/loader-with-promises.js

+50-22
Original file line numberDiff line numberDiff line change
@@ -3209,10 +3209,17 @@ function logloads(loads) {
32093209
return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
32103210
}
32113211

3212+
var doubleSlash = /^\/\//;
3213+
32123214
function toAbsoluteURL(inBase, inHref) {
32133215
var href = inHref;
32143216
var base = inBase
32153217

3218+
if(doubleSlash.test(inHref)) {
3219+
// Default to http
3220+
return 'http:' + inHref;
3221+
}
3222+
32163223
if (isWindows)
32173224
href = href.replace(/\\/g, '/');
32183225

@@ -3283,28 +3290,49 @@ function logloads(loads) {
32833290
}
32843291
}
32853292
else if (typeof require != 'undefined') {
3286-
var fs, fourOhFourFS = /ENOENT/;
3293+
var fs, http, https, fourOhFourFS = /ENOENT/;
32873294
fetchTextFromURL = function(rawUrl, fulfill, reject) {
3288-
if (rawUrl.substr(0, 5) != 'file:')
3289-
throw 'Only file URLs of the form file: allowed running in Node.';
3290-
fs = fs || require('fs');
3291-
var url = rawUrl.substr(5);
3292-
if (isWindows)
3293-
url = url.replace(/\//g, '\\');
3294-
return fs.readFile(url, function(err, data) {
3295-
if (err) {
3296-
// Mark this error as a 404, so that the npm extension
3297-
// will know to retry.
3298-
if(fourOhFourFS.test(err.message)) {
3299-
err.statusCode = 404;
3300-
err.url = rawUrl;
3301-
}
3295+
if (rawUrl.substr(0, 5) === 'file:') {
3296+
fs = fs || require('fs');
3297+
var url = rawUrl.substr(5);
3298+
if (isWindows)
3299+
url = url.replace(/\//g, '\\');
3300+
return fs.readFile(url, function(err, data) {
3301+
if (err) {
3302+
// Mark this error as a 404, so that the npm extension
3303+
// will know to retry.
3304+
if(fourOhFourFS.test(err.message)) {
3305+
err.statusCode = 404;
3306+
err.url = rawUrl;
3307+
}
33023308

3303-
return reject(err);
3304-
} else {
3305-
fulfill(data + '');
3306-
}
3307-
});
3309+
return reject(err);
3310+
} else {
3311+
fulfill(data + '');
3312+
}
3313+
});
3314+
} else if(rawUrl.substr(0, 4) === 'http') {
3315+
var h;
3316+
if(rawUrl.substr(0, 6) === 'https:') {
3317+
h = https = https || require('https');
3318+
} else {
3319+
h = http = http || require('http');
3320+
}
3321+
return h.get(rawUrl, function(res) {
3322+
if(res.statusCode !== 200) {
3323+
reject(new Error('Request failed. Status: ' + res.statusCode));
3324+
} else {
3325+
var rawData = "";
3326+
res.setEncoding("utf8");
3327+
res.on("data", function(chunk) {
3328+
rawData += chunk;
3329+
});
3330+
res.on("end", function(){
3331+
fulfill(rawData);
3332+
});
3333+
}
3334+
})
3335+
}
33083336
}
33093337
}
33103338
else if(typeof fetch === 'function') {
@@ -3437,11 +3465,11 @@ function logloads(loads) {
34373465
dotdots = i;
34383466
}
34393467

3440-
for (var j = i; j < segments.length; j++) {
3468+
/*for (var j = i; j < segments.length; j++) {
34413469
var segment = segments[j];
34423470
if (segment == '' || segment == '.' || segment == '..')
34433471
throw new TypeError('Illegal module name "' + name + '"');
3444-
}
3472+
}*/
34453473

34463474
if (!rel)
34473475
return name;

src/loader/loader.js

+50-22
Original file line numberDiff line numberDiff line change
@@ -1939,10 +1939,17 @@ function logloads(loads) {
19391939
return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
19401940
}
19411941

1942+
var doubleSlash = /^\/\//;
1943+
19421944
function toAbsoluteURL(inBase, inHref) {
19431945
var href = inHref;
19441946
var base = inBase
19451947

1948+
if(doubleSlash.test(inHref)) {
1949+
// Default to http
1950+
return 'http:' + inHref;
1951+
}
1952+
19461953
if (isWindows)
19471954
href = href.replace(/\\/g, '/');
19481955

@@ -2013,28 +2020,49 @@ function logloads(loads) {
20132020
}
20142021
}
20152022
else if (typeof require != 'undefined') {
2016-
var fs, fourOhFourFS = /ENOENT/;
2023+
var fs, http, https, fourOhFourFS = /ENOENT/;
20172024
fetchTextFromURL = function(rawUrl, fulfill, reject) {
2018-
if (rawUrl.substr(0, 5) != 'file:')
2019-
throw 'Only file URLs of the form file: allowed running in Node.';
2020-
fs = fs || require('fs');
2021-
var url = rawUrl.substr(5);
2022-
if (isWindows)
2023-
url = url.replace(/\//g, '\\');
2024-
return fs.readFile(url, function(err, data) {
2025-
if (err) {
2026-
// Mark this error as a 404, so that the npm extension
2027-
// will know to retry.
2028-
if(fourOhFourFS.test(err.message)) {
2029-
err.statusCode = 404;
2030-
err.url = rawUrl;
2031-
}
2025+
if (rawUrl.substr(0, 5) === 'file:') {
2026+
fs = fs || require('fs');
2027+
var url = rawUrl.substr(5);
2028+
if (isWindows)
2029+
url = url.replace(/\//g, '\\');
2030+
return fs.readFile(url, function(err, data) {
2031+
if (err) {
2032+
// Mark this error as a 404, so that the npm extension
2033+
// will know to retry.
2034+
if(fourOhFourFS.test(err.message)) {
2035+
err.statusCode = 404;
2036+
err.url = rawUrl;
2037+
}
20322038

2033-
return reject(err);
2034-
} else {
2035-
fulfill(data + '');
2036-
}
2037-
});
2039+
return reject(err);
2040+
} else {
2041+
fulfill(data + '');
2042+
}
2043+
});
2044+
} else if(rawUrl.substr(0, 4) === 'http') {
2045+
var h;
2046+
if(rawUrl.substr(0, 6) === 'https:') {
2047+
h = https = https || require('https');
2048+
} else {
2049+
h = http = http || require('http');
2050+
}
2051+
return h.get(rawUrl, function(res) {
2052+
if(res.statusCode !== 200) {
2053+
reject(new Error('Request failed. Status: ' + res.statusCode));
2054+
} else {
2055+
var rawData = "";
2056+
res.setEncoding("utf8");
2057+
res.on("data", function(chunk) {
2058+
rawData += chunk;
2059+
});
2060+
res.on("end", function(){
2061+
fulfill(rawData);
2062+
});
2063+
}
2064+
})
2065+
}
20382066
}
20392067
}
20402068
else if(typeof fetch === 'function') {
@@ -2167,11 +2195,11 @@ function logloads(loads) {
21672195
dotdots = i;
21682196
}
21692197

2170-
for (var j = i; j < segments.length; j++) {
2198+
/*for (var j = i; j < segments.length; j++) {
21712199
var segment = segments[j];
21722200
if (segment == '' || segment == '.' || segment == '..')
21732201
throw new TypeError('Illegal module name "' + name + '"');
2174-
}
2202+
}*/
21752203

21762204
if (!rel)
21772205
return name;

0 commit comments

Comments
 (0)