Skip to content

Commit 4647567

Browse files
authored
Simplify _scriptName / scriptDirectory handling. NFC (#24023)
- Avoid defining `_scriptName` outside the wrapper function in `EXPORT_ES6` mode and for Node.js CommonJS builds. - Simplify `scriptDirectory` resolution to `new URL('.', _scriptName).href` on the web. - Add tests to verify that `scriptDirectory` is an absolute path across different build configurations.
1 parent 0acd21a commit 4647567

File tree

93 files changed

+162
-144
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+162
-144
lines changed

src/closure-externs/modularize-externs.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
// Due to the way MODULARIZE works, Closure is run on generated code that does not define _scriptName,
2-
// but only after MODULARIZE has finished, _scriptName is injected to the generated code.
3-
// Therefore it cannot be minified.
1+
// In MODULARIZE mode the JS code may be executed later, after `document.currentScript` is gone, so we store
2+
// it to `_scriptName` outside the wrapper function. Therefore, it cannot be minified.
3+
// In EXPORT_ES6 mode we use `import.meta.url` and for Node.js CommonJS builds we use `__filename`.
4+
45
/**
56
* @suppress {duplicate, undefinedVars}
67
*/

src/shell.js

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,32 @@ var quit_ = (status, toThrow) => {
139139
throw toThrow;
140140
};
141141

142-
#if SHARED_MEMORY && !MODULARIZE
142+
#if EXPORT_ES6
143+
var _scriptName = import.meta.url;
144+
#else
145+
#if ENVIRONMENT_MAY_BE_WEB
146+
#if !MODULARIZE
143147
// In MODULARIZE mode _scriptName needs to be captured already at the very top of the page immediately when the page is parsed, so it is generated there
144148
// before the page load. In non-MODULARIZE modes generate it here.
145-
var _scriptName = (typeof document != 'undefined') ? document.currentScript?.src : undefined;
149+
var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
150+
#endif // !MODULARIZE
151+
#elif ENVIRONMENT_MAY_BE_NODE || ENVIRONMENT_MAY_BE_WORKER
152+
var _scriptName;
153+
#endif // ENVIRONMENT_MAY_BE_WEB
146154

147155
#if ENVIRONMENT_MAY_BE_NODE
148-
if (ENVIRONMENT_IS_NODE) {
149-
#if EXPORT_ES6
150-
_scriptName = typeof __filename != 'undefined' ? __filename : import.meta.url
151-
#else
156+
if (typeof __filename != 'undefined') { // Node
152157
_scriptName = __filename;
153-
#endif
154158
} else
155159
#endif // ENVIRONMENT_MAY_BE_NODE
160+
#if ENVIRONMENT_MAY_BE_WORKER
156161
if (ENVIRONMENT_IS_WORKER) {
157162
_scriptName = self.location.href;
158163
}
159-
#endif // SHARED_MEMORY && !MODULARIZE
164+
#elif ENVIRONMENT_MAY_BE_NODE
165+
/*no-op*/{}
166+
#endif // ENVIRONMENT_MAY_BE_WORKER
167+
#endif // EXPORT_ES6
160168

161169
// `/` should be present at the end if `scriptDirectory` is not empty
162170
var scriptDirectory = '';
@@ -197,11 +205,8 @@ if (ENVIRONMENT_IS_NODE) {
197205
var nodePath = require('path');
198206

199207
#if EXPORT_ES6
200-
// EXPORT_ES6 + ENVIRONMENT_IS_NODE always requires use of import.meta.url,
201-
// since there's no way getting the current absolute path of the module when
202-
// support for that is not available.
203-
if (!import.meta.url.startsWith('data:')) {
204-
scriptDirectory = nodePath.dirname(require('url').fileURLToPath(import.meta.url)) + '/';
208+
if (_scriptName.startsWith('file:')) {
209+
scriptDirectory = nodePath.dirname(require('url').fileURLToPath(_scriptName)) + '/';
205210
}
206211
#else
207212
scriptDirectory = __dirname + '/';
@@ -335,28 +340,11 @@ if (ENVIRONMENT_IS_SHELL) {
335340
// ENVIRONMENT_IS_NODE.
336341
#if ENVIRONMENT_MAY_BE_WEB || ENVIRONMENT_MAY_BE_WORKER
337342
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
338-
if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
339-
scriptDirectory = self.location.href;
340-
} else if (typeof document != 'undefined' && document.currentScript) { // web
341-
scriptDirectory = document.currentScript.src;
342-
}
343-
#if MODULARIZE
344-
// When MODULARIZE, this JS may be executed later, after document.currentScript
345-
// is gone, so we saved it, and we use it here instead of any other info.
346-
if (_scriptName) {
347-
scriptDirectory = _scriptName;
348-
}
349-
#endif
350-
// blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
351-
// otherwise, slice off the final part of the url to find the script directory.
352-
// if scriptDirectory does not contain a slash, lastIndexOf will return -1,
353-
// and scriptDirectory will correctly be replaced with an empty string.
354-
// If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
355-
// they are removed because they could contain a slash.
356-
if (scriptDirectory.startsWith('blob:')) {
357-
scriptDirectory = '';
358-
} else {
359-
scriptDirectory = scriptDirectory.slice(0, scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/')+1);
343+
try {
344+
scriptDirectory = new URL('.', _scriptName).href; // includes trailing slash
345+
} catch {
346+
// Must be a `blob:` or `data:` URL (e.g. `blob:http://site.com/etc/etc`), we cannot
347+
// infer anything from them.
360348
}
361349

362350
#if ENVIRONMENT && ASSERTIONS

src/shell_minimal.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ var ENVIRONMENT_IS_PTHREAD = ENVIRONMENT_IS_WORKER && self.name?.startsWith('em-
134134
#if !MODULARIZE
135135
// In MODULARIZE mode _scriptName needs to be captured already at the very top of the page immediately when the page is parsed, so it is generated there
136136
// before the page load. In non-MODULARIZE modes generate it here.
137-
var _scriptName = (typeof document != 'undefined') ? document.currentScript?.src : undefined;
137+
var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
138138
#endif
139139

140140
#if ENVIRONMENT_MAY_BE_NODE
@@ -145,9 +145,11 @@ if (ENVIRONMENT_IS_NODE) {
145145
// Under node we set `workerData` to `em-pthread` to signal that the worker
146146
// is hosting a pthread.
147147
ENVIRONMENT_IS_PTHREAD = ENVIRONMENT_IS_WORKER && worker_threads['workerData'] == 'em-pthread'
148+
#if !EXPORT_ES6
148149
_scriptName = __filename;
149-
} else
150150
#endif
151+
} else
152+
#endif // ENVIRONMENT_MAY_BE_NODE
151153
if (ENVIRONMENT_IS_WORKER) {
152154
_scriptName = self.location.href;
153155
}

src/wasm_worker.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ if (ENVIRONMENT_IS_NODE) {
3434
Object.assign(global, {
3535
self: global,
3636
require,
37+
#if !EXPORT_ES6
38+
// `vm.runInThisContext` global scope lacks `__filename` and `__dirname`
3739
__filename,
3840
__dirname,
41+
#endif
3942
Worker: nodeWorkerThreads.Worker,
4043
importScripts: (f) => vm.runInThisContext(fs.readFileSync(f, 'utf8'), {filename: f}),
4144
postMessage: (msg) => parentPort.postMessage(msg),
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3996
1+
3934
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8237
1+
8208
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
19928
1+
19920
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8226
1+
8196
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
19906
1+
19898
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9227
1+
9203

0 commit comments

Comments
 (0)