diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index fd932b93fb..a121f4e265 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -43,7 +43,9 @@ module.exports = {
"@babel/development/no-undefined-identifier": "error",
"@babel/development/no-deprecated-clone": "error",
"guard-for-in": "error",
+ "import/extensions": ["error", { json: "always", cjs: "always" }],
},
+ globals: { PACKAGE_JSON: "readonly" },
},
{
files: [
@@ -63,6 +65,7 @@ module.exports = {
"jest/no-standalone-expect": "off",
"jest/no-test-callback": "off",
"jest/valid-describe": "off",
+ "import/extensions": ["error", { json: "always", cjs: "always" }],
},
},
{
diff --git a/.flowconfig b/.flowconfig
index 11ea40a036..3180c265db 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -17,6 +17,7 @@ lib/third-party-libs.js.flow
lib/preset-modules.js.flow
packages/babel-types/lib/index.js.flow
lib/babel-packages.js.flow
+lib/package-json.js.flow
[options]
include_warnings=true
diff --git a/babel.config.js b/babel.config.js
index ee0d89b628..1a8b029708 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,9 +1,10 @@
"use strict";
-const path = require("path");
+const pathUtils = require("path");
+const fs = require("fs");
function normalize(src) {
- return src.replace(/\//, path.sep);
+ return src.replace(/\//, pathUtils.sep);
}
module.exports = function (api) {
@@ -125,6 +126,8 @@ module.exports = function (api) {
convertESM ? "@babel/proposal-export-namespace-from" : null,
convertESM ? "@babel/transform-modules-commonjs" : null,
+ pluginPackageJsonMacro,
+
process.env.STRIP_BABEL_8_FLAG && [
pluginToggleBabel8Breaking,
{ breaking: bool(process.env.BABEL_8_BREAKING) },
@@ -319,3 +322,49 @@ function pluginToggleBabel8Breaking({ types: t }, { breaking }) {
},
};
}
+
+function pluginPackageJsonMacro({ types: t }) {
+ const fnName = "PACKAGE_JSON";
+
+ return {
+ visitor: {
+ ReferencedIdentifier(path) {
+ if (path.isIdentifier({ name: fnName })) {
+ throw path.buildCodeFrameError(
+ `"${fnName}" is only supported in member expressions.`
+ );
+ }
+ },
+ MemberExpression(path) {
+ if (!path.get("object").isIdentifier({ name: fnName })) return;
+
+ if (path.node.computed) {
+ throw path.buildCodeFrameError(
+ `"${fnName}" does not support computed properties.`
+ );
+ }
+ const field = path.node.property.name;
+
+ // TODO: When dropping old Node.js versions, use require.resolve
+ // instead of looping through the folders hierarchy
+
+ let pkg;
+ for (let dir = pathUtils.dirname(this.filename); ; ) {
+ try {
+ pkg = fs.readFileSync(pathUtils.join(dir, "package.json"), "utf8");
+ break;
+ } catch (_) {}
+
+ const prev = dir;
+ dir = pathUtils.resolve(dir, "..");
+
+ // We are in the root and didn't find a package.json file
+ if (dir === prev) return;
+ }
+
+ const value = JSON.parse(pkg)[field];
+ path.replaceWith(t.valueToNode(value));
+ },
+ },
+ };
+}
diff --git a/eslint/babel-eslint-parser/src/index.js b/eslint/babel-eslint-parser/src/index.js
index e4be37d822..709232c269 100644
--- a/eslint/babel-eslint-parser/src/index.js
+++ b/eslint/babel-eslint-parser/src/index.js
@@ -3,7 +3,6 @@ import {
version as babelCoreVersion,
parseSync as babelParse,
} from "@babel/core";
-import packageJson from "../package.json";
import {
normalizeBabelParseConfig,
normalizeESLintConfig,
@@ -27,7 +26,7 @@ function baseParse(code, options) {
if (!isRunningMinSupportedCoreVersion) {
throw new Error(
- `@babel/eslint-parser@${packageJson.version} does not support @babel/core@${babelCoreVersion}. Please upgrade to @babel/core@${minSupportedCoreVersion}.`,
+ `@babel/eslint-parser@${PACKAGE_JSON.version} does not support @babel/core@${babelCoreVersion}. Please upgrade to @babel/core@${minSupportedCoreVersion}.`,
);
}
diff --git a/lib/package-json.d.ts b/lib/package-json.d.ts
new file mode 100644
index 0000000000..6e82c0f5a3
--- /dev/null
+++ b/lib/package-json.d.ts
@@ -0,0 +1,8 @@
+// NOTE: This global .d.ts file can be included with
+// ///
+// in .ts files using the PACKAGE_JSON macro.
+
+declare const PACKAGE_JSON: {
+ name: string;
+ version: string;
+};
diff --git a/lib/package-json.js.flow b/lib/package-json.js.flow
new file mode 100644
index 0000000000..71a1659669
--- /dev/null
+++ b/lib/package-json.js.flow
@@ -0,0 +1,4 @@
+declare var PACKAGE_JSON: {
+ name: string;
+ version: string;
+};
diff --git a/packages/babel-cli/src/babel/options.js b/packages/babel-cli/src/babel/options.js
index 0aa54b3ef6..fe23788dd0 100644
--- a/packages/babel-cli/src/babel/options.js
+++ b/packages/babel-cli/src/babel/options.js
@@ -6,8 +6,6 @@ import commander from "commander";
import { version } from "@babel/core";
import glob from "glob";
-import pkg from "../../package.json";
-
// Standard Babel input configs.
commander.option(
"-f, --filename [filename]",
@@ -170,7 +168,7 @@ commander.option(
"Use a specific extension for the output files",
);
-commander.version(pkg.version + " (@babel/core " + version + ")");
+commander.version(PACKAGE_JSON.version + " (@babel/core " + version + ")");
commander.usage("[options] ");
// register an empty action handler so that commander.js can throw on
// unknown options _after_ args
diff --git a/packages/babel-core/src/index.js b/packages/babel-core/src/index.js
index 23d023b5ca..b5ce0fd680 100644
--- a/packages/babel-core/src/index.js
+++ b/packages/babel-core/src/index.js
@@ -1,10 +1,11 @@
// @flow
+export const version = PACKAGE_JSON.version;
+
export { default as File } from "./transformation/file/file";
export { default as buildExternalHelpers } from "./tools/build-external-helpers";
export { resolvePlugin, resolvePreset } from "./config/files";
-export { version } from "../package.json";
export { getEnv } from "./config/helpers/environment";
export * as types from "@babel/types";
diff --git a/packages/babel-helper-compilation-targets/src/index.js b/packages/babel-helper-compilation-targets/src/index.js
index 4fff39876f..e488ea3eec 100644
--- a/packages/babel-helper-compilation-targets/src/index.js
+++ b/packages/babel-helper-compilation-targets/src/index.js
@@ -13,7 +13,6 @@ import {
import { OptionValidator } from "@babel/helper-validator-option";
import { browserNameMap } from "./targets";
import { TargetNames } from "./options";
-import { name as packageName } from "../package.json";
import type { Targets, InputTargets, Browsers, TargetsTuple } from "./types";
export type { Targets, InputTargets };
@@ -23,7 +22,7 @@ export { getInclusionReasons } from "./debug";
export { default as filterItems, isRequired } from "./filter-items";
export { unreleasedLabels } from "./targets";
-const v = new OptionValidator(packageName);
+const v = new OptionValidator(PACKAGE_JSON.name);
const browserslistDefaults = browserslist.defaults;
function validateTargetNames(targets: Targets): TargetsTuple {
diff --git a/packages/babel-helper-compilation-targets/src/utils.js b/packages/babel-helper-compilation-targets/src/utils.js
index 96c6075318..80fda8315f 100644
--- a/packages/babel-helper-compilation-targets/src/utils.js
+++ b/packages/babel-helper-compilation-targets/src/utils.js
@@ -1,13 +1,12 @@
// @flow
import semver from "semver";
import { OptionValidator } from "@babel/helper-validator-option";
-import { name as packageName } from "../package.json";
import { unreleasedLabels } from "./targets";
import type { Target, Targets } from "./types";
const versionRegExp = /^(\d+|\d+.\d+)$/;
-const v = new OptionValidator(packageName);
+const v = new OptionValidator(PACKAGE_JSON.name);
export function semverMin(first: ?string, second: string): string {
return first && semver.lt(first, second) ? first : second;
diff --git a/packages/babel-helper-create-class-features-plugin/src/index.js b/packages/babel-helper-create-class-features-plugin/src/index.js
index fef48ee705..66cfb83fb0 100644
--- a/packages/babel-helper-create-class-features-plugin/src/index.js
+++ b/packages/babel-helper-create-class-features-plugin/src/index.js
@@ -20,15 +20,15 @@ import {
isLoose,
} from "./features";
-import pkg from "../package.json";
-
export { FEATURES, injectInitialization };
// Note: Versions are represented as an integer. e.g. 7.1.5 is represented
// as 70000100005. This method is easier than using a semver-parsing
// package, but it breaks if we release x.y.z where x, y or z are
// greater than 99_999.
-const version = pkg.version.split(".").reduce((v, x) => v * 1e5 + +x, 0);
+const version = PACKAGE_JSON.version
+ .split(".")
+ .reduce((v, x) => v * 1e5 + +x, 0);
const versionKey = "@babel/plugin-class-features/version";
export function createClassFeaturePlugin({
diff --git a/packages/babel-helper-create-regexp-features-plugin/src/index.js b/packages/babel-helper-create-regexp-features-plugin/src/index.js
index 7c9e5802d1..c48f200988 100644
--- a/packages/babel-helper-create-regexp-features-plugin/src/index.js
+++ b/packages/babel-helper-create-regexp-features-plugin/src/index.js
@@ -8,7 +8,6 @@ import {
} from "./features";
import { generateRegexpuOptions } from "./util";
-import pkg from "../package.json";
import { types as t } from "@babel/core";
import annotateAsPure from "@babel/helper-annotate-as-pure";
@@ -29,7 +28,9 @@ function pullFlag(node, flag: RegExpFlags): void {
// as 70000100005. This method is easier than using a semver-parsing
// package, but it breaks if we release x.y.z where x, y or z are
// greater than 99_999.
-const version = pkg.version.split(".").reduce((v, x) => v * 1e5 + +x, 0);
+const version = PACKAGE_JSON.version
+ .split(".")
+ .reduce((v, x) => v * 1e5 + +x, 0);
const versionKey = "@babel/plugin-regexp-features/version";
export function createRegExpFeaturePlugin({ name, feature, options = {} }) {
diff --git a/packages/babel-helper-member-expression-to-functions/src/index.js b/packages/babel-helper-member-expression-to-functions/src/index.js
index 71c81bb024..f9f3ba723d 100644
--- a/packages/babel-helper-member-expression-to-functions/src/index.js
+++ b/packages/babel-helper-member-expression-to-functions/src/index.js
@@ -1,5 +1,5 @@
import * as t from "@babel/types";
-import { willPathCastToBoolean } from "./util.js";
+import { willPathCastToBoolean } from "./util";
class AssignmentMemoiser {
constructor() {
diff --git a/packages/babel-helper-validator-option/src/validator.ts b/packages/babel-helper-validator-option/src/validator.ts
index eff7165bfb..f698df93c7 100644
--- a/packages/babel-helper-validator-option/src/validator.ts
+++ b/packages/babel-helper-validator-option/src/validator.ts
@@ -1,4 +1,4 @@
-import { findSuggestion } from "./find-suggestion.js";
+import { findSuggestion } from "./find-suggestion";
export class OptionValidator {
declare descriptor: string;
diff --git a/packages/babel-node/src/_babel-node.js b/packages/babel-node/src/_babel-node.js
index cb7a04e93f..405f656ce5 100644
--- a/packages/babel-node/src/_babel-node.js
+++ b/packages/babel-node/src/_babel-node.js
@@ -9,8 +9,6 @@ import "core-js/stable";
import "regenerator-runtime/runtime";
import register from "@babel/register";
-import pkg from "../package.json";
-
const program = new commander.Command("babel-node");
function collect(value, previousValue): Array {
@@ -61,7 +59,7 @@ program.option(
program.option("-w, --plugins [string]", "", collect);
program.option("-b, --presets [string]", "", collect);
-program.version(pkg.version);
+program.version(PACKAGE_JSON.version);
program.usage("[options] [ -e script | script.js ] [arguments]");
program.parse(process.argv);
diff --git a/packages/babel-parser/src/parser/error.js b/packages/babel-parser/src/parser/error.js
index eea9610307..0de72f4910 100644
--- a/packages/babel-parser/src/parser/error.js
+++ b/packages/babel-parser/src/parser/error.js
@@ -18,7 +18,7 @@ type ErrorContext = {
export type ParsingError = SyntaxError & ErrorContext;
-export { ErrorMessages as Errors } from "./error-message.js";
+export { ErrorMessages as Errors } from "./error-message";
export default class ParserError extends CommentsParser {
// Forward-declaration: defined in tokenizer/index.js
diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js
index 861ddfc14c..3c52a4f229 100644
--- a/packages/babel-parser/src/parser/expression.js
+++ b/packages/babel-parser/src/parser/expression.js
@@ -53,7 +53,7 @@ import {
newArrowHeadScope,
newAsyncArrowScope,
newExpressionScope,
-} from "../util/expression-scope.js";
+} from "../util/expression-scope";
import { Errors } from "./error";
export default class ExpressionParser extends LValParser {
diff --git a/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js b/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js
index 675e970382..d32d3ffe93 100644
--- a/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js
+++ b/packages/babel-plugin-proposal-class-static-block/test/plugin-ordering.test.js
@@ -1,5 +1,5 @@
import * as babel from "@babel/core";
-import proposalClassStaticBlock from "../lib/index.js";
+import proposalClassStaticBlock from "..";
describe("plugin ordering", () => {
it("should throw when @babel/plugin-proposal-class-static-block is after class features plugin", () => {
diff --git a/packages/babel-plugin-proposal-dynamic-import/src/index.js b/packages/babel-plugin-proposal-dynamic-import/src/index.js
index 9482e24514..4d50fcfac3 100644
--- a/packages/babel-plugin-proposal-dynamic-import/src/index.js
+++ b/packages/babel-plugin-proposal-dynamic-import/src/index.js
@@ -1,6 +1,5 @@
import { declare } from "@babel/helper-plugin-utils";
import syntaxDynamicImport from "@babel/plugin-syntax-dynamic-import";
-import { version } from "../package.json";
const SUPPORTED_MODULES = ["commonjs", "amd", "systemjs"];
@@ -25,7 +24,10 @@ export default declare(api => {
inherits: syntaxDynamicImport,
pre() {
- this.file.set("@babel/plugin-proposal-dynamic-import", version);
+ this.file.set(
+ "@babel/plugin-proposal-dynamic-import",
+ PACKAGE_JSON.version,
+ );
},
visitor: {
diff --git a/packages/babel-plugin-proposal-optional-chaining/src/index.js b/packages/babel-plugin-proposal-optional-chaining/src/index.js
index c25d95d7f9..052c71b6f0 100644
--- a/packages/babel-plugin-proposal-optional-chaining/src/index.js
+++ b/packages/babel-plugin-proposal-optional-chaining/src/index.js
@@ -5,10 +5,7 @@ import {
} from "@babel/helper-skip-transparent-expression-wrappers";
import syntaxOptionalChaining from "@babel/plugin-syntax-optional-chaining";
import { types as t, template } from "@babel/core";
-import {
- willPathCastToBoolean,
- findOutermostTransparentParent,
-} from "./util.js";
+import { willPathCastToBoolean, findOutermostTransparentParent } from "./util";
const { ast } = template.expression;
diff --git a/packages/babel-plugin-transform-react-jsx-development/src/index.js b/packages/babel-plugin-transform-react-jsx-development/src/index.js
index 5273b9f25d..f0418c2957 100644
--- a/packages/babel-plugin-transform-react-jsx-development/src/index.js
+++ b/packages/babel-plugin-transform-react-jsx-development/src/index.js
@@ -1,3 +1,3 @@
/* eslint-disable @babel/development/plugin-name */
-export { default } from "@babel/plugin-transform-react-jsx/lib/development.js";
+export { default } from "@babel/plugin-transform-react-jsx/lib/development";
diff --git a/packages/babel-plugin-transform-react-jsx/src/development.js b/packages/babel-plugin-transform-react-jsx/src/development.js
index 4de15f885d..a1582db7f1 100644
--- a/packages/babel-plugin-transform-react-jsx/src/development.js
+++ b/packages/babel-plugin-transform-react-jsx/src/development.js
@@ -1,4 +1,4 @@
-import createPlugin from "./create-plugin.js";
+import createPlugin from "./create-plugin";
export default createPlugin({
name: "transform-react-jsx/development",
diff --git a/packages/babel-plugin-transform-react-jsx/src/index.js b/packages/babel-plugin-transform-react-jsx/src/index.js
index 8b83306d99..5e040d067f 100644
--- a/packages/babel-plugin-transform-react-jsx/src/index.js
+++ b/packages/babel-plugin-transform-react-jsx/src/index.js
@@ -1,6 +1,6 @@
/* eslint-disable @babel/development/plugin-name */
-import createPlugin from "./create-plugin.js";
+import createPlugin from "./create-plugin";
export default createPlugin({
name: "transform-react-jsx",
diff --git a/packages/babel-preset-env/src/normalize-options.js b/packages/babel-preset-env/src/normalize-options.js
index 417353bc4c..1f1086ab57 100644
--- a/packages/babel-preset-env/src/normalize-options.js
+++ b/packages/babel-preset-env/src/normalize-options.js
@@ -1,5 +1,5 @@
// @flow
-import corejs3Polyfills from "core-js-compat/data";
+import corejs3Polyfills from "core-js-compat/data.json";
import { coerce, SemVer } from "semver";
import corejs2Polyfills from "@babel/compat-data/corejs2-built-ins";
import { plugins as pluginsList } from "./plugins-compat-data";
@@ -7,7 +7,6 @@ import moduleTransformations from "./module-transformations";
import { TopLevelOptions, ModulesOption, UseBuiltInsOption } from "./options";
import { OptionValidator } from "@babel/helper-validator-option";
import { defaultWebIncludes } from "./polyfills/corejs2/get-platform-specific-default";
-import { name as packageName } from "../package.json";
import type {
BuiltInsOption,
@@ -18,7 +17,7 @@ import type {
PluginListOption,
} from "./types";
-const v = new OptionValidator(packageName);
+const v = new OptionValidator(PACKAGE_JSON.name);
const allPluginsList = Object.keys(pluginsList);
diff --git a/packages/babel-preset-env/src/polyfills/corejs3/entry-plugin.js b/packages/babel-preset-env/src/polyfills/corejs3/entry-plugin.js
index caa8de4cff..7ded2949e1 100644
--- a/packages/babel-preset-env/src/polyfills/corejs3/entry-plugin.js
+++ b/packages/babel-preset-env/src/polyfills/corejs3/entry-plugin.js
@@ -1,7 +1,7 @@
// @flow
-import corejs3Polyfills from "core-js-compat/data";
-import corejsEntries from "core-js-compat/entries";
+import corejs3Polyfills from "core-js-compat/data.json";
+import corejsEntries from "core-js-compat/entries.json";
import getModulesListForTargetVersion from "core-js-compat/get-modules-list-for-target-version";
import { filterItems } from "@babel/helper-compilation-targets";
import {
diff --git a/packages/babel-preset-env/src/polyfills/corejs3/usage-plugin.js b/packages/babel-preset-env/src/polyfills/corejs3/usage-plugin.js
index 0cd423af19..22627a4d4e 100644
--- a/packages/babel-preset-env/src/polyfills/corejs3/usage-plugin.js
+++ b/packages/babel-preset-env/src/polyfills/corejs3/usage-plugin.js
@@ -1,6 +1,6 @@
// @flow
-import corejs3Polyfills from "core-js-compat/data";
+import corejs3Polyfills from "core-js-compat/data.json";
import corejs3ShippedProposalsList from "@babel/compat-data/corejs3-shipped-proposals";
import getModulesListForTargetVersion from "core-js-compat/get-modules-list-for-target-version";
import { filterItems } from "@babel/helper-compilation-targets";
diff --git a/packages/babel-preset-typescript/src/index.js b/packages/babel-preset-typescript/src/index.js
index 099fc24757..94534d0473 100644
--- a/packages/babel-preset-typescript/src/index.js
+++ b/packages/babel-preset-typescript/src/index.js
@@ -1,6 +1,6 @@
import { declare } from "@babel/helper-plugin-utils";
import transformTypeScript from "@babel/plugin-transform-typescript";
-import normalizeOptions from "./normalize-options.js";
+import normalizeOptions from "./normalize-options";
export default declare((api, opts) => {
api.assertVersion(7);
diff --git a/scripts/rollup-plugin-babel-source.js b/scripts/rollup-plugin-babel-source.js
index 5f4fbc49a7..522dfd9789 100644
--- a/scripts/rollup-plugin-babel-source.js
+++ b/scripts/rollup-plugin-babel-source.js
@@ -88,13 +88,14 @@ export default function () {
? packageJson["browser"]
: packageJson["main"];
- const asJS = path.normalize(
+ let asJS = path.normalize(
path.join(
packageFolder,
// replace lib with src in the package.json entry
filename.replace(/^(\.\/)?lib\//, "src/")
)
);
+ if (!/\.[a-z]+$/.test(asJS)) asJS += ".js";
const asTS = asJS.replace(/\.js$/, ".ts");
try {