fix: babel-register transform internal dependencies (#12665)

Closes #11964, #12662.
This commit is contained in:
overlookmotel 2021-01-22 10:08:20 +00:00 committed by GitHub
parent f1314a1683
commit 22eb99bea4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 97 additions and 15 deletions

View File

@ -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",

View File

@ -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);

View File

@ -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 = {};
@ -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;
}
}

View File

@ -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;

View File

@ -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()
})
);

View File

@ -6,7 +6,7 @@ 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);
@ -14,6 +14,9 @@ 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 {
@ -152,18 +155,7 @@ describe("@babel/register", function () {
// that working inside a test, possibly because of jests 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 {
@ -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);
});
}