Skip to content

Commit e735266

Browse files
Avoid importing .json files (#12759)
* Avoid importing `.json` files * Use ESold in babel.config.json * Use `import/extensions` eslint plugin
1 parent 87f264c commit e735266

28 files changed

Lines changed: 101 additions & 42 deletions

File tree

.eslintrc.cjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ module.exports = {
4343
"@babel/development/no-undefined-identifier": "error",
4444
"@babel/development/no-deprecated-clone": "error",
4545
"guard-for-in": "error",
46+
"import/extensions": ["error", { json: "always", cjs: "always" }],
4647
},
48+
globals: { PACKAGE_JSON: "readonly" },
4749
},
4850
{
4951
files: [
@@ -63,6 +65,7 @@ module.exports = {
6365
"jest/no-standalone-expect": "off",
6466
"jest/no-test-callback": "off",
6567
"jest/valid-describe": "off",
68+
"import/extensions": ["error", { json: "always", cjs: "always" }],
6669
},
6770
},
6871
{

.flowconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lib/third-party-libs.js.flow
1717
lib/preset-modules.js.flow
1818
packages/babel-types/lib/index.js.flow
1919
lib/babel-packages.js.flow
20+
lib/package-json.js.flow
2021

2122
[options]
2223
include_warnings=true

babel.config.js

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"use strict";
22

3-
const path = require("path");
3+
const pathUtils = require("path");
4+
const fs = require("fs");
45

56
function normalize(src) {
6-
return src.replace(/\//, path.sep);
7+
return src.replace(/\//, pathUtils.sep);
78
}
89

910
module.exports = function (api) {
@@ -125,6 +126,8 @@ module.exports = function (api) {
125126
convertESM ? "@babel/proposal-export-namespace-from" : null,
126127
convertESM ? "@babel/transform-modules-commonjs" : null,
127128

129+
pluginPackageJsonMacro,
130+
128131
process.env.STRIP_BABEL_8_FLAG && [
129132
pluginToggleBabel8Breaking,
130133
{ breaking: bool(process.env.BABEL_8_BREAKING) },
@@ -319,3 +322,49 @@ function pluginToggleBabel8Breaking({ types: t }, { breaking }) {
319322
},
320323
};
321324
}
325+
326+
function pluginPackageJsonMacro({ types: t }) {
327+
const fnName = "PACKAGE_JSON";
328+
329+
return {
330+
visitor: {
331+
ReferencedIdentifier(path) {
332+
if (path.isIdentifier({ name: fnName })) {
333+
throw path.buildCodeFrameError(
334+
`"${fnName}" is only supported in member expressions.`
335+
);
336+
}
337+
},
338+
MemberExpression(path) {
339+
if (!path.get("object").isIdentifier({ name: fnName })) return;
340+
341+
if (path.node.computed) {
342+
throw path.buildCodeFrameError(
343+
`"${fnName}" does not support computed properties.`
344+
);
345+
}
346+
const field = path.node.property.name;
347+
348+
// TODO: When dropping old Node.js versions, use require.resolve
349+
// instead of looping through the folders hierarchy
350+
351+
let pkg;
352+
for (let dir = pathUtils.dirname(this.filename); ; ) {
353+
try {
354+
pkg = fs.readFileSync(pathUtils.join(dir, "package.json"), "utf8");
355+
break;
356+
} catch (_) {}
357+
358+
const prev = dir;
359+
dir = pathUtils.resolve(dir, "..");
360+
361+
// We are in the root and didn't find a package.json file
362+
if (dir === prev) return;
363+
}
364+
365+
const value = JSON.parse(pkg)[field];
366+
path.replaceWith(t.valueToNode(value));
367+
},
368+
},
369+
};
370+
}

eslint/babel-eslint-parser/src/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
version as babelCoreVersion,
44
parseSync as babelParse,
55
} from "@babel/core";
6-
import packageJson from "../package.json";
76
import {
87
normalizeBabelParseConfig,
98
normalizeESLintConfig,
@@ -27,7 +26,7 @@ function baseParse(code, options) {
2726

2827
if (!isRunningMinSupportedCoreVersion) {
2928
throw new Error(
30-
`@babel/eslint-parser@${packageJson.version} does not support @babel/core@${babelCoreVersion}. Please upgrade to @babel/core@${minSupportedCoreVersion}.`,
29+
`@babel/eslint-parser@${PACKAGE_JSON.version} does not support @babel/core@${babelCoreVersion}. Please upgrade to @babel/core@${minSupportedCoreVersion}.`,
3130
);
3231
}
3332

lib/package-json.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// NOTE: This global .d.ts file can be included with
2+
// /// <reference path="../../../lib/package-json.d.ts" />
3+
// in .ts files using the PACKAGE_JSON macro.
4+
5+
declare const PACKAGE_JSON: {
6+
name: string;
7+
version: string;
8+
};

lib/package-json.js.flow

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare var PACKAGE_JSON: {
2+
name: string;
3+
version: string;
4+
};

packages/babel-cli/src/babel/options.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import commander from "commander";
66
import { version } from "@babel/core";
77
import glob from "glob";
88

9-
import pkg from "../../package.json";
10-
119
// Standard Babel input configs.
1210
commander.option(
1311
"-f, --filename [filename]",
@@ -170,7 +168,7 @@ commander.option(
170168
"Use a specific extension for the output files",
171169
);
172170

173-
commander.version(pkg.version + " (@babel/core " + version + ")");
171+
commander.version(PACKAGE_JSON.version + " (@babel/core " + version + ")");
174172
commander.usage("[options] <files ...>");
175173
// register an empty action handler so that commander.js can throw on
176174
// unknown options _after_ args

packages/babel-core/src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// @flow
22

3+
export const version = PACKAGE_JSON.version;
4+
35
export { default as File } from "./transformation/file/file";
46
export { default as buildExternalHelpers } from "./tools/build-external-helpers";
57
export { resolvePlugin, resolvePreset } from "./config/files";
68

7-
export { version } from "../package.json";
89
export { getEnv } from "./config/helpers/environment";
910

1011
export * as types from "@babel/types";

packages/babel-helper-compilation-targets/src/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
import { OptionValidator } from "@babel/helper-validator-option";
1414
import { browserNameMap } from "./targets";
1515
import { TargetNames } from "./options";
16-
import { name as packageName } from "../package.json";
1716
import type { Targets, InputTargets, Browsers, TargetsTuple } from "./types";
1817

1918
export type { Targets, InputTargets };
@@ -23,7 +22,7 @@ export { getInclusionReasons } from "./debug";
2322
export { default as filterItems, isRequired } from "./filter-items";
2423
export { unreleasedLabels } from "./targets";
2524

26-
const v = new OptionValidator(packageName);
25+
const v = new OptionValidator(PACKAGE_JSON.name);
2726
const browserslistDefaults = browserslist.defaults;
2827

2928
function validateTargetNames(targets: Targets): TargetsTuple {

packages/babel-helper-compilation-targets/src/utils.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
// @flow
22
import semver from "semver";
33
import { OptionValidator } from "@babel/helper-validator-option";
4-
import { name as packageName } from "../package.json";
54
import { unreleasedLabels } from "./targets";
65
import type { Target, Targets } from "./types";
76

87
const versionRegExp = /^(\d+|\d+.\d+)$/;
98

10-
const v = new OptionValidator(packageName);
9+
const v = new OptionValidator(PACKAGE_JSON.name);
1110

1211
export function semverMin(first: ?string, second: string): string {
1312
return first && semver.lt(first, second) ? first : second;

0 commit comments

Comments
 (0)