|
9 | 9 | SafeMap, |
10 | 10 | SafeSet, |
11 | 11 | StringPrototypeCharCodeAt, |
12 | | - StringPrototypeIncludes, |
| 12 | + StringPrototypeSplit, |
13 | 13 | StringPrototypeSlice, |
14 | 14 | StringPrototypeStartsWith, |
15 | 15 | } = primordials; |
@@ -145,52 +145,62 @@ function addBuiltinLibsToObject(object, dummyModuleName) { |
145 | 145 | const { builtinModules } = Module; |
146 | 146 |
|
147 | 147 | // To require built-in modules in user-land and ignore modules whose |
148 | | - // `canBeRequiredByUsers` is false. So we create a dummy module object and not |
149 | | - // use `require()` directly. |
| 148 | + // `canBeRequiredByUsers` is false. So we create a dummy module object and |
| 149 | + // not use `require()` directly. |
150 | 150 | const dummyModule = new Module(dummyModuleName); |
151 | 151 |
|
152 | | - ArrayPrototypeForEach(builtinModules, (name) => { |
153 | | - // Neither add underscored modules, nor ones that contain slashes (e.g., |
154 | | - // 'fs/promises') or ones that are already defined. |
155 | | - if (StringPrototypeStartsWith(name, '_') || |
156 | | - StringPrototypeIncludes(name, '/') || |
157 | | - ObjectPrototypeHasOwnProperty(object, name)) { |
158 | | - return; |
159 | | - } |
160 | | - // Goals of this mechanism are: |
161 | | - // - Lazy loading of built-in modules |
162 | | - // - Having all built-in modules available as non-enumerable properties |
163 | | - // - Allowing the user to re-assign these variables as if there were no |
164 | | - // pre-existing globals with the same name. |
165 | | - |
166 | | - const setReal = (val) => { |
167 | | - // Deleting the property before re-assigning it disables the |
168 | | - // getter/setter mechanism. |
169 | | - delete object[name]; |
170 | | - object[name] = val; |
171 | | - }; |
| 152 | + // Goals of this mechanism are: |
| 153 | + // - Lazy loading of built-in modules or submodules |
| 154 | + // - Having all built-in modules or submodules available as |
| 155 | + // non-enumerable properties |
| 156 | + // - Allowing the user to re-assign these variables as if there were no |
| 157 | + // pre-existing globals with the same name. |
| 158 | + |
| 159 | + function attachModulesWrapper(object, parent, modules) { |
| 160 | + ArrayPrototypeForEach(modules, (mod) => { |
| 161 | + const name = parent ? StringPrototypeSplit(mod, '/')[1] : mod; |
| 162 | + |
| 163 | + // Neither add underscored modules/submodules or ones that |
| 164 | + // are already defined. |
| 165 | + if (StringPrototypeStartsWith(name, '_') || |
| 166 | + ObjectPrototypeHasOwnProperty(object, name)) { |
| 167 | + return; |
| 168 | + } |
172 | 169 |
|
173 | | - ObjectDefineProperty(object, name, { |
174 | | - get: () => { |
175 | | - const lib = dummyModule.require(name); |
176 | | - |
177 | | - // Disable the current getter/setter and set up a new |
178 | | - // non-enumerable property. |
179 | | - delete object[name]; |
180 | | - ObjectDefineProperty(object, name, { |
181 | | - get: () => lib, |
182 | | - set: setReal, |
183 | | - configurable: true, |
184 | | - enumerable: false |
185 | | - }); |
186 | | - |
187 | | - return lib; |
188 | | - }, |
189 | | - set: setReal, |
190 | | - configurable: true, |
191 | | - enumerable: false |
| 170 | + ObjectDefineProperty(object, name, { |
| 171 | + get() { |
| 172 | + const lib = dummyModule.require(mod); |
| 173 | + |
| 174 | + const submodules = builtinModules |
| 175 | + .filter((module) => module.startsWith(`${mod}/`)); |
| 176 | + if (submodules.length > 0) |
| 177 | + attachModulesWrapper(lib, mod, submodules); |
| 178 | + |
| 179 | + // Disable the current getter/setter and set up a new |
| 180 | + // non-enumerable property. |
| 181 | + delete object[name]; |
| 182 | + ObjectDefineProperty(object, name, { |
| 183 | + value: lib, |
| 184 | + writable: true, |
| 185 | + configurable: true, |
| 186 | + enumerable: false, |
| 187 | + }); |
| 188 | + return lib; |
| 189 | + }, |
| 190 | + |
| 191 | + set(val) { |
| 192 | + // Deleting the property before re-assigning it disables the |
| 193 | + // getter/setter mechanism. |
| 194 | + delete object[name]; |
| 195 | + object[name] = val; |
| 196 | + }, |
| 197 | + configurable: true, |
| 198 | + enumerable: false, |
| 199 | + }); |
192 | 200 | }); |
193 | | - }); |
| 201 | + } |
| 202 | + |
| 203 | + attachModulesWrapper(object, '', builtinModules); |
194 | 204 | } |
195 | 205 |
|
196 | 206 | function normalizeReferrerURL(referrer) { |
|
0 commit comments