Expose @babel/eslint-parser/experimental-worker (#13398)
* Expose `@babel/eslint-parser/experimental-worker` * Fix `@babel/runtime` build on Windows
This commit is contained in:
parent
830b99dc83
commit
885e1e02f5
@ -23,6 +23,7 @@
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": "./lib/index.cjs",
|
||||
"./experimental-worker": "./lib/experimental-worker.cjs",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@ -4,13 +4,11 @@ const OriginalPatternVisitor = require("eslint-scope/lib/pattern-visitor");
|
||||
const OriginalReferencer = require("eslint-scope/lib/referencer");
|
||||
const { getKeys: fallback } = require("eslint-visitor-keys");
|
||||
|
||||
const { getTypesInfo, getVisitorKeys } = require("./client.cjs");
|
||||
|
||||
let visitorKeysMap;
|
||||
function getVisitorValues(nodeType) {
|
||||
function getVisitorValues(nodeType, client) {
|
||||
if (visitorKeysMap) return visitorKeysMap[nodeType];
|
||||
|
||||
const { FLOW_FLIPPED_ALIAS_KEYS, VISITOR_KEYS } = getTypesInfo();
|
||||
const { FLOW_FLIPPED_ALIAS_KEYS, VISITOR_KEYS } = client.getTypesInfo();
|
||||
|
||||
const flowFlippedAliasKeys = FLOW_FLIPPED_ALIAS_KEYS.concat([
|
||||
"ArrayPattern",
|
||||
@ -63,6 +61,13 @@ class PatternVisitor extends OriginalPatternVisitor {
|
||||
}
|
||||
|
||||
class Referencer extends OriginalReferencer {
|
||||
#client;
|
||||
|
||||
constructor(options, scopeManager, client) {
|
||||
super(options, scopeManager);
|
||||
this.#client = client;
|
||||
}
|
||||
|
||||
// inherits.
|
||||
visitPattern(node, options, callback) {
|
||||
if (!node) {
|
||||
@ -264,7 +269,7 @@ class Referencer extends OriginalReferencer {
|
||||
}
|
||||
|
||||
// get property to check (params, id, etc...)
|
||||
const visitorValues = getVisitorValues(node.type);
|
||||
const visitorValues = getVisitorValues(node.type, this.#client);
|
||||
if (!visitorValues) {
|
||||
return;
|
||||
}
|
||||
@ -328,7 +333,7 @@ class Referencer extends OriginalReferencer {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function analyzeScope(ast, parserOptions) {
|
||||
module.exports = function analyzeScope(ast, parserOptions, client) {
|
||||
const options = {
|
||||
ignoreEval: true,
|
||||
optimistic: false,
|
||||
@ -343,10 +348,10 @@ module.exports = function analyzeScope(ast, parserOptions) {
|
||||
fallback,
|
||||
};
|
||||
|
||||
options.childVisitorKeys = getVisitorKeys();
|
||||
options.childVisitorKeys = client.getVisitorKeys();
|
||||
|
||||
const scopeManager = new escope.ScopeManager(options);
|
||||
const referencer = new Referencer(options, scopeManager);
|
||||
const referencer = new Referencer(options, scopeManager, client);
|
||||
|
||||
referencer.visit(ast);
|
||||
|
||||
|
||||
@ -1,67 +1,105 @@
|
||||
const path = require("path");
|
||||
|
||||
let send;
|
||||
const ACTIONS = {
|
||||
GET_VERSION: "GET_VERSION",
|
||||
GET_TYPES_INFO: "GET_TYPES_INFO",
|
||||
GET_VISITOR_KEYS: "GET_VISITOR_KEYS",
|
||||
GET_TOKEN_LABELS: "GET_TOKEN_LABELS",
|
||||
MAYBE_PARSE: "MAYBE_PARSE",
|
||||
MAYBE_PARSE_SYNC: "MAYBE_PARSE_SYNC",
|
||||
};
|
||||
|
||||
exports.getVersion = sendCached("GET_VERSION");
|
||||
class Client {
|
||||
#send;
|
||||
|
||||
exports.getTypesInfo = sendCached("GET_TYPES_INFO");
|
||||
constructor(send) {
|
||||
this.#send = send;
|
||||
}
|
||||
|
||||
exports.getVisitorKeys = sendCached("GET_VISITOR_KEYS");
|
||||
#vCache;
|
||||
getVersion() {
|
||||
return (this.#vCache ??= this.#send(ACTIONS.GET_VERSION, undefined));
|
||||
}
|
||||
|
||||
exports.getTokLabels = sendCached("GET_TOKEN_LABELS");
|
||||
#tiCache;
|
||||
getTypesInfo() {
|
||||
return (this.#tiCache ??= this.#send(ACTIONS.GET_TYPES_INFO, undefined));
|
||||
}
|
||||
|
||||
exports.maybeParse = (code, options) => send("MAYBE_PARSE", { code, options });
|
||||
#vkCache;
|
||||
getVisitorKeys() {
|
||||
return (this.#vkCache ??= this.#send(ACTIONS.GET_VISITOR_KEYS, undefined));
|
||||
}
|
||||
|
||||
function sendCached(action) {
|
||||
let cache = null;
|
||||
#tlCache;
|
||||
getTokLabels() {
|
||||
return (this.#tlCache ??= this.#send(ACTIONS.GET_TOKEN_LABELS, undefined));
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (!cache) cache = send(action, undefined);
|
||||
return cache;
|
||||
};
|
||||
maybeParse(code, options) {
|
||||
return this.#send(ACTIONS.MAYBE_PARSE, { code, options });
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.BABEL_8_BREAKING) {
|
||||
const {
|
||||
Worker,
|
||||
receiveMessageOnPort,
|
||||
MessageChannel,
|
||||
SHARE_ENV,
|
||||
} = require("worker_threads");
|
||||
// We need to run Babel in a worker for two reasons:
|
||||
// 1. ESLint workers must be CJS files, and this is a problem
|
||||
// since Babel 8+ uses native ESM
|
||||
// 2. ESLint parsers must run synchronously, but many steps
|
||||
// of Babel's config loading (which is done for each file)
|
||||
// can be asynchronous
|
||||
// If ESLint starts supporting async parsers, we can move
|
||||
// everything back to the main thread.
|
||||
exports.WorkerClient = class WorkerClient extends Client {
|
||||
static #worker_threads_cache;
|
||||
static get #worker_threads() {
|
||||
return (WorkerClient.#worker_threads_cache ??= require("worker_threads"));
|
||||
}
|
||||
|
||||
// We need to run Babel in a worker for two reasons:
|
||||
// 1. ESLint workers must be CJS files, and this is a problem
|
||||
// since Babel 8+ uses native ESM
|
||||
// 2. ESLint parsers must run synchronously, but many steps
|
||||
// of Babel's config loading (which is done for each file)
|
||||
// can be asynchronous
|
||||
// If ESLint starts supporting async parsers, we can move
|
||||
// everything back to the main thread.
|
||||
const worker = new Worker(
|
||||
#worker = new WorkerClient.#worker_threads.Worker(
|
||||
path.resolve(__dirname, "../lib/worker/index.cjs"),
|
||||
{ env: SHARE_ENV },
|
||||
{ env: WorkerClient.#worker_threads.SHARE_ENV },
|
||||
);
|
||||
|
||||
// The worker will never exit by itself. Prevent it from keeping
|
||||
// the main process alive.
|
||||
worker.unref();
|
||||
#signal = new Int32Array(new SharedArrayBuffer(4));
|
||||
|
||||
const signal = new Int32Array(new SharedArrayBuffer(4));
|
||||
constructor() {
|
||||
super((action, payload) => {
|
||||
this.#signal[0] = 0;
|
||||
const subChannel = new WorkerClient.#worker_threads.MessageChannel();
|
||||
|
||||
send = (action, payload) => {
|
||||
signal[0] = 0;
|
||||
const subChannel = new MessageChannel();
|
||||
this.#worker.postMessage(
|
||||
{ signal: this.#signal, port: subChannel.port1, action, payload },
|
||||
[subChannel.port1],
|
||||
);
|
||||
|
||||
worker.postMessage({ signal, port: subChannel.port1, action, payload }, [
|
||||
subChannel.port1,
|
||||
]);
|
||||
|
||||
Atomics.wait(signal, 0, 0);
|
||||
const { message } = receiveMessageOnPort(subChannel.port2);
|
||||
Atomics.wait(this.#signal, 0, 0);
|
||||
const { message } = WorkerClient.#worker_threads.receiveMessageOnPort(
|
||||
subChannel.port2,
|
||||
);
|
||||
|
||||
if (message.error) throw Object.assign(message.error, message.errorData);
|
||||
else return message.result;
|
||||
});
|
||||
|
||||
// The worker will never exit by itself. Prevent it from keeping
|
||||
// the main process alive.
|
||||
this.#worker.unref();
|
||||
}
|
||||
};
|
||||
|
||||
if (!process.env.BABEL_8_BREAKING) {
|
||||
exports.LocalClient = class LocalClient extends Client {
|
||||
static #handleMessage;
|
||||
|
||||
constructor() {
|
||||
LocalClient.#handleMessage ??= require("./worker/handle-message.cjs");
|
||||
|
||||
super((action, payload) => {
|
||||
return LocalClient.#handleMessage(
|
||||
action === ACTIONS.MAYBE_PARSE ? ACTIONS.MAYBE_PARSE_SYNC : action,
|
||||
payload,
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
} else {
|
||||
send = require("./worker/index.cjs");
|
||||
}
|
||||
|
||||
22
eslint/babel-eslint-parser/src/experimental-worker.cjs
Normal file
22
eslint/babel-eslint-parser/src/experimental-worker.cjs
Normal file
@ -0,0 +1,22 @@
|
||||
const [major, minor] = process.versions.node.split(".").map(Number);
|
||||
|
||||
if (major < 12 || (major === 12 && minor < 3)) {
|
||||
throw new Error(
|
||||
"@babel/eslint-parser/experimental-worker requires Node.js >= 12.3.0",
|
||||
);
|
||||
}
|
||||
|
||||
const { normalizeESLintConfig } = require("./configuration.cjs");
|
||||
const analyzeScope = require("./analyze-scope.cjs");
|
||||
const baseParse = require("./parse.cjs");
|
||||
|
||||
const { WorkerClient } = require("./client.cjs");
|
||||
const client = new WorkerClient();
|
||||
|
||||
exports.parseForESLint = function (code, options = {}) {
|
||||
const normalizedOptions = normalizeESLintConfig(options);
|
||||
const ast = baseParse(code, normalizedOptions, client);
|
||||
const scopeManager = analyzeScope(ast, normalizedOptions, client);
|
||||
|
||||
return { ast, scopeManager, visitorKeys: client.getVisitorKeys() };
|
||||
};
|
||||
@ -1,63 +1,20 @@
|
||||
const semver = require("semver");
|
||||
const { normalizeESLintConfig } = require("./configuration.cjs");
|
||||
const analyzeScope = require("./analyze-scope.cjs");
|
||||
const {
|
||||
getVersion,
|
||||
getVisitorKeys,
|
||||
getTokLabels,
|
||||
maybeParse,
|
||||
} = require("./client.cjs");
|
||||
const convert = require("./convert/index.cjs");
|
||||
const baseParse = require("./parse.cjs");
|
||||
|
||||
const babelParser = require(require.resolve("@babel/parser", {
|
||||
paths: [require.resolve("@babel/core/package.json")],
|
||||
}));
|
||||
|
||||
let isRunningMinSupportedCoreVersion = null;
|
||||
|
||||
function baseParse(code, options) {
|
||||
// Ensure we're using a version of `@babel/core` that includes `parse()` and `tokTypes`.
|
||||
const minSupportedCoreVersion = ">=7.2.0";
|
||||
|
||||
if (typeof isRunningMinSupportedCoreVersion !== "boolean") {
|
||||
isRunningMinSupportedCoreVersion = semver.satisfies(
|
||||
getVersion(),
|
||||
minSupportedCoreVersion,
|
||||
);
|
||||
}
|
||||
|
||||
if (!isRunningMinSupportedCoreVersion) {
|
||||
throw new Error(
|
||||
`@babel/eslint-parser@${
|
||||
PACKAGE_JSON.version
|
||||
} does not support @babel/core@${getVersion()}. Please upgrade to @babel/core@${minSupportedCoreVersion}.`,
|
||||
);
|
||||
}
|
||||
|
||||
const { ast, parserOptions } = maybeParse(code, options);
|
||||
|
||||
if (ast) return ast;
|
||||
|
||||
try {
|
||||
return convert.ast(
|
||||
babelParser.parse(code, parserOptions),
|
||||
code,
|
||||
getTokLabels(),
|
||||
getVisitorKeys(),
|
||||
);
|
||||
} catch (err) {
|
||||
throw convert.error(err);
|
||||
}
|
||||
}
|
||||
const { LocalClient, WorkerClient } = require("./client.cjs");
|
||||
const client = new (
|
||||
process.env.BABEL_8_BREAKING ? WorkerClient : LocalClient
|
||||
)();
|
||||
|
||||
exports.parse = function (code, options = {}) {
|
||||
return baseParse(code, normalizeESLintConfig(options));
|
||||
return baseParse(code, normalizeESLintConfig(options), client);
|
||||
};
|
||||
|
||||
exports.parseForESLint = function (code, options = {}) {
|
||||
const normalizedOptions = normalizeESLintConfig(options);
|
||||
const ast = baseParse(code, normalizedOptions);
|
||||
const scopeManager = analyzeScope(ast, normalizedOptions);
|
||||
const ast = baseParse(code, normalizedOptions, client);
|
||||
const scopeManager = analyzeScope(ast, normalizedOptions, client);
|
||||
|
||||
return { ast, scopeManager, visitorKeys: getVisitorKeys() };
|
||||
return { ast, scopeManager, visitorKeys: client.getVisitorKeys() };
|
||||
};
|
||||
|
||||
45
eslint/babel-eslint-parser/src/parse.cjs
Normal file
45
eslint/babel-eslint-parser/src/parse.cjs
Normal file
@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
|
||||
const semver = require("semver");
|
||||
const convert = require("./convert/index.cjs");
|
||||
|
||||
const babelParser = require(require.resolve("@babel/parser", {
|
||||
paths: [require.resolve("@babel/core/package.json")],
|
||||
}));
|
||||
|
||||
let isRunningMinSupportedCoreVersion = null;
|
||||
|
||||
module.exports = function parse(code, options, client) {
|
||||
// Ensure we're using a version of `@babel/core` that includes `parse()` and `tokTypes`.
|
||||
const minSupportedCoreVersion = ">=7.2.0";
|
||||
|
||||
if (typeof isRunningMinSupportedCoreVersion !== "boolean") {
|
||||
isRunningMinSupportedCoreVersion = semver.satisfies(
|
||||
client.getVersion(),
|
||||
minSupportedCoreVersion,
|
||||
);
|
||||
}
|
||||
|
||||
if (!isRunningMinSupportedCoreVersion) {
|
||||
throw new Error(
|
||||
`@babel/eslint-parser@${
|
||||
PACKAGE_JSON.version
|
||||
} does not support @babel/core@${client.getVersion()}. Please upgrade to @babel/core@${minSupportedCoreVersion}.`,
|
||||
);
|
||||
}
|
||||
|
||||
const { ast, parserOptions } = client.maybeParse(code, options);
|
||||
|
||||
if (ast) return ast;
|
||||
|
||||
try {
|
||||
return convert.ast(
|
||||
babelParser.parse(code, parserOptions),
|
||||
code,
|
||||
client.getTokLabels(),
|
||||
client.getVisitorKeys(),
|
||||
);
|
||||
} catch (err) {
|
||||
throw convert.error(err);
|
||||
}
|
||||
};
|
||||
@ -41,7 +41,7 @@ function normalizeParserOptions(options) {
|
||||
};
|
||||
}
|
||||
|
||||
function validateResolvedConfig(config, options) {
|
||||
function validateResolvedConfig(config, options, parseOptions) {
|
||||
if (config !== null) {
|
||||
if (options.requireConfigFile !== false) {
|
||||
if (!config.hasFilesystemConfig()) {
|
||||
@ -54,8 +54,10 @@ function validateResolvedConfig(config, options) {
|
||||
throw new Error(error);
|
||||
}
|
||||
}
|
||||
return config.options;
|
||||
if (config.options) return config.options;
|
||||
}
|
||||
|
||||
return getDefaultParserOptions(parseOptions);
|
||||
}
|
||||
|
||||
function getDefaultParserOptions(options) {
|
||||
@ -70,25 +72,14 @@ function getDefaultParserOptions(options) {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function normalizeBabelParseConfig(options) {
|
||||
exports.normalizeBabelParseConfig = async function (options) {
|
||||
const parseOptions = normalizeParserOptions(options);
|
||||
|
||||
if (process.env.BABEL_8_BREAKING) {
|
||||
return babel
|
||||
.loadPartialConfigAsync(parseOptions)
|
||||
.then(config => validateConfigWithFallback(config));
|
||||
} else {
|
||||
const config = babel.loadPartialConfigSync(parseOptions);
|
||||
return validateConfigWithFallback(config);
|
||||
}
|
||||
|
||||
function validateConfigWithFallback(inputConfig) {
|
||||
const result = validateResolvedConfig(inputConfig, options);
|
||||
if (result) {
|
||||
return result;
|
||||
} else {
|
||||
// Fallback when `loadPartialConfig` returns `null` (e.g.: when the file is ignored)
|
||||
return getDefaultParserOptions(parseOptions);
|
||||
}
|
||||
}
|
||||
const config = await babel.loadPartialConfigAsync(parseOptions);
|
||||
return validateResolvedConfig(config, options, parseOptions);
|
||||
};
|
||||
|
||||
exports.normalizeBabelParseConfigSync = function (options) {
|
||||
const parseOptions = normalizeParserOptions(options);
|
||||
const config = babel.loadPartialConfigSync(parseOptions);
|
||||
return validateResolvedConfig(config, options, parseOptions);
|
||||
};
|
||||
|
||||
36
eslint/babel-eslint-parser/src/worker/handle-message.cjs
Normal file
36
eslint/babel-eslint-parser/src/worker/handle-message.cjs
Normal file
@ -0,0 +1,36 @@
|
||||
const babel = require("./babel-core.cjs");
|
||||
const maybeParse = require("./maybeParse.cjs");
|
||||
const { getVisitorKeys, getTokLabels } = require("./ast-info.cjs");
|
||||
const {
|
||||
normalizeBabelParseConfig,
|
||||
normalizeBabelParseConfigSync,
|
||||
} = require("./configuration.cjs");
|
||||
|
||||
module.exports = function handleMessage(action, payload) {
|
||||
switch (action) {
|
||||
case "GET_VERSION":
|
||||
return babel.version;
|
||||
case "GET_TYPES_INFO":
|
||||
return {
|
||||
FLOW_FLIPPED_ALIAS_KEYS: babel.types.FLIPPED_ALIAS_KEYS.Flow,
|
||||
VISITOR_KEYS: babel.types.VISITOR_KEYS,
|
||||
};
|
||||
case "GET_TOKEN_LABELS":
|
||||
return getTokLabels();
|
||||
case "GET_VISITOR_KEYS":
|
||||
return getVisitorKeys();
|
||||
case "MAYBE_PARSE":
|
||||
return normalizeBabelParseConfig(payload.options).then(options =>
|
||||
maybeParse(payload.code, options),
|
||||
);
|
||||
case "MAYBE_PARSE_SYNC":
|
||||
if (!process.env.BABEL_8_BREAKING) {
|
||||
return maybeParse(
|
||||
payload.code,
|
||||
normalizeBabelParseConfigSync(payload.options),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unknown internal parser worker action: ${action}`);
|
||||
};
|
||||
@ -1,43 +1,9 @@
|
||||
const babel = require("./babel-core.cjs");
|
||||
const maybeParse = require("./maybeParse.cjs");
|
||||
const { getVisitorKeys, getTokLabels } = require("./ast-info.cjs");
|
||||
const normalizeBabelParseConfig = require("./configuration.cjs");
|
||||
const handleMessage = require("./handle-message.cjs");
|
||||
|
||||
function handleMessage(action, payload) {
|
||||
switch (action) {
|
||||
case "GET_VERSION":
|
||||
return babel.version;
|
||||
case "GET_TYPES_INFO":
|
||||
return {
|
||||
FLOW_FLIPPED_ALIAS_KEYS: babel.types.FLIPPED_ALIAS_KEYS.Flow,
|
||||
VISITOR_KEYS: babel.types.VISITOR_KEYS,
|
||||
};
|
||||
case "GET_TOKEN_LABELS":
|
||||
return getTokLabels();
|
||||
case "GET_VISITOR_KEYS":
|
||||
return getVisitorKeys();
|
||||
case "MAYBE_PARSE":
|
||||
if (process.env.BABEL_8_BREAKING) {
|
||||
return normalizeBabelParseConfig(payload.options).then(options =>
|
||||
maybeParse(payload.code, options),
|
||||
);
|
||||
} else {
|
||||
return maybeParse(
|
||||
payload.code,
|
||||
normalizeBabelParseConfig(payload.options),
|
||||
);
|
||||
}
|
||||
}
|
||||
const { parentPort } = require("worker_threads");
|
||||
|
||||
throw new Error(`Unknown internal parser worker action: ${action}`);
|
||||
}
|
||||
|
||||
if (process.env.BABEL_8_BREAKING) {
|
||||
const { parentPort } = require("worker_threads");
|
||||
|
||||
parentPort.addListener(
|
||||
"message",
|
||||
async ({ signal, port, action, payload }) => {
|
||||
parentPort.addListener("message", async ({ signal, port, action, payload }) => {
|
||||
let response;
|
||||
|
||||
try {
|
||||
@ -59,8 +25,4 @@ if (process.env.BABEL_8_BREAKING) {
|
||||
Atomics.store(signal, 0, 1);
|
||||
Atomics.notify(signal, 0);
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
module.exports = handleMessage;
|
||||
}
|
||||
});
|
||||
|
||||
13
eslint/babel-eslint-tests/test/fixtures/mjs-config-file-babel-7/.eslintrc.js
vendored
Normal file
13
eslint/babel-eslint-tests/test/fixtures/mjs-config-file-babel-7/.eslintrc.js
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: "@babel/eslint-parser/experimental-worker",
|
||||
parserOptions: {
|
||||
babelOptions: {
|
||||
configFile: __dirname + "/babel.config.mjs",
|
||||
sourceType: "module",
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"template-curly-spacing": "error",
|
||||
},
|
||||
};
|
||||
1
eslint/babel-eslint-tests/test/fixtures/mjs-config-file-babel-7/a.js
vendored
Normal file
1
eslint/babel-eslint-tests/test/fixtures/mjs-config-file-babel-7/a.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default () => <div />;
|
||||
3
eslint/babel-eslint-tests/test/fixtures/mjs-config-file-babel-7/babel.config.mjs
vendored
Normal file
3
eslint/babel-eslint-tests/test/fixtures/mjs-config-file-babel-7/babel.config.mjs
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
presets: ["@babel/preset-react"],
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: "@babel/eslint-parser",
|
||||
parser: "@babel/eslint-parser/experimental-worker",
|
||||
parserOptions: {
|
||||
babelOptions: {
|
||||
configFile: __dirname + "/babel.config.mjs",
|
||||
|
||||
@ -16,4 +16,21 @@ describe("Babel config files", () => {
|
||||
]),
|
||||
).toMatchObject({ errorCount: 0 });
|
||||
});
|
||||
|
||||
const babel7node12 =
|
||||
process.env.BABEL_8_BREAKING || parseInt(process.versions.node) < 12
|
||||
? it.skip
|
||||
: it;
|
||||
|
||||
babel7node12("experimental worker works with babel.config.mjs", () => {
|
||||
const engine = new eslint.CLIEngine({ ignore: false });
|
||||
expect(
|
||||
engine.executeOnFiles([
|
||||
path.resolve(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
`../fixtures/mjs-config-file-babel-7/a.js`,
|
||||
),
|
||||
]),
|
||||
).toMatchObject({ errorCount: 0 });
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
const supportsESM = parseInt(process.versions.node) >= 12;
|
||||
|
||||
module.exports = {
|
||||
collectCoverageFrom: [
|
||||
"packages/*/src/**/*.{js,mjs,ts}",
|
||||
@ -40,6 +42,7 @@ module.exports = {
|
||||
"/test/__data__/",
|
||||
"<rootDir>/build/",
|
||||
],
|
||||
resolver: supportsESM ? "./test/jestExportsMapResolver.cjs" : null,
|
||||
// We don't need module name mappers here as depedencies of workspace
|
||||
// package should be declared explicitly in the package.json
|
||||
// Yarn will generate correct file links so that Jest can resolve correctly
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
"babel-plugin-transform-charcodes": "^0.2.0",
|
||||
"chalk": "^2.4.2",
|
||||
"charcodes": "^0.2.0",
|
||||
"enhanced-resolve": "^5.8.2",
|
||||
"eslint": "^7.27.0",
|
||||
"eslint-import-resolver-node": "^0.3.4",
|
||||
"eslint-plugin-flowtype": "^5.7.2",
|
||||
|
||||
@ -127,7 +127,7 @@ function writeHelperFile(
|
||||
buildHelper(runtimeName, pkgDirname, fullPath, helperName, { esm, corejs })
|
||||
);
|
||||
|
||||
return `./${filePath}`;
|
||||
return esm ? `./helpers/esm/${fileName}` : `./helpers/${fileName}`;
|
||||
}
|
||||
|
||||
function writeHelpers(runtimeName, { corejs } = {}) {
|
||||
@ -164,12 +164,13 @@ function writeHelpers(runtimeName, { corejs } = {}) {
|
||||
// - Node.js <13.2.0 will fail resolving the first array entry, and will
|
||||
// fallback to the second entry (the CJS file)
|
||||
// In Babel 8 we can simplify this.
|
||||
helperSubExports[`./${helperPath}`] = [
|
||||
helperSubExports[`./${path.posix.join("helpers", helperName)}`] = [
|
||||
{ node: cjs, import: esm, default: cjs },
|
||||
cjs,
|
||||
];
|
||||
// For backward compatibility. We can remove this in Babel 8.
|
||||
helperSubExports[`./${path.join("helpers", "esm", helperName)}`] = esm;
|
||||
helperSubExports[`./${path.posix.join("helpers", "esm", helperName)}`] =
|
||||
esm;
|
||||
}
|
||||
|
||||
writeHelperExports(runtimeName, helperSubExports);
|
||||
|
||||
11
test/jestExportsMapResolver.cjs
Normal file
11
test/jestExportsMapResolver.cjs
Normal file
@ -0,0 +1,11 @@
|
||||
// Temporary workaround for https://github.com/facebook/jest/issues/9771
|
||||
// Source: https://github.com/facebook/jest/issues/9771#issuecomment-841624042
|
||||
|
||||
const resolver = require("enhanced-resolve").create.sync({
|
||||
conditionNames: ["node", "require", "default"],
|
||||
extensions: [".js", ".json", ".node", ".ts"],
|
||||
});
|
||||
|
||||
module.exports = function (request, options) {
|
||||
return resolver(options.basedir, request);
|
||||
};
|
||||
@ -5749,6 +5749,7 @@ __metadata:
|
||||
babel-plugin-transform-charcodes: ^0.2.0
|
||||
chalk: ^2.4.2
|
||||
charcodes: ^0.2.0
|
||||
enhanced-resolve: ^5.8.2
|
||||
eslint: ^7.27.0
|
||||
eslint-import-resolver-node: ^0.3.4
|
||||
eslint-plugin-flowtype: ^5.7.2
|
||||
@ -7445,13 +7446,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"enhanced-resolve@npm:^5.7.0":
|
||||
version: 5.7.0
|
||||
resolution: "enhanced-resolve@npm:5.7.0"
|
||||
"enhanced-resolve@npm:^5.7.0, enhanced-resolve@npm:^5.8.2":
|
||||
version: 5.8.2
|
||||
resolution: "enhanced-resolve@npm:5.8.2"
|
||||
dependencies:
|
||||
graceful-fs: ^4.2.4
|
||||
tapable: ^2.2.0
|
||||
checksum: 545cfa659e9cdccf1240bccbbd1791db7ec589979d71b35df5aeaf872dd8d13fab379ad73fa960f4cb32963b85492792c0fb0866f484043740014824ae6088b9
|
||||
checksum: 1af3f6bcb92e849f6c18d44c427cbdaecac4be61023f2008d2ef0f8a48c909bf13afa9a5c04f9d030f27d9a7e27e40c367caa22cd63d2a7eb5fdbab7579d1538
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user