Skip to content

Commit

Permalink
Revert "module: disable cjs snapshotting into esm loader"
Browse files Browse the repository at this point in the history
This reverts commit 1fe39f0.

PR-URL: nodejs#34562
Reviewed-By: Bradley Farias <bradley.meck@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
  • Loading branch information
devsnek committed Jul 30, 2020
1 parent 2d2a812 commit dc00a07
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 19 deletions.
32 changes: 30 additions & 2 deletions lib/internal/modules/cjs/loader.js
Expand Up @@ -32,6 +32,7 @@ const {
ArrayPrototypeJoin,
Error,
JSONParse,
Map,
Number,
ObjectCreate,
ObjectDefineProperty,
Expand Down Expand Up @@ -112,6 +113,8 @@ const {
} = require('internal/util/types');

const asyncESM = require('internal/process/esm_loader');
const ModuleJob = require('internal/modules/esm/module_job');
const { ModuleWrap, kInstantiated } = internalBinding('module_wrap');
const {
encodedSepRegEx,
packageInternalResolve
Expand Down Expand Up @@ -371,7 +374,7 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
// In order to minimize unnecessary lstat() calls,
// this cache is a list of known-real paths.
// Set to an empty Map to reset.
const realpathCache = new SafeMap();
const realpathCache = new Map();

// Check if the file exists and is not a directory
// if using --preserve-symlinks and isMain is false,
Expand Down Expand Up @@ -1115,6 +1118,31 @@ Module.prototype.load = function(filename) {
}
Module._extensions[extension](this, filename);
this.loaded = true;

const ESMLoader = asyncESM.ESMLoader;
const url = `${pathToFileURL(filename)}`;
const module = ESMLoader.moduleMap.get(url);
// Create module entry at load time to snapshot exports correctly
const exports = this.exports;
// Called from cjs translator
if (module !== undefined && module.module !== undefined) {
if (module.module.getStatus() >= kInstantiated)
module.module.setExport('default', exports);
} else {
// Preemptively cache
// We use a function to defer promise creation for async hooks.
ESMLoader.moduleMap.set(
url,
// Module job creation will start promises.
// We make it a function to lazily trigger those promises
// for async hooks compatibility.
() => new ModuleJob(ESMLoader, url, () =>
new ModuleWrap(url, undefined, ['default'], function() {
this.setExport('default', exports);
})
, false /* isMain */, false /* inspectBrk */)
);
}
};


Expand Down Expand Up @@ -1234,7 +1262,7 @@ Module.prototype._compile = function(content, filename) {
const exports = this.exports;
const thisValue = exports;
const module = this;
if (requireDepth === 0) statCache = new SafeMap();
if (requireDepth === 0) statCache = new Map();
if (inspectorWrapper) {
result = inspectorWrapper(compiledWrapper, thisValue, exports,
require, module, filename, dirname);
Expand Down
6 changes: 5 additions & 1 deletion lib/internal/modules/esm/loader.js
Expand Up @@ -5,7 +5,8 @@ require('internal/modules/cjs/loader');

const {
FunctionPrototypeBind,
ObjectSetPrototypeOf
ObjectSetPrototypeOf,
SafeMap,
} = primordials;

const {
Expand Down Expand Up @@ -45,6 +46,9 @@ class Loader {
// Registry of loaded modules, akin to `require.cache`
this.moduleMap = new ModuleMap();

// Map of already-loaded CJS modules to use
this.cjsCache = new SafeMap();

// This hook is called before the first root module is imported. It's a
// function that returns a piece of code that runs as a sloppy-mode script.
// The script may evaluate to a function that can be called with a
Expand Down
34 changes: 19 additions & 15 deletions lib/internal/modules/esm/translators.js
Expand Up @@ -11,8 +11,6 @@ const {
StringPrototypeReplace,
} = primordials;

const assert = require('internal/assert');

let _TYPES = null;
function lazyTypes() {
if (_TYPES !== null) return _TYPES;
Expand Down Expand Up @@ -134,21 +132,27 @@ const isWindows = process.platform === 'win32';
const winSepRegEx = /\//g;
translators.set('commonjs', function commonjsStrategy(url, isMain) {
debug(`Translating CJSModule ${url}`);
let filename = internalURLModule.fileURLToPath(new URL(url));
if (isWindows)
filename = StringPrototypeReplace(filename, winSepRegEx, '\\');
const pathname = internalURLModule.fileURLToPath(new URL(url));
const cached = this.cjsCache.get(url);
if (cached) {
this.cjsCache.delete(url);
return cached;
}
const module = CJSModule._cache[
isWindows ? StringPrototypeReplace(pathname, winSepRegEx, '\\') : pathname
];
if (module && module.loaded) {
const exports = module.exports;
return new ModuleWrap(url, undefined, ['default'], function() {
this.setExport('default', exports);
});
}
return new ModuleWrap(url, undefined, ['default'], function() {
debug(`Loading CJSModule ${url}`);
let module = CJSModule._cache[filename];
if (!module || !module.loaded) {
module = new CJSModule(filename);
module.filename = filename;
module.paths = CJSModule._nodeModulePaths(module.path);
CJSModule._cache[filename] = module;
module.load(filename);
assert(module && module.loaded);
}
this.setExport('default', module.exports);
// We don't care about the return val of _load here because Module#load
// will handle it for us by checking the loader registry and filling the
// exports like above
CJSModule._load(pathname, undefined, isMain);
});
});

Expand Down
2 changes: 1 addition & 1 deletion test/es-module/test-esm-snapshot.mjs
Expand Up @@ -3,4 +3,4 @@ import '../fixtures/es-modules/esm-snapshot-mutator.js';
import one from '../fixtures/es-modules/esm-snapshot.js';
import assert from 'assert';

assert.strictEqual(one, 2);
assert.strictEqual(one, 1);

0 comments on commit dc00a07

Please sign in to comment.