Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid importing .json files #12759

Merged
merged 3 commits into from Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.cjs
Expand Up @@ -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: [
Expand All @@ -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" }],
},
},
{
Expand Down
1 change: 1 addition & 0 deletions .flowconfig
Expand Up @@ -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
Expand Down
53 changes: 51 additions & 2 deletions 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) {
Expand Down Expand Up @@ -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) },
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need to support old versions since 1) we are building on latest node 2) it is a compile-time macro?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"compile time" means also "on Node.js 6 inside babel-jest"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I thought we are replacing packageJson.field on the build step.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we also run Babel in jest (that's the reason why we cannot use babel.config.mjs)

// 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));
},
},
};
}
3 changes: 1 addition & 2 deletions eslint/babel-eslint-parser/src/index.js
Expand Up @@ -3,7 +3,6 @@ import {
version as babelCoreVersion,
parseSync as babelParse,
} from "@babel/core";
import packageJson from "../package.json";
import {
normalizeBabelParseConfig,
normalizeESLintConfig,
Expand All @@ -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}.`,
);
}

Expand Down
8 changes: 8 additions & 0 deletions lib/package-json.d.ts
@@ -0,0 +1,8 @@
// NOTE: This global .d.ts file can be included with
// /// <reference path="../../../lib/package-json.d.ts" />
// in .ts files using the PACKAGE_JSON macro.

declare const PACKAGE_JSON: {
name: string;
version: string;
};
4 changes: 4 additions & 0 deletions lib/package-json.js.flow
@@ -0,0 +1,4 @@
declare var PACKAGE_JSON: {
name: string;
version: string;
};
4 changes: 1 addition & 3 deletions packages/babel-cli/src/babel/options.js
Expand Up @@ -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]",
Expand Down Expand Up @@ -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] <files ...>");
// register an empty action handler so that commander.js can throw on
// unknown options _after_ args
Expand Down
3 changes: 2 additions & 1 deletion 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";
Expand Down
3 changes: 1 addition & 2 deletions packages/babel-helper-compilation-targets/src/index.js
Expand Up @@ -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 };
Expand All @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions 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;
Expand Down
Expand Up @@ -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({
Expand Down
Expand Up @@ -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";

Expand All @@ -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 = {} }) {
Expand Down
@@ -1,5 +1,5 @@
import * as t from "@babel/types";
import { willPathCastToBoolean } from "./util.js";
import { willPathCastToBoolean } from "./util";

class AssignmentMemoiser {
constructor() {
Expand Down
2 changes: 1 addition & 1 deletion 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;
Expand Down
4 changes: 1 addition & 3 deletions packages/babel-node/src/_babel-node.js
Expand Up @@ -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<string> {
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion packages/babel-parser/src/parser/error.js
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-parser/src/parser/expression.js
Expand Up @@ -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 {
Expand Down
@@ -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", () => {
Expand Down
6 changes: 4 additions & 2 deletions 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"];

Expand All @@ -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: {
Expand Down
Expand Up @@ -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;

Expand Down
@@ -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";
@@ -1,4 +1,4 @@
import createPlugin from "./create-plugin.js";
import createPlugin from "./create-plugin";

export default createPlugin({
name: "transform-react-jsx/development",
Expand Down
2 changes: 1 addition & 1 deletion 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",
Expand Down
5 changes: 2 additions & 3 deletions packages/babel-preset-env/src/normalize-options.js
@@ -1,13 +1,12 @@
// @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";
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,
Expand All @@ -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);

Expand Down
@@ -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 {
Expand Down
@@ -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";
Expand Down
2 changes: 1 addition & 1 deletion 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);
Expand Down