Skip to content

Commit

Permalink
Avoid importing .json files (#12759)
Browse files Browse the repository at this point in the history
* Avoid importing `.json` files

* Use ESold in babel.config.json

* Use `import/extensions` eslint plugin
  • Loading branch information
nicolo-ribaudo committed Feb 5, 2021
1 parent 87f264c commit e735266
Show file tree
Hide file tree
Showing 28 changed files with 101 additions and 42 deletions.
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
// 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

0 comments on commit e735266

Please sign in to comment.