fix: babel-register transform internal dependencies (#12665)
Closes #11964, #12662.
This commit is contained in:
parent
f1314a1683
commit
22eb99bea4
@ -14,7 +14,7 @@
|
|||||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"browser": {
|
"browser": {
|
||||||
"./lib/node.js": "./lib/browser.js"
|
"./lib/nodeWrapper.js": "./lib/browser.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"find-cache-dir": "^2.0.0",
|
"find-cache-dir": "^2.0.0",
|
||||||
|
|||||||
@ -9,7 +9,7 @@ exports = module.exports = function (...args) {
|
|||||||
};
|
};
|
||||||
exports.__esModule = true;
|
exports.__esModule = true;
|
||||||
|
|
||||||
const node = require("./node");
|
const node = require("./nodeWrapper");
|
||||||
const register = node.default;
|
const register = node.default;
|
||||||
|
|
||||||
Object.assign(exports, node);
|
Object.assign(exports, node);
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { OptionManager, DEFAULT_EXTENSIONS } from "@babel/core";
|
|||||||
import { addHook } from "pirates";
|
import { addHook } from "pirates";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import Module from "module";
|
||||||
|
|
||||||
const maps = {};
|
const maps = {};
|
||||||
let transformOpts = {};
|
let transformOpts = {};
|
||||||
@ -82,15 +83,19 @@ function compile(code, filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let compiling = false;
|
let compiling = false;
|
||||||
|
const internalModuleCache = Module._cache;
|
||||||
|
|
||||||
function compileHook(code, filename) {
|
function compileHook(code, filename) {
|
||||||
if (compiling) return code;
|
if (compiling) return code;
|
||||||
|
|
||||||
|
const globalModuleCache = Module._cache;
|
||||||
try {
|
try {
|
||||||
compiling = true;
|
compiling = true;
|
||||||
|
Module._cache = internalModuleCache;
|
||||||
return compile(code, filename);
|
return compile(code, filename);
|
||||||
} finally {
|
} finally {
|
||||||
compiling = false;
|
compiling = false;
|
||||||
|
Module._cache = globalModuleCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
packages/babel-register/src/nodeWrapper.js
Normal file
21
packages/babel-register/src/nodeWrapper.js
Normal 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;
|
||||||
28
packages/babel-register/test/fixtures/internal-modules/index.js
vendored
Normal file
28
packages/babel-register/test/fixtures/internal-modules/index.js
vendored
Normal 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()
|
||||||
|
})
|
||||||
|
);
|
||||||
@ -6,7 +6,7 @@ let currentHook;
|
|||||||
let currentOptions;
|
let currentOptions;
|
||||||
let sourceMapSupport = false;
|
let sourceMapSupport = false;
|
||||||
|
|
||||||
const registerFile = require.resolve("../lib/node");
|
const registerFile = require.resolve("../lib/index");
|
||||||
const testCacheFilename = path.join(__dirname, ".babel");
|
const testCacheFilename = path.join(__dirname, ".babel");
|
||||||
const testFile = require.resolve("./fixtures/babelrc/es2015");
|
const testFile = require.resolve("./fixtures/babelrc/es2015");
|
||||||
const testFileContent = fs.readFileSync(testFile);
|
const testFileContent = fs.readFileSync(testFile);
|
||||||
@ -14,6 +14,9 @@ const sourceMapTestFile = require.resolve("./fixtures/source-map/index");
|
|||||||
const sourceMapNestedTestFile = require.resolve(
|
const sourceMapNestedTestFile = require.resolve(
|
||||||
"./fixtures/source-map/foo/bar",
|
"./fixtures/source-map/foo/bar",
|
||||||
);
|
);
|
||||||
|
const internalModulesTestFile = require.resolve(
|
||||||
|
"./fixtures/internal-modules/index",
|
||||||
|
);
|
||||||
|
|
||||||
jest.mock("pirates", () => {
|
jest.mock("pirates", () => {
|
||||||
return {
|
return {
|
||||||
@ -152,18 +155,7 @@ describe("@babel/register", function () {
|
|||||||
// that working inside a test, possibly because of jest’s mocking
|
// that working inside a test, possibly because of jest’s mocking
|
||||||
// hooks, so we spawn a separate process.
|
// hooks, so we spawn a separate process.
|
||||||
|
|
||||||
const args = ["-r", registerFile, sourceMapTestFile];
|
spawnNode(["-r", registerFile, sourceMapTestFile], output => {
|
||||||
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 () {
|
|
||||||
let err;
|
let err;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -201,4 +193,40 @@ describe("@babel/register", function () {
|
|||||||
|
|
||||||
expect(result).toBe('"use strict";\n\nrequire("assert");');
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user