Skip to content

Commit 7207361

Browse files
committed
Fallback .js imports to .ts files when there is no .js file and no extension imports to .js files when there are no .ts files
1 parent 4b3e236 commit 7207361

File tree

1 file changed

+61
-24
lines changed

1 file changed

+61
-24
lines changed

src/WorkerManager.js

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const NUM_OF_WORKERS = 3;
1212
*
1313
* it's the md5 of the last commit
1414
*/
15-
const CACHED_FORMAT_VERSION = 'c5cf72a8627e15938f522ddc742c99c98b4bf6e9';
15+
const CACHED_FORMAT_VERSION = '4b3e236d842f6ca0a86cd571c4c203ab8c6cde7a';
1616

1717
function eventToError(data, contextMessage) {
1818
const {messageType, messageData} = data;
@@ -178,30 +178,67 @@ function bufferToHex (buffer) {
178178
.join("");
179179
}
180180

181-
const WorkerManager = ({compilerOptions}) => {
182-
const fetchModuleSrc = (url) => {
183-
// typescript does not allow specifying extension in the import, but react
184-
// files may have .tsx extension rather than .ts, so have to check both
185-
const urlOptions = [];
186-
if (EXPLICIT_EXTENSIONS.some(ext => url.endsWith('.' + ext))) {
187-
urlOptions.push(url);
188-
} else {
189-
urlOptions.push(url + '.ts');
190-
if (compilerOptions.jsx) {
191-
urlOptions.push(url + '.tsx');
181+
function tryFetchModuleSrcWithExt(fullUrl) {
182+
return fetch(fullUrl)
183+
.then(rs => {
184+
if (rs.status === 200) {
185+
return rs.text().then(tsCode => ({fullUrl, tsCode}));
186+
} else {
187+
const msg = 'Failed to fetch module file ' + rs.status + ': ' + fullUrl;
188+
return Promise.reject(new Error(msg));
192189
}
190+
});
191+
}
192+
193+
/**
194+
* @param {string} url
195+
* @param {boolean} jsx
196+
*/
197+
function tryFetchModuleSrcExtOrNot(url, jsx) {
198+
// typescript does not allow specifying extension in the import, but react
199+
// files may have .tsx extension rather than .ts, so have to check both
200+
const urlOptions = [];
201+
const explicitExtension = EXPLICIT_EXTENSIONS.find(ext => url.endsWith('.' + ext));
202+
if (explicitExtension) {
203+
const whenModule = tryFetchModuleSrcWithExt(url);
204+
if (explicitExtension !== "js") {
205+
// when you import .ts files, compiler normally does not let you specify ".ts" explicitly
206+
// you can only use ".js" extension or no extension at all to refer to that .ts file
207+
// since typescript allows referring to .ts files by .js extension - so should we
208+
return whenModule.catch(async jsExtError => {
209+
try {
210+
return await tryFetchModuleSrcWithExt(url.replace(/\.js$/, "") + ".ts")
211+
} catch {
212+
throw jsExtError;
213+
}
214+
});
215+
} else {
216+
return whenModule;
193217
}
194-
return oneSuccess(
195-
urlOptions.map(fullUrl => fetch(fullUrl)
196-
.then(rs => {
197-
if (rs.status === 200) {
198-
return rs.text().then(tsCode => ({fullUrl, tsCode}));
199-
} else {
200-
const msg = 'Failed to fetch module file ' + rs.status + ': ' + fullUrl;
201-
return Promise.reject(new Error(msg));
202-
}
203-
}))
204-
);
218+
}
219+
urlOptions.push(url + '.ts');
220+
if (jsx) {
221+
urlOptions.push(url + '.tsx');
222+
}
223+
return oneSuccess(
224+
urlOptions.map(tryFetchModuleSrcWithExt)
225+
).catch(async tsExtError => {
226+
// if nor .ts, nor .tsx extension works - try the .js
227+
// the lib would be happier if .js file imports always included
228+
// the .js extension as is the requirement in es6 imports, but
229+
// IDEA does not include extensions in imports by default, so it's still a use
230+
// case - let's make it work when we can: better slower than not working at all
231+
try {
232+
return await tryFetchModuleSrcWithExt(url + ".js")
233+
} catch {
234+
throw tsExtError;
235+
}
236+
});
237+
}
238+
239+
const WorkerManager = ({compilerOptions}) => {
240+
const fetchModuleSrc = (url) => {
241+
return tryFetchModuleSrcExtOrNot(url, compilerOptions.jsx);
205242
};
206243

207244
const parseInWorker = async ({url, fullUrl, tsCode}) => {
@@ -210,7 +247,7 @@ const WorkerManager = ({compilerOptions}) => {
210247
);
211248
// only available on https pages, probably should just use some simple inline checksum
212249
// function, like crc, but bigger than 32 bytes to make sure there won't be collisions
213-
const checksum = !crypto.subtle ? null :
250+
const checksum = !crypto.subtle ? null :
214251
await crypto.subtle.digest(
215252
'SHA-256', sourceCodeBytes
216253
).then(bufferToHex);

0 commit comments

Comments
 (0)