Skip to content

Commit

Permalink
[babel 8] Move @babel/register transform to a separate worker (#14025)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Dec 29, 2021
1 parent d1cabf6 commit e77e3de
Show file tree
Hide file tree
Showing 31 changed files with 777 additions and 367 deletions.
@@ -1 +1,3 @@
console.log("foo");
// See https://github.com/babel/babel/pull/14025#issuecomment-986296424
// for the reason behind using setImmediate.
setImmediate(() => console.log("foo"));
@@ -1 +1,3 @@
console.log("foo");
// See https://github.com/babel/babel/pull/14025#issuecomment-986296424
// for the reason behind using setImmediate.
setImmediate(() => console.log("foo"));
@@ -1 +1,3 @@
console.log("foo");
// See https://github.com/babel/babel/pull/14025#issuecomment-986296424
// for the reason behind using setImmediate.
setImmediate(() => console.log("foo"));
4 changes: 3 additions & 1 deletion packages/babel-node/test/fixtures/cli/-b/in-files/index.js
@@ -1 +1,3 @@
console.log("foo");
// See https://github.com/babel/babel/pull/14025#issuecomment-986296424
// for the reason behind using setImmediate.
setImmediate(() => console.log("foo"));
4 changes: 4 additions & 0 deletions packages/babel-register/.npmignore
@@ -1,3 +1,7 @@
src
test
*.log

experimental-worker.js
lib/experimental-worker.js
lib/is-in-register-worker.js
1 change: 1 addition & 0 deletions packages/babel-register/experimental-worker.js
@@ -0,0 +1 @@
module.exports = require("./lib/experimental-worker");
4 changes: 3 additions & 1 deletion packages/babel-register/package.json
Expand Up @@ -12,9 +12,10 @@
"directory": "packages/babel-register"
},
"author": "The Babel Team (https://babel.dev/team)",
"type": "commonjs",
"main": "./lib/index.js",
"browser": {
"./lib/nodeWrapper.js": "./lib/browser.js"
"./lib/index.js": "./lib/browser.js"
},
"dependencies": {
"clone-deep": "^4.0.1",
Expand All @@ -28,6 +29,7 @@
},
"devDependencies": {
"@babel/core": "workspace:^",
"@babel/plugin-transform-arrow-functions": "workspace:^",
"@babel/plugin-transform-modules-commonjs": "workspace:^",
"browserify": "^16.5.2"
},
Expand Down
10 changes: 10 additions & 0 deletions packages/babel-register/src/browser.js
@@ -0,0 +1,10 @@
// required to safely use babel/register within a browserify codebase

function register() {}

module.exports = Object.assign(register, {
default: register,
register,
revert: function revert() {},
__esModule: true,
});
5 changes: 0 additions & 5 deletions packages/babel-register/src/browser.ts

This file was deleted.

3 changes: 3 additions & 0 deletions packages/babel-register/src/cache.js
@@ -0,0 +1,3 @@
// File moved to ./worker/cache.js
// TODO: Remove this backward-compat "proxy file" in Babel 8
module.exports = require("./worker/cache");
26 changes: 26 additions & 0 deletions packages/babel-register/src/experimental-worker.js
@@ -0,0 +1,26 @@
// TODO: Move this file to index.js in Babel 8

"use strict";

const [major, minor] = process.versions.node.split(".").map(Number);

if (major < 12 || (major === 12 && minor < 3)) {
throw new Error(
"@babel/register/experimental-worker requires Node.js >= 12.3.0",
);
}

const hook = require("./hook");
const { WorkerClient } = require("./worker-client");

const register = hook.register.bind(null, new WorkerClient());

module.exports = Object.assign(register, {
revert: hook.revert,
default: register,
__esModule: true,
});

if (!require("./is-in-register-worker").isInRegisterWorker) {
register();
}
85 changes: 85 additions & 0 deletions packages/babel-register/src/hook.js
@@ -0,0 +1,85 @@
"use strict";

const { addHook } = require("pirates");
const sourceMapSupport = require("source-map-support");

let piratesRevert;
const maps = Object.create(null);

function installSourceMapSupport() {
installSourceMapSupport = () => {}; // eslint-disable-line no-func-assign

sourceMapSupport.install({
handleUncaughtExceptions: false,
environment: "node",
retrieveSourceMap(filename) {
const map = maps?.[filename];
if (map) {
return { url: null, map: map };
} else {
return null;
}
},
});
}

if (!process.env.BABEL_8_BREAKING) {
// Babel 7 compiles files in the same thread where it hooks `require()`,
// so we must prevent mixing Babel plugin dependencies with the files
// to be compiled.
// All the `!process.env.BABEL_8_BREAKING` code in this file is for
// this purpose.

const Module = require("module");

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

// eslint-disable-next-line no-var
var compileBabel7 = function compileBabel7(client, code, filename) {
if (!client.isLocalClient) return compile(client, code, filename);

if (compiling) return code;

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

function compile(client, inputCode, filename) {
const result = client.transform(inputCode, filename);

if (result === null) return inputCode;

const { code, map } = result;
if (map) {
maps[filename] = map;
installSourceMapSupport();
}
return code;
}

exports.register = function register(client, opts = {}) {
if (piratesRevert) piratesRevert();

piratesRevert = addHook(
(process.env.BABEL_8_BREAKING ? compile : compileBabel7).bind(null, client),
{
exts: opts.extensions ?? client.getDefaultExtensions(),
ignoreNodeModules: false,
},
);

client.setOptions(opts);
};

exports.revert = function revert() {
if (piratesRevert) piratesRevert();
};
18 changes: 11 additions & 7 deletions packages/babel-register/src/index.js
Expand Up @@ -4,12 +4,16 @@
* from a compiled Babel import.
*/

exports = module.exports = function (...args) {
return register(...args);
};
exports.__esModule = true;
if (process.env.BABEL_8_BREAKING) {
module.exports = require("./experimental-worker");
} else {
exports = module.exports = function (...args) {
return register(...args);
};
exports.__esModule = true;

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

Object.assign(exports, node);
Object.assign(exports, node);
}
20 changes: 20 additions & 0 deletions packages/babel-register/src/is-in-register-worker.js
@@ -0,0 +1,20 @@
"use strict";

/**
* Since workers inherit the exec options from the parent thread, we
* must be careful to avoid infite "@babel/register" setup loops.
*
* If @babel/register is imported using the -r/--require flag, the worker
* will have the same flag and we must avoid registering the @babel/register
* hook again.
*
* - markInRegisterWorker() can be used to mark a set of env vars (that will
* be forwarded to a worker) as being in the @babel/register worker.
* - isInRegisterWorker will be true in @babel/register workers.
*/

const envVarName = "___INTERNAL___IS_INSIDE_BABEL_REGISTER_WORKER___";
const envVarValue = "yes_I_am";

exports.markInRegisterWorker = env => ({ ...env, [envVarName]: envVarValue });
exports.isInRegisterWorker = process.env[envVarName] === envVarValue;
13 changes: 13 additions & 0 deletions packages/babel-register/src/node.js
@@ -0,0 +1,13 @@
// TODO: Remove this file in Babel 8

"use strict";

const hook = require("./hook");
const { LocalClient } = require("./worker-client");

const register = hook.register.bind(null, new LocalClient());

module.exports = Object.assign(register, {
revert: hook.revert,
default: register,
});

0 comments on commit e77e3de

Please sign in to comment.