diff --git a/lib/console.js b/lib/console.js
deleted file mode 100644
index f0b9a74cfc7df8..00000000000000
--- a/lib/console.js
+++ /dev/null
@@ -1,574 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'use strict';
-
-const { trace } = internalBinding('trace_events');
-const {
-  isStackOverflowError,
-  codes: {
-    ERR_CONSOLE_WRITABLE_STREAM,
-    ERR_INVALID_ARG_TYPE,
-    ERR_INVALID_ARG_VALUE,
-  },
-} = require('internal/errors');
-const { previewEntries } = internalBinding('util');
-const { Buffer: { isBuffer } } = require('buffer');
-const util = require('util');
-const {
-  isTypedArray, isSet, isMap, isSetIterator, isMapIterator,
-} = util.types;
-const kCounts = Symbol('counts');
-
-const kTraceConsoleCategory = 'node,node.console';
-const kTraceCount = 'C'.charCodeAt(0);
-const kTraceBegin = 'b'.charCodeAt(0);
-const kTraceEnd = 'e'.charCodeAt(0);
-const kTraceInstant = 'n'.charCodeAt(0);
-
-const {
-  keys: ObjectKeys,
-  values: ObjectValues,
-} = Object;
-const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
-
-const {
-  isArray: ArrayIsArray,
-  from: ArrayFrom,
-} = Array;
-
-// Lazy loaded for startup performance.
-let cliTable;
-
-// Track amount of indentation required via `console.group()`.
-const kGroupIndent = Symbol('kGroupIndent');
-const kFormatForStderr = Symbol('kFormatForStderr');
-const kFormatForStdout = Symbol('kFormatForStdout');
-const kGetInspectOptions = Symbol('kGetInspectOptions');
-const kColorMode = Symbol('kColorMode');
-const kIsConsole = Symbol('kIsConsole');
-const kWriteToConsole = Symbol('kWriteToConsole');
-const kBindProperties = Symbol('kBindProperties');
-const kBindStreamsEager = Symbol('kBindStreamsEager');
-const kBindStreamsLazy = Symbol('kBindStreamsLazy');
-const kUseStdout = Symbol('kUseStdout');
-const kUseStderr = Symbol('kUseStderr');
-
-// This constructor is not used to construct the global console.
-// It's exported for backwards compatibility.
-function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
-  // We have to test new.target here to see if this function is called
-  // with new, because we need to define a custom instanceof to accommodate
-  // the global console.
-  if (!new.target) {
-    return new Console(...arguments);
-  }
-
-  if (!options || typeof options.write === 'function') {
-    options = {
-      stdout: options,
-      stderr: arguments[1],
-      ignoreErrors: arguments[2]
-    };
-  }
-
-  const {
-    stdout,
-    stderr = stdout,
-    ignoreErrors = true,
-    colorMode = 'auto'
-  } = options;
-
-  if (!stdout || typeof stdout.write !== 'function') {
-    throw new ERR_CONSOLE_WRITABLE_STREAM('stdout');
-  }
-  if (!stderr || typeof stderr.write !== 'function') {
-    throw new ERR_CONSOLE_WRITABLE_STREAM('stderr');
-  }
-
-  if (typeof colorMode !== 'boolean' && colorMode !== 'auto')
-    throw new ERR_INVALID_ARG_VALUE('colorMode', colorMode);
-
-  // Bind the prototype functions to this Console instance
-  var keys = Object.keys(Console.prototype);
-  for (var v = 0; v < keys.length; v++) {
-    var k = keys[v];
-    // We have to bind the methods grabbed from the instance instead of from
-    // the prototype so that users extending the Console can override them
-    // from the prototype chain of the subclass.
-    this[k] = this[k].bind(this);
-  }
-
-  this[kBindStreamsEager](stdout, stderr);
-  this[kBindProperties](ignoreErrors, colorMode);
-}
-
-const consolePropAttributes = {
-  writable: true,
-  enumerable: false,
-  configurable: true
-};
-
-// Fixup global.console instanceof global.console.Console
-Object.defineProperty(Console, Symbol.hasInstance, {
-  value(instance) {
-    return instance[kIsConsole];
-  }
-});
-
-// Eager version for the Console constructor
-Console.prototype[kBindStreamsEager] = function(stdout, stderr) {
-  Object.defineProperties(this, {
-    '_stdout': { ...consolePropAttributes, value: stdout },
-    '_stderr': { ...consolePropAttributes, value: stderr }
-  });
-};
-
-// Lazily load the stdout and stderr from an object so we don't
-// create the stdio streams when they are not even accessed
-Console.prototype[kBindStreamsLazy] = function(object) {
-  let stdout;
-  let stderr;
-  Object.defineProperties(this, {
-    '_stdout': {
-      enumerable: false,
-      configurable: true,
-      get() {
-        if (!stdout) stdout = object.stdout;
-        return stdout;
-      },
-      set(value) { stdout = value; }
-    },
-    '_stderr': {
-      enumerable: false,
-      configurable: true,
-      get() {
-        if (!stderr) { stderr = object.stderr; }
-        return stderr;
-      },
-      set(value) { stderr = value; }
-    }
-  });
-};
-
-Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) {
-  Object.defineProperties(this, {
-    '_stdoutErrorHandler': {
-      ...consolePropAttributes,
-      value: createWriteErrorHandler(this, kUseStdout)
-    },
-    '_stderrErrorHandler': {
-      ...consolePropAttributes,
-      value: createWriteErrorHandler(this, kUseStderr)
-    },
-    '_ignoreErrors': {
-      ...consolePropAttributes,
-      value: Boolean(ignoreErrors)
-    },
-    '_times': { ...consolePropAttributes, value: new Map() }
-  });
-
-  // TODO(joyeecheung): use consolePropAttributes for these
-  // Corresponds to https://console.spec.whatwg.org/#count-map
-  this[kCounts] = new Map();
-  this[kColorMode] = colorMode;
-  this[kIsConsole] = true;
-  this[kGroupIndent] = '';
-};
-
-// Make a function that can serve as the callback passed to `stream.write()`.
-function createWriteErrorHandler(instance, streamSymbol) {
-  return (err) => {
-    // This conditional evaluates to true if and only if there was an error
-    // that was not already emitted (which happens when the _write callback
-    // is invoked asynchronously).
-    const stream = streamSymbol === kUseStdout ?
-      instance._stdout : instance._stderr;
-    if (err !== null && !stream._writableState.errorEmitted) {
-      // If there was an error, it will be emitted on `stream` as
-      // an `error` event. Adding a `once` listener will keep that error
-      // from becoming an uncaught exception, but since the handler is
-      // removed after the event, non-console.* writes won't be affected.
-      // we are only adding noop if there is no one else listening for 'error'
-      if (stream.listenerCount('error') === 0) {
-        stream.on('error', noop);
-      }
-    }
-  };
-}
-
-Console.prototype[kWriteToConsole] = function(streamSymbol, string) {
-  const ignoreErrors = this._ignoreErrors;
-  const groupIndent = this[kGroupIndent];
-
-  const useStdout = streamSymbol === kUseStdout;
-  const stream = useStdout ? this._stdout : this._stderr;
-  const errorHandler = useStdout ?
-    this._stdoutErrorHandler : this._stderrErrorHandler;
-
-  if (groupIndent.length !== 0) {
-    if (string.indexOf('\n') !== -1) {
-      string = string.replace(/\n/g, `\n${groupIndent}`);
-    }
-    string = groupIndent + string;
-  }
-  string += '\n';
-
-  if (ignoreErrors === false) return stream.write(string);
-
-  // There may be an error occurring synchronously (e.g. for files or TTYs
-  // on POSIX systems) or asynchronously (e.g. pipes on POSIX systems), so
-  // handle both situations.
-  try {
-    // Add and later remove a noop error handler to catch synchronous errors.
-    stream.once('error', noop);
-
-    stream.write(string, errorHandler);
-  } catch (e) {
-    // Console is a debugging utility, so it swallowing errors is not desirable
-    // even in edge cases such as low stack space.
-    if (isStackOverflowError(e))
-      throw e;
-    // Sorry, there's no proper way to pass along the error here.
-  } finally {
-    stream.removeListener('error', noop);
-  }
-};
-
-const kColorInspectOptions = { colors: true };
-const kNoColorInspectOptions = {};
-Console.prototype[kGetInspectOptions] = function(stream) {
-  let color = this[kColorMode];
-  if (color === 'auto') {
-    color = stream.isTTY && (
-      typeof stream.getColorDepth === 'function' ?
-        stream.getColorDepth() > 2 : true);
-  }
-
-  return color ? kColorInspectOptions : kNoColorInspectOptions;
-};
-
-Console.prototype[kFormatForStdout] = function(args) {
-  const opts = this[kGetInspectOptions](this._stdout);
-  return util.formatWithOptions(opts, ...args);
-};
-
-Console.prototype[kFormatForStderr] = function(args) {
-  const opts = this[kGetInspectOptions](this._stderr);
-  return util.formatWithOptions(opts, ...args);
-};
-
-Console.prototype.log = function log(...args) {
-  this[kWriteToConsole](kUseStdout, this[kFormatForStdout](args));
-};
-
-Console.prototype.debug = Console.prototype.log;
-Console.prototype.info = Console.prototype.log;
-Console.prototype.dirxml = Console.prototype.log;
-
-Console.prototype.warn = function warn(...args) {
-  this[kWriteToConsole](kUseStderr, this[kFormatForStderr](args));
-};
-
-Console.prototype.error = Console.prototype.warn;
-
-Console.prototype.dir = function dir(object, options) {
-  options = {
-    customInspect: false,
-    ...this[kGetInspectOptions](this._stdout),
-    ...options
-  };
-  this[kWriteToConsole](kUseStdout, util.inspect(object, options));
-};
-
-Console.prototype.time = function time(label = 'default') {
-  // Coerces everything other than Symbol to a string
-  label = `${label}`;
-  if (this._times.has(label)) {
-    process.emitWarning(`Label '${label}' already exists for console.time()`);
-    return;
-  }
-  trace(kTraceBegin, kTraceConsoleCategory, `time::${label}`, 0);
-  this._times.set(label, process.hrtime());
-};
-
-Console.prototype.timeEnd = function timeEnd(label = 'default') {
-  // Coerces everything other than Symbol to a string
-  label = `${label}`;
-  const hasWarned = timeLogImpl(this, 'timeEnd', label);
-  trace(kTraceEnd, kTraceConsoleCategory, `time::${label}`, 0);
-  if (!hasWarned) {
-    this._times.delete(label);
-  }
-};
-
-Console.prototype.timeLog = function timeLog(label = 'default', ...data) {
-  // Coerces everything other than Symbol to a string
-  label = `${label}`;
-  timeLogImpl(this, 'timeLog', label, data);
-  trace(kTraceInstant, kTraceConsoleCategory, `time::${label}`, 0);
-};
-
-// Returns true if label was not found
-function timeLogImpl(self, name, label, data) {
-  const time = self._times.get(label);
-  if (!time) {
-    process.emitWarning(`No such label '${label}' for console.${name}()`);
-    return true;
-  }
-  const duration = process.hrtime(time);
-  const ms = duration[0] * 1000 + duration[1] / 1e6;
-  if (data === undefined) {
-    self.log('%s: %sms', label, ms.toFixed(3));
-  } else {
-    self.log('%s: %sms', label, ms.toFixed(3), ...data);
-  }
-  return false;
-}
-
-Console.prototype.trace = function trace(...args) {
-  const err = {
-    name: 'Trace',
-    message: this[kFormatForStderr](args)
-  };
-  Error.captureStackTrace(err, trace);
-  this.error(err.stack);
-};
-
-Console.prototype.assert = function assert(expression, ...args) {
-  if (!expression) {
-    args[0] = `Assertion failed${args.length === 0 ? '' : `: ${args[0]}`}`;
-    this.warn(...args);  // the arguments will be formatted in warn() again
-  }
-};
-
-// Defined by: https://console.spec.whatwg.org/#clear
-Console.prototype.clear = function clear() {
-  // It only makes sense to clear if _stdout is a TTY.
-  // Otherwise, do nothing.
-  if (this._stdout.isTTY) {
-    // The require is here intentionally to avoid readline being
-    // required too early when console is first loaded.
-    const { cursorTo, clearScreenDown } = require('readline');
-    cursorTo(this._stdout, 0, 0);
-    clearScreenDown(this._stdout);
-  }
-};
-
-// Defined by: https://console.spec.whatwg.org/#count
-Console.prototype.count = function count(label = 'default') {
-  // Ensures that label is a string, and only things that can be
-  // coerced to strings. e.g. Symbol is not allowed
-  label = `${label}`;
-  const counts = this[kCounts];
-  let count = counts.get(label);
-  if (count === undefined)
-    count = 1;
-  else
-    count++;
-  counts.set(label, count);
-  trace(kTraceCount, kTraceConsoleCategory, `count::${label}`, 0, count);
-  this.log(`${label}: ${count}`);
-};
-
-// Defined by: https://console.spec.whatwg.org/#countreset
-Console.prototype.countReset = function countReset(label = 'default') {
-  const counts = this[kCounts];
-  if (!counts.has(label)) {
-    process.emitWarning(`Count for '${label}' does not exist`);
-    return;
-  }
-  trace(kTraceCount, kTraceConsoleCategory, `count::${label}`, 0, 0);
-  counts.delete(`${label}`);
-};
-
-Console.prototype.group = function group(...data) {
-  if (data.length > 0) {
-    this.log(...data);
-  }
-  this[kGroupIndent] += '  ';
-};
-Console.prototype.groupCollapsed = Console.prototype.group;
-
-Console.prototype.groupEnd = function groupEnd() {
-  this[kGroupIndent] =
-    this[kGroupIndent].slice(0, this[kGroupIndent].length - 2);
-};
-
-const keyKey = 'Key';
-const valuesKey = 'Values';
-const indexKey = '(index)';
-const iterKey = '(iteration index)';
-
-const isArray = (v) => ArrayIsArray(v) || isTypedArray(v) || isBuffer(v);
-
-// https://console.spec.whatwg.org/#table
-Console.prototype.table = function(tabularData, properties) {
-  if (properties !== undefined && !ArrayIsArray(properties))
-    throw new ERR_INVALID_ARG_TYPE('properties', 'Array', properties);
-
-  if (tabularData === null || typeof tabularData !== 'object')
-    return this.log(tabularData);
-
-  if (cliTable === undefined) cliTable = require('internal/cli_table');
-  const final = (k, v) => this.log(cliTable(k, v));
-
-  const inspect = (v) => {
-    const opt = { depth: 0, maxArrayLength: 3 };
-    if (v !== null && typeof v === 'object' &&
-      !isArray(v) && ObjectKeys(v).length > 2)
-      opt.depth = -1;
-    Object.assign(opt, this[kGetInspectOptions](this._stdout));
-    return util.inspect(v, opt);
-  };
-  const getIndexArray = (length) => ArrayFrom({ length }, (_, i) => inspect(i));
-
-  const mapIter = isMapIterator(tabularData);
-  let isKeyValue = false;
-  let i = 0;
-  if (mapIter) {
-    const res = previewEntries(tabularData, true);
-    tabularData = res[0];
-    isKeyValue = res[1];
-  }
-
-  if (isKeyValue || isMap(tabularData)) {
-    const keys = [];
-    const values = [];
-    let length = 0;
-    if (mapIter) {
-      for (; i < tabularData.length / 2; ++i) {
-        keys.push(inspect(tabularData[i * 2]));
-        values.push(inspect(tabularData[i * 2 + 1]));
-        length++;
-      }
-    } else {
-      for (const [k, v] of tabularData) {
-        keys.push(inspect(k));
-        values.push(inspect(v));
-        length++;
-      }
-    }
-    return final([
-      iterKey, keyKey, valuesKey
-    ], [
-      getIndexArray(length),
-      keys,
-      values,
-    ]);
-  }
-
-  const setIter = isSetIterator(tabularData);
-  if (setIter)
-    tabularData = previewEntries(tabularData);
-
-  const setlike = setIter || (mapIter && !isKeyValue) || isSet(tabularData);
-  if (setlike) {
-    const values = [];
-    let length = 0;
-    for (const v of tabularData) {
-      values.push(inspect(v));
-      length++;
-    }
-    return final([setlike ? iterKey : indexKey, valuesKey], [
-      getIndexArray(length),
-      values,
-    ]);
-  }
-
-  const map = {};
-  let hasPrimitives = false;
-  const valuesKeyArray = [];
-  const indexKeyArray = ObjectKeys(tabularData);
-
-  for (; i < indexKeyArray.length; i++) {
-    const item = tabularData[indexKeyArray[i]];
-    const primitive = item === null ||
-        (typeof item !== 'function' && typeof item !== 'object');
-    if (properties === undefined && primitive) {
-      hasPrimitives = true;
-      valuesKeyArray[i] = inspect(item);
-    } else {
-      const keys = properties || ObjectKeys(item);
-      for (const key of keys) {
-        if (map[key] === undefined)
-          map[key] = [];
-        if ((primitive && properties) || !hasOwnProperty(item, key))
-          map[key][i] = '';
-        else
-          map[key][i] = item == null ? item : inspect(item[key]);
-      }
-    }
-  }
-
-  const keys = ObjectKeys(map);
-  const values = ObjectValues(map);
-  if (hasPrimitives) {
-    keys.push(valuesKey);
-    values.push(valuesKeyArray);
-  }
-  keys.unshift(indexKey);
-  values.unshift(indexKeyArray);
-
-  return final(keys, values);
-};
-
-function noop() {}
-
-// See https://console.spec.whatwg.org/#console-namespace
-// > For historical web-compatibility reasons, the namespace object
-// > for console must have as its [[Prototype]] an empty object,
-// > created as if by ObjectCreate(%ObjectPrototype%),
-// > instead of %ObjectPrototype%.
-
-// Since in Node.js, the Console constructor has been exposed through
-// require('console'), we need to keep the Console constructor but
-// we cannot actually use `new Console` to construct the global console.
-// Therefore, the console.Console.prototype is not
-// in the global console prototype chain anymore.
-
-// TODO(joyeecheung):
-// - Move the Console constructor into internal/console.js
-// - Move the global console creation code along with the inspector console
-//   wrapping code in internal/bootstrap/node.js into a separate file.
-// - Make this file a simple re-export of those two files.
-// This is only here for v11.x conflict resolution.
-const globalConsole = Object.create(Console.prototype);
-
-// Since Console is not on the prototype chain of the global console,
-// the symbol properties on Console.prototype have to be looked up from
-// the global console itself. In addition, we need to make the global
-// console a namespace by binding the console methods directly onto
-// the global console with the receiver fixed.
-for (const prop of Reflect.ownKeys(Console.prototype)) {
-  if (prop === 'constructor') { continue; }
-  const desc = Reflect.getOwnPropertyDescriptor(Console.prototype, prop);
-  if (typeof desc.value === 'function') { // fix the receiver
-    desc.value = desc.value.bind(globalConsole);
-  }
-  Reflect.defineProperty(globalConsole, prop, desc);
-}
-
-globalConsole[kBindStreamsLazy](process);
-globalConsole[kBindProperties](true, 'auto');
-
-module.exports = globalConsole;
-module.exports.Console = Console;
diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js
index dcfb5f4a70a826..f0b9a74cfc7df8 100644
--- a/lib/internal/console/constructor.js
+++ b/lib/internal/console/constructor.js
@@ -1,7 +1,25 @@
-'use strict';
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-// The Console constructor is not actually used to construct the global
-// console. It's exported for backwards compatibility.
+'use strict';
 
 const { trace } = internalBinding('trace_events');
 const {
@@ -54,6 +72,8 @@ const kBindStreamsLazy = Symbol('kBindStreamsLazy');
 const kUseStdout = Symbol('kUseStdout');
 const kUseStderr = Symbol('kUseStderr');
 
+// This constructor is not used to construct the global console.
+// It's exported for backwards compatibility.
 function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
   // We have to test new.target here to see if this function is called
   // with new, because we need to define a custom instanceof to accommodate
@@ -271,11 +291,12 @@ Console.prototype.warn = function warn(...args) {
 Console.prototype.error = Console.prototype.warn;
 
 Console.prototype.dir = function dir(object, options) {
-  this[kWriteToConsole](kUseStdout, util.inspect(object, {
+  options = {
     customInspect: false,
     ...this[kGetInspectOptions](this._stdout),
     ...options
-  }));
+  };
+  this[kWriteToConsole](kUseStdout, util.inspect(object, options));
 };
 
 Console.prototype.time = function time(label = 'default') {
@@ -411,15 +432,11 @@ Console.prototype.table = function(tabularData, properties) {
   const final = (k, v) => this.log(cliTable(k, v));
 
   const inspect = (v) => {
-    const depth = v !== null &&
-                  typeof v === 'object' &&
-                  !isArray(v) &&
-                  ObjectKeys(v).length > 2 ? -1 : 0;
-    const opt = {
-      depth,
-      maxArrayLength: 3,
-      ...this[kGetInspectOptions](this._stdout)
-    };
+    const opt = { depth: 0, maxArrayLength: 3 };
+    if (v !== null && typeof v === 'object' &&
+      !isArray(v) && ObjectKeys(v).length > 2)
+      opt.depth = -1;
+    Object.assign(opt, this[kGetInspectOptions](this._stdout));
     return util.inspect(v, opt);
   };
   const getIndexArray = (length) => ArrayFrom({ length }, (_, i) => inspect(i));
@@ -516,8 +533,42 @@ Console.prototype.table = function(tabularData, properties) {
 
 function noop() {}
 
-module.exports = {
-  Console,
-  kBindStreamsLazy,
-  kBindProperties
-};
+// See https://console.spec.whatwg.org/#console-namespace
+// > For historical web-compatibility reasons, the namespace object
+// > for console must have as its [[Prototype]] an empty object,
+// > created as if by ObjectCreate(%ObjectPrototype%),
+// > instead of %ObjectPrototype%.
+
+// Since in Node.js, the Console constructor has been exposed through
+// require('console'), we need to keep the Console constructor but
+// we cannot actually use `new Console` to construct the global console.
+// Therefore, the console.Console.prototype is not
+// in the global console prototype chain anymore.
+
+// TODO(joyeecheung):
+// - Move the Console constructor into internal/console.js
+// - Move the global console creation code along with the inspector console
+//   wrapping code in internal/bootstrap/node.js into a separate file.
+// - Make this file a simple re-export of those two files.
+// This is only here for v11.x conflict resolution.
+const globalConsole = Object.create(Console.prototype);
+
+// Since Console is not on the prototype chain of the global console,
+// the symbol properties on Console.prototype have to be looked up from
+// the global console itself. In addition, we need to make the global
+// console a namespace by binding the console methods directly onto
+// the global console with the receiver fixed.
+for (const prop of Reflect.ownKeys(Console.prototype)) {
+  if (prop === 'constructor') { continue; }
+  const desc = Reflect.getOwnPropertyDescriptor(Console.prototype, prop);
+  if (typeof desc.value === 'function') { // fix the receiver
+    desc.value = desc.value.bind(globalConsole);
+  }
+  Reflect.defineProperty(globalConsole, prop, desc);
+}
+
+globalConsole[kBindStreamsLazy](process);
+globalConsole[kBindProperties](true, 'auto');
+
+module.exports = globalConsole;
+module.exports.Console = Console;