GeezerVison is showing github.com — console: move the inspector console wrapping in a separate file · nodejs/node@57323e8
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/inspector.js +3-2Lines changed: 3 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -12,7 +12,6 @@ const { | 12 | 12 | const { validateString } = require('internal/validators'); | 13 | 13 | const util = require('util'); | 14 | 14 | const { Connection, open, url } = internalBinding('inspector'); | 15 | | -const { originalConsole } = require('internal/process/per_thread'); | 16 | 15 |
| 17 | 16 | if (!Connection) | 18 | 17 | throw new ERR_INSPECTOR_NOT_AVAILABLE(); | @@ -103,6 +102,8 @@ module.exports = { | 103 | 102 | open: (port, host, wait) => open(port, host, !!wait), | 104 | 103 | close: process._debugEnd, | 105 | 104 | url: url, | 106 | | - console: originalConsole, | | 105 | + // This is dynamically added during bootstrap, | | 106 | + // where the console from the VM is still available | | 107 | + console: require('internal/console/inspector').consoleFromVM, | 107 | 108 | Session | 108 | 109 | }; |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/bootstrap/node.js +15-53Lines changed: 15 additions & 53 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 121 | 121 |
| 122 | 122 | const browserGlobals = !process._noBrowserGlobals; | 123 | 123 | if (browserGlobals) { | 124 | | - // We are setting this here to forward it to the inspector later | 125 | | - perThreadSetup.originalConsole = global.console; | 126 | 124 | setupGlobalTimeouts(); | 127 | 125 | setupGlobalConsole(); | 128 | 126 | setupGlobalURL(); | | 486 | 484 | } | 487 | 485 |
| 488 | 486 | function setupGlobalConsole() { | 489 | | - const originalConsole = global.console; | 490 | | - // Setup Node.js global.console. | 491 | | - const wrappedConsole = NativeModule.require('console'); | | 487 | + const consoleFromVM = global.console; | | 488 | + const consoleFromNode = | | 489 | + NativeModule.require('internal/console/global'); | | 490 | + // Override global console from the one provided by the VM | | 491 | + // to the one implemented by Node.js | 492 | 492 | Object.defineProperty(global, 'console', { | 493 | 493 | configurable: true, | 494 | 494 | enumerable: false, | 495 | | - value: wrappedConsole, | | 495 | + value: consoleFromNode, | 496 | 496 | writable: true | 497 | 497 | }); | 498 | | - setupInspector(originalConsole, wrappedConsole); | | 498 | + // TODO(joyeecheung): can we skip this if inspector is not active? | | 499 | + if (process.config.variables.v8_enable_inspector) { | | 500 | + const inspector = | | 501 | + NativeModule.require('internal/console/inspector'); | | 502 | + inspector.addInspectorApis(consoleFromNode, consoleFromVM); | | 503 | + // This will be exposed by `require('inspector').console` later. | | 504 | + inspector.consoleFromVM = consoleFromVM; | | 505 | + } | 499 | 506 | } | 500 | 507 |
| 501 | 508 | function setupGlobalURL() { | | 570 | 577 | registerDOMException(DOMException); | 571 | 578 | } | 572 | 579 |
| 573 | | - function setupInspector(originalConsole, wrappedConsole) { | 574 | | - if (!process.config.variables.v8_enable_inspector) { | 575 | | - return; | 576 | | - } | 577 | | - const CJSModule = NativeModule.require('internal/modules/cjs/loader'); | 578 | | - const { addCommandLineAPI, consoleCall } = process.binding('inspector'); | 579 | | - // Setup inspector command line API. | 580 | | - const { makeRequireFunction } = | 581 | | - NativeModule.require('internal/modules/cjs/helpers'); | 582 | | - const path = NativeModule.require('path'); | 583 | | - const cwd = tryGetCwd(path); | 584 | | - | 585 | | - const consoleAPIModule = new CJSModule('<inspector console>'); | 586 | | - consoleAPIModule.paths = | 587 | | - CJSModule._nodeModulePaths(cwd).concat(CJSModule.globalPaths); | 588 | | - addCommandLineAPI('require', makeRequireFunction(consoleAPIModule)); | 589 | | - const config = {}; | 590 | | - for (const key of Object.keys(wrappedConsole)) { | 591 | | - if (!originalConsole.hasOwnProperty(key)) | 592 | | - continue; | 593 | | - // If global console has the same method as inspector console, | 594 | | - // then wrap these two methods into one. Native wrapper will preserve | 595 | | - // the original stack. | 596 | | - wrappedConsole[key] = consoleCall.bind(wrappedConsole, | 597 | | - originalConsole[key], | 598 | | - wrappedConsole[key], | 599 | | - config); | 600 | | - } | 601 | | - for (const key of Object.keys(originalConsole)) { | 602 | | - if (wrappedConsole.hasOwnProperty(key)) | 603 | | - continue; | 604 | | - wrappedConsole[key] = originalConsole[key]; | 605 | | - } | 606 | | - } | 607 | | - | 608 | 580 | function noop() {} | 609 | 581 |
| 610 | 582 | function setupProcessFatal() { | | 683 | 655 | } | 684 | 656 | } | 685 | 657 |
| 686 | | - function tryGetCwd(path) { | 687 | | - try { | 688 | | - return process.cwd(); | 689 | | - } catch { | 690 | | - // getcwd(3) can fail if the current working directory has been deleted. | 691 | | - // Fall back to the directory name of the (absolute) executable path. | 692 | | - // It's not really correct but what are the alternatives? | 693 | | - return path.dirname(process.execPath); | 694 | | - } | 695 | | - } | 696 | | - | 697 | 658 | function wrapForBreakOnFirstLine(source) { | 698 | 659 | if (!process._breakFirstLine) | 699 | 660 | return source; | | 704 | 665 | function evalScript(name, body) { | 705 | 666 | const CJSModule = NativeModule.require('internal/modules/cjs/loader'); | 706 | 667 | const path = NativeModule.require('path'); | | 668 | + const { tryGetCwd } = NativeModule.require('internal/util'); | 707 | 669 | const cwd = tryGetCwd(path); | 708 | 670 |
| 709 | 671 | const module = new CJSModule(name); | |
Collapse file Copy file name to clipboard +53Lines changed: 53 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const path = require('path'); | | 4 | +const CJSModule = require('internal/modules/cjs/loader'); | | 5 | +const { makeRequireFunction } = require('internal/modules/cjs/helpers'); | | 6 | +const { tryGetCwd } = require('internal/util'); | | 7 | +const { addCommandLineAPI, consoleCall } = process.binding('inspector'); | | 8 | + | | 9 | +// Wrap a console implemented by Node.js with features from the VM inspector | | 10 | +function addInspectorApis(consoleFromNode, consoleFromVM) { | | 11 | + // Setup inspector command line API. | | 12 | + const cwd = tryGetCwd(path); | | 13 | + const consoleAPIModule = new CJSModule('<inspector console>'); | | 14 | + consoleAPIModule.paths = | | 15 | + CJSModule._nodeModulePaths(cwd).concat(CJSModule.globalPaths); | | 16 | + addCommandLineAPI('require', makeRequireFunction(consoleAPIModule)); | | 17 | + const config = {}; | | 18 | + | | 19 | + // If global console has the same method as inspector console, | | 20 | + // then wrap these two methods into one. Native wrapper will preserve | | 21 | + // the original stack. | | 22 | + for (const key of Object.keys(consoleFromNode)) { | | 23 | + if (!consoleFromVM.hasOwnProperty(key)) | | 24 | + continue; | | 25 | + consoleFromNode[key] = consoleCall.bind(consoleFromNode, | | 26 | + consoleFromVM[key], | | 27 | + consoleFromNode[key], | | 28 | + config); | | 29 | + } | | 30 | + | | 31 | + // Add additional console APIs from the inspector | | 32 | + for (const key of Object.keys(consoleFromVM)) { | | 33 | + if (consoleFromNode.hasOwnProperty(key)) | | 34 | + continue; | | 35 | + consoleFromNode[key] = consoleFromVM[key]; | | 36 | + } | | 37 | +} | | 38 | + | | 39 | +module.exports = { | | 40 | + addInspectorApis | | 41 | +}; | | 42 | + | | 43 | +// Stores the console from VM, should be set during bootstrap. | | 44 | +let consoleFromVM; | | 45 | + | | 46 | +Object.defineProperty(module.exports, 'consoleFromVM', { | | 47 | + get() { | | 48 | + return consoleFromVM; | | 49 | + }, | | 50 | + set(val) { | | 51 | + consoleFromVM = val; | | 52 | + } | | 53 | +}); |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/util.js +12Lines changed: 12 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -387,6 +387,17 @@ function once(callback) { | 387 | 387 | }; | 388 | 388 | } | 389 | 389 |
| | 390 | +function tryGetCwd(path) { | | 391 | + try { | | 392 | + return process.cwd(); | | 393 | + } catch { | | 394 | + // getcwd(3) can fail if the current working directory has been deleted. | | 395 | + // Fall back to the directory name of the (absolute) executable path. | | 396 | + // It's not really correct but what are the alternatives? | | 397 | + return path.dirname(process.execPath); | | 398 | + } | | 399 | +} | | 400 | + | 390 | 401 | module.exports = { | 391 | 402 | assertCrypto, | 392 | 403 | cachedResult, | @@ -406,6 +417,7 @@ module.exports = { | 406 | 417 | once, | 407 | 418 | promisify, | 408 | 419 | spliceOne, | | 420 | + tryGetCwd, | 409 | 421 | removeColors, | 410 | 422 |
| 411 | 423 | // Symbol used to customize promisify conversion | |
Collapse file Copy file name to clipboardExpand all lines: node.gyp +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 98 | 98 | 'lib/internal/cluster/worker.js', | 99 | 99 | 'lib/internal/console/constructor.js', | 100 | 100 | 'lib/internal/console/global.js', | | 101 | + 'lib/internal/console/inspector.js', | 101 | 102 | 'lib/internal/crypto/certificate.js', | 102 | 103 | 'lib/internal/crypto/cipher.js', | 103 | 104 | 'lib/internal/crypto/diffiehellman.js', | |
|