From cf1fe762dcc9381060eb9ab55920e86a02bf55ec Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 11 Jul 2017 09:23:38 -0400 Subject: [PATCH] lib: improve lazy requires * internal/errors - assert should already be in place when calling any of the message generating functions. * No lazy load if not necessary. * Replace function calls with `if`s. PR-URL: https://github.com/nodejs/node/pull/14167 Reviewed-By: Refael Ackermann Reviewed-By: Timothy Gu --- lib/dgram.js | 7 ++----- lib/internal/errors.js | 37 +++++++++++++-------------------- lib/internal/process.js | 18 +++++----------- lib/internal/process/stdio.js | 18 ++++------------ lib/internal/process/warning.js | 26 ++++++++--------------- lib/net.js | 17 +++++---------- lib/readline.js | 6 ++---- 7 files changed, 41 insertions(+), 88 deletions(-) diff --git a/lib/dgram.js b/lib/dgram.js index 486f269345cacf..3221784d533c3d 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -24,6 +24,7 @@ const assert = require('assert'); const errors = require('internal/errors'); const Buffer = require('buffer').Buffer; +const dns = require('dns'); const util = require('util'); const EventEmitter = require('events'); const setInitTriggerId = require('async_hooks').setInitTriggerId; @@ -39,17 +40,13 @@ const BIND_STATE_UNBOUND = 0; const BIND_STATE_BINDING = 1; const BIND_STATE_BOUND = 2; -// lazily loaded +// Lazily loaded var cluster = null; -var dns = null; const errnoException = util._errnoException; const exceptionWithHostPort = util._exceptionWithHostPort; function lookup(address, family, callback) { - if (!dns) - dns = require('dns'); - return dns.lookup(address, family, callback); } diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 48a47bc64102d8..6499e4991f2921 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -9,19 +9,9 @@ const kCode = Symbol('code'); const messages = new Map(); -var util; -function lazyUtil() { - if (!util) - util = require('util'); - return util; -} - -var assert; -function lazyAssert() { - if (!assert) - assert = require('assert'); - return assert; -} +// Lazily loaded +var assert = null; +var util = null; function makeNodeError(Base) { return class NodeError extends Base { @@ -45,13 +35,14 @@ class AssertionError extends Error { if (typeof options !== 'object' || options === null) { throw new exports.TypeError('ERR_INVALID_ARG_TYPE', 'options', 'object'); } - const util = lazyUtil(); - const message = options.message || - `${util.inspect(options.actual).slice(0, 128)} ` + - `${options.operator} ` + - util.inspect(options.expected).slice(0, 128); + if (options.message) { + super(options.message); + } else { + if (util === null) util = require('util'); + super(`${util.inspect(options.actual).slice(0, 128)} ` + + `${options.operator} ${util.inspect(options.expected).slice(0, 128)}`); + } - super(message); this.generatedMessage = !options.message; this.name = 'AssertionError [ERR_ASSERTION]'; this.code = 'ERR_ASSERTION'; @@ -63,15 +54,16 @@ class AssertionError extends Error { } function message(key, args) { - const assert = lazyAssert(); + if (assert === null) assert = require('assert'); assert.strictEqual(typeof key, 'string'); - const util = lazyUtil(); const msg = messages.get(key); assert(msg, `An invalid error message key was used: ${key}.`); - let fmt = util.format; + let fmt; if (typeof msg === 'function') { fmt = msg; } else { + if (util === null) util = require('util'); + fmt = util.format; if (args === undefined || args.length === 0) return msg; args.unshift(msg); @@ -240,7 +232,6 @@ E('ERR_VALID_PERFORMANCE_ENTRY_TYPE', // Add new errors from here... function invalidArgType(name, expected, actual) { - const assert = lazyAssert(); assert(name, 'name is required'); var msg = `The "${name}" argument must be ${oneOf(expected, 'type')}`; if (arguments.length >= 3) { diff --git a/lib/internal/process.js b/lib/internal/process.js index 92be0b674056fd..7f903798a262f9 100644 --- a/lib/internal/process.js +++ b/lib/internal/process.js @@ -1,15 +1,7 @@ 'use strict'; const util = require('util'); - -var _lazyConstants = null; - -function lazyConstants() { - if (!_lazyConstants) { - _lazyConstants = process.binding('constants').os.signals; - } - return _lazyConstants; -} +const constants = process.binding('constants').os.signals; const assert = process.assert = function(x, msg) { if (!x) throw new Error(msg || 'assertion error'); @@ -177,8 +169,8 @@ function setupKillAndExit() { err = process._kill(pid, 0); } else { sig = sig || 'SIGTERM'; - if (lazyConstants()[sig]) { - err = process._kill(pid, lazyConstants()[sig]); + if (constants[sig]) { + err = process._kill(pid, constants[sig]); } else { throw new Error(`Unknown signal: ${sig}`); } @@ -198,7 +190,7 @@ function setupSignalHandlers() { const signalWraps = {}; function isSignal(event) { - return typeof event === 'string' && lazyConstants()[event] !== undefined; + return typeof event === 'string' && constants[event] !== undefined; } // Detect presence of a listener for the special signal types @@ -212,7 +204,7 @@ function setupSignalHandlers() { wrap.onsignal = function() { process.emit(type); }; - const signum = lazyConstants()[type]; + const signum = constants[type]; const err = wrap.start(signum); if (err) { wrap.close(); diff --git a/lib/internal/process/stdio.js b/lib/internal/process/stdio.js index db544b15337142..45568ae631698b 100644 --- a/lib/internal/process/stdio.js +++ b/lib/internal/process/stdio.js @@ -1,14 +1,8 @@ 'use strict'; -exports.setup = setupStdio; - -var errors; +const errors = require('internal/errors'); -function lazyErrors() { - if (!errors) - errors = require('internal/errors'); - return errors; -} +exports.setup = setupStdio; function setupStdio() { var stdin; @@ -20,8 +14,7 @@ function setupStdio() { stdout = createWritableStdioStream(1); stdout.destroySoon = stdout.destroy; stdout._destroy = function(er, cb) { - // avoid errors if we already emitted - const errors = lazyErrors(); + // Avoid errors if we already emitted er = er || new errors.Error('ERR_STDOUT_CLOSE'); cb(er); }; @@ -36,8 +29,7 @@ function setupStdio() { stderr = createWritableStdioStream(2); stderr.destroySoon = stderr.destroy; stderr._destroy = function(er, cb) { - // avoid errors if we already emitted - const errors = lazyErrors(); + // Avoid errors if we already emitted er = er || new errors.Error('ERR_STDERR_CLOSE'); cb(er); }; @@ -95,7 +87,6 @@ function setupStdio() { default: // Probably an error on in uv_guess_handle() - const errors = lazyErrors(); throw new errors.Error('ERR_UNKNOWN_STDIN_TYPE'); } @@ -180,7 +171,6 @@ function createWritableStdioStream(fd) { default: // Probably an error on in uv_guess_handle() - const errors = lazyErrors(); throw new errors.Error('ERR_UNKNOWN_STREAM_TYPE'); } diff --git a/lib/internal/process/warning.js b/lib/internal/process/warning.js index 3208fb098d0a97..67a3113f2330f4 100644 --- a/lib/internal/process/warning.js +++ b/lib/internal/process/warning.js @@ -2,26 +2,16 @@ const config = process.binding('config'); const prefix = `(${process.release.name}:${process.pid}) `; +const errors = require('internal/errors'); exports.setup = setupProcessWarnings; -var errors; -var fs; var cachedFd; var acquiringFd = false; function nop() {} -function lazyErrors() { - if (!errors) - errors = require('internal/errors'); - return errors; -} - -function lazyFs() { - if (!fs) - fs = require('fs'); - return fs; -} +// Lazily loaded +var fs = null; function writeOut(message) { if (console && typeof console.error === 'function') @@ -31,7 +21,8 @@ function writeOut(message) { function onClose(fd) { return function() { - lazyFs().close(fd, nop); + if (fs === null) fs = require('fs'); + fs.close(fd, nop); }; } @@ -53,14 +44,16 @@ function onAcquired(message) { return function(err, fd) { if (err) return writeOut(message); - lazyFs().appendFile(fd, `${message}\n`, nop); + if (fs === null) fs = require('fs'); + fs.appendFile(fd, `${message}\n`, nop); }; } function acquireFd(cb) { if (cachedFd === undefined && !acquiringFd) { acquiringFd = true; - lazyFs().open(config.warningFile, 'a', onOpen(cb)); + if (fs === null) fs = require('fs'); + fs.open(config.warningFile, 'a', onOpen(cb)); } else if (cachedFd !== undefined && !acquiringFd) { cb(null, cachedFd); } else { @@ -112,7 +105,6 @@ function setupProcessWarnings() { // process.emitWarning(str[, type[, code]][, ctor]) // process.emitWarning(str[, options]) process.emitWarning = function(warning, type, code, ctor, now) { - const errors = lazyErrors(); var detail; if (type !== null && typeof type === 'object' && !Array.isArray(type)) { ctor = type.ctor; diff --git a/lib/net.js b/lib/net.js index 80fd1f82e5375c..c4054cf8b61071 100644 --- a/lib/net.js +++ b/lib/net.js @@ -43,9 +43,11 @@ const async_id_symbol = process.binding('async_wrap').async_id_symbol; const { newUid, setInitTriggerId } = require('async_hooks'); const nextTick = require('internal/process/next_tick').nextTick; const errors = require('internal/errors'); +const dns = require('dns'); -var cluster; -var dns; +// `cluster` is only used by `listenInCluster` so for startup performance +// reasons it's lazy loaded. +var cluster = null; const errnoException = util._errnoException; const exceptionWithHostPort = util._exceptionWithHostPort; @@ -1023,7 +1025,6 @@ Socket.prototype.connect = function(...args) { function lookupAndConnect(self, options) { - const dns = lazyDns(); var host = options.host || 'localhost'; var port = options.port; var localAddress = options.localAddress; @@ -1371,18 +1372,11 @@ function emitListeningNT(self) { } -function lazyDns() { - if (dns === undefined) - dns = require('dns'); - return dns; -} - - function listenInCluster(server, address, port, addressType, backlog, fd, exclusive) { exclusive = !!exclusive; - if (!cluster) cluster = require('cluster'); + if (cluster === null) cluster = require('cluster'); if (cluster.isMaster || exclusive) { // Will create a new handle @@ -1491,7 +1485,6 @@ Server.prototype.listen = function(...args) { }; function lookupAndListen(self, port, address, backlog, exclusive) { - const dns = lazyDns(); dns.lookup(address, function doListen(err, ip, addressType) { if (err) { self.emit('error', err); diff --git a/lib/readline.js b/lib/readline.js index 60d67083274532..8a6a5e2d1ac203 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -28,8 +28,9 @@ 'use strict'; const { debug, inherits } = require('util'); -const Buffer = require('buffer').Buffer; +const { Buffer } = require('buffer'); const EventEmitter = require('events'); +const { StringDecoder } = require('string_decoder'); const { CSI, emitKeys, @@ -59,7 +60,6 @@ const ESCAPE_DECODER = Symbol('escape-decoder'); // GNU readline library - keyseq-timeout is 500ms (default) const ESCAPE_CODE_TIMEOUT = 500; - function createInterface(input, output, completer, terminal) { return new Interface(input, output, completer, terminal); } @@ -177,7 +177,6 @@ function Interface(input, output, completer, terminal) { input.removeListener('data', ondata); input.removeListener('end', onend); }); - var StringDecoder = require('string_decoder').StringDecoder; // lazy load this._decoder = new StringDecoder('utf8'); } else { @@ -979,7 +978,6 @@ Interface.prototype._ttyWrite = function(s, key) { function emitKeypressEvents(stream, iface) { if (stream[KEYPRESS_DECODER]) return; - var StringDecoder = require('string_decoder').StringDecoder; // lazy load stream[KEYPRESS_DECODER] = new StringDecoder('utf8'); stream[ESCAPE_DECODER] = emitKeys(stream);