Skip to content

Commit

Permalink
fix: babel-register transform internal dependencies (#12665)
Browse files Browse the repository at this point in the history
Closes #11964, #12662.
  • Loading branch information
overlookmotel committed Jan 22, 2021
1 parent f1314a1 commit 22eb99b
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 15 deletions.
2 changes: 1 addition & 1 deletion packages/babel-register/package.json
Expand Up @@ -14,7 +14,7 @@
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"main": "lib/index.js",
"browser": {
"./lib/node.js": "./lib/browser.js"
"./lib/nodeWrapper.js": "./lib/browser.js"
},
"dependencies": {
"find-cache-dir": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-register/src/index.js
Expand Up @@ -9,7 +9,7 @@ exports = module.exports = function (...args) {
};
exports.__esModule = true;

const node = require("./node");
const node = require("./nodeWrapper");
const register = node.default;

Object.assign(exports, node);
5 changes: 5 additions & 0 deletions packages/babel-register/src/node.js
Expand Up @@ -7,6 +7,7 @@ import { OptionManager, DEFAULT_EXTENSIONS } from "@babel/core";
import { addHook } from "pirates";
import fs from "fs";
import path from "path";
import Module from "module";

const maps = {};
let transformOpts = {};
Expand Down Expand Up @@ -82,15 +83,19 @@ function compile(code, filename) {
}

let compiling = false;
const internalModuleCache = Module._cache;

function compileHook(code, filename) {
if (compiling) return code;

const globalModuleCache = Module._cache;
try {
compiling = true;
Module._cache = internalModuleCache;
return compile(code, filename);
} finally {
compiling = false;
Module._cache = globalModuleCache;
}
}

Expand Down
21 changes: 21 additions & 0 deletions packages/babel-register/src/nodeWrapper.js
@@ -0,0 +1,21 @@
/**
* This file wraps the implementation of register so all modules `require()`-ed
* internally within register are stored in a separate module cache.
* This prevents un-transformed modules being stored in global module cache,
* and allows register to transform these modules if they are loaded externally.
*/

const Module = require("module");

const globalModuleCache = Module._cache;
const internalModuleCache = Object.create(null);

Module._cache = internalModuleCache;
const node = require("./node");
Module._cache = globalModuleCache;

// Add source-map-support to global cache as it's stateful
const smsPath = require.resolve("source-map-support");
globalModuleCache[smsPath] = internalModuleCache[smsPath];

module.exports = node;
28 changes: 28 additions & 0 deletions packages/babel-register/test/fixtures/internal-modules/index.js
@@ -0,0 +1,28 @@
const register = require('../../..');

// Plugin to add '/* transformed */' comment to start of function bodies
const plugin = () => ( {
visitor: {
Function(path) {
const bodyNode = path.node.body;
(bodyNode.leadingComments || (bodyNode.leadingComments = [])).push( {
type: 'CommentBlock',
value: ' transformed '
} );
},
},
} );

register( {
ignore: [],
babelrc: false,
configFile: false,
plugins: [plugin]
} );

console.log(
JSON.stringify({
convertSourceMap: require('convert-source-map').fromObject.toString(),
isPlainObject: require('lodash/isPlainObject').toString()
})
);
54 changes: 41 additions & 13 deletions packages/babel-register/test/index.js
Expand Up @@ -6,14 +6,17 @@ let currentHook;
let currentOptions;
let sourceMapSupport = false;

const registerFile = require.resolve("../lib/node");
const registerFile = require.resolve("../lib/index");
const testCacheFilename = path.join(__dirname, ".babel");
const testFile = require.resolve("./fixtures/babelrc/es2015");
const testFileContent = fs.readFileSync(testFile);
const sourceMapTestFile = require.resolve("./fixtures/source-map/index");
const sourceMapNestedTestFile = require.resolve(
"./fixtures/source-map/foo/bar",
);
const internalModulesTestFile = require.resolve(
"./fixtures/internal-modules/index",
);

jest.mock("pirates", () => {
return {
Expand Down Expand Up @@ -152,18 +155,7 @@ describe("@babel/register", function () {
// that working inside a test, possibly because of jest鈥檚 mocking
// hooks, so we spawn a separate process.

const args = ["-r", registerFile, sourceMapTestFile];
const spawn = child.spawn(process.execPath, args, { cwd: __dirname });

let output = "";

for (const stream of [spawn.stderr, spawn.stdout]) {
stream.on("data", chunk => {
output += chunk;
});
}

spawn.on("close", function () {
spawnNode(["-r", registerFile, sourceMapTestFile], output => {
let err;

try {
Expand Down Expand Up @@ -201,4 +193,40 @@ describe("@babel/register", function () {

expect(result).toBe('"use strict";\n\nrequire("assert");');
});

test("transforms modules used within register", callback => {
// Need a clean environment without `convert-source-map`
// and `lodash/isPlainObject` already in the require cache,
// so we spawn a separate process

spawnNode([internalModulesTestFile], output => {
let err;

try {
const { convertSourceMap, isPlainObject } = JSON.parse(output);
expect(convertSourceMap).toMatch("/* transformed */");
expect(isPlainObject).toMatch("/* transformed */");
} catch (e) {
err = e;
}

callback(err);
});
});
});

function spawnNode(args, callback) {
const spawn = child.spawn(process.execPath, args, { cwd: __dirname });

let output = "";

for (const stream of [spawn.stderr, spawn.stdout]) {
stream.on("data", chunk => {
output += chunk;
});
}

spawn.on("close", function () {
callback(output);
});
}

0 comments on commit 22eb99b

Please sign in to comment.