Handling babylon parsing errors in a better way (#6961)
* Handling babylon parsing errors in a better way * Better error messages + Helpful URLs * Replaced message from babylon completely * Add importMeta plugin to the map
This commit is contained in:
committed by
Henry Zhu
parent
56638e1370
commit
17b37b5013
@@ -6,6 +6,7 @@ import convertSourceMap, { typeof Converter } from "convert-source-map";
|
||||
import { parse } from "babylon";
|
||||
import { codeFrameColumns } from "@babel/code-frame";
|
||||
import File from "./file/file";
|
||||
import generateMissingPluginMessage from "./util/missing-plugin-helper";
|
||||
|
||||
const shebangRegex = /^#!.*/;
|
||||
|
||||
@@ -88,21 +89,27 @@ function parser(pluginPasses, options, code) {
|
||||
}
|
||||
throw new Error("More than one plugin attempted to override parsing.");
|
||||
} catch (err) {
|
||||
const loc = err.loc;
|
||||
const { loc, missingPlugin } = err;
|
||||
if (loc) {
|
||||
err.loc = null;
|
||||
err.message =
|
||||
`${options.filename || "unknown"}: ${err.message}\n` +
|
||||
codeFrameColumns(
|
||||
code,
|
||||
{
|
||||
start: {
|
||||
line: loc.line,
|
||||
column: loc.column + 1,
|
||||
},
|
||||
const codeFrame = codeFrameColumns(
|
||||
code,
|
||||
{
|
||||
start: {
|
||||
line: loc.line,
|
||||
column: loc.column + 1,
|
||||
},
|
||||
options,
|
||||
);
|
||||
},
|
||||
options,
|
||||
);
|
||||
if (missingPlugin) {
|
||||
err.message =
|
||||
`${options.filename || "unknown"}: ` +
|
||||
generateMissingPluginMessage(missingPlugin[0], loc, codeFrame);
|
||||
} else {
|
||||
err.message =
|
||||
`${options.filename || "unknown"}: ${err.message}\n\n` + codeFrame;
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
// @flow
|
||||
|
||||
const pluginNameMap = {
|
||||
asyncGenerators: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-async-generators",
|
||||
url: "https://git.io/vb4SY",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-async-generator-functions",
|
||||
url: "https://git.io/vb4yp",
|
||||
},
|
||||
},
|
||||
classProperties: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-class-properties",
|
||||
url: "https://git.io/vb4yQ",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-class-properties",
|
||||
url: "https://git.io/vb4SL",
|
||||
},
|
||||
},
|
||||
decorators: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-decorators",
|
||||
url: "https://git.io/vb4y9",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-decorators",
|
||||
url: "https://git.io/vb4ST",
|
||||
},
|
||||
},
|
||||
doExpressions: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-do-expressions",
|
||||
url: "https://git.io/vb4yh",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-do-expressions",
|
||||
url: "https://git.io/vb4S3",
|
||||
},
|
||||
},
|
||||
dynamicImport: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-dynamic-import",
|
||||
url: "https://git.io/vb4Sv",
|
||||
},
|
||||
},
|
||||
exportDefaultFrom: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-export-default-from",
|
||||
url: "https://git.io/vb4SO",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-export-default-from",
|
||||
url: "https://git.io/vb4yH",
|
||||
},
|
||||
},
|
||||
exportNamespaceFrom: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-export-namespace-from",
|
||||
url: "https://git.io/vb4Sf",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-export-namespace-from",
|
||||
url: "https://git.io/vb4SG",
|
||||
},
|
||||
},
|
||||
flow: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-flow",
|
||||
url: "https://git.io/vb4yb",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-transform-flow-strip-types",
|
||||
url: "https://git.io/vb49g",
|
||||
},
|
||||
},
|
||||
functionBind: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-function-bind",
|
||||
url: "https://git.io/vb4y7",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-function-bind",
|
||||
url: "https://git.io/vb4St",
|
||||
},
|
||||
},
|
||||
functionSent: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-function-sent",
|
||||
url: "https://git.io/vb4yN",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-function-sent",
|
||||
url: "https://git.io/vb4SZ",
|
||||
},
|
||||
},
|
||||
importMeta: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-import-meta",
|
||||
url: "https://git.io/vbKK6",
|
||||
},
|
||||
},
|
||||
jsx: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-jsx",
|
||||
url: "https://git.io/vb4yA",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-transform-react-jsx",
|
||||
url: "https://git.io/vb4yd",
|
||||
},
|
||||
},
|
||||
nullishCoalescingOperator: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-nullish-coalescing-operator",
|
||||
url: "https://git.io/vb4yx",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
url: "https://git.io/vb4Se",
|
||||
},
|
||||
},
|
||||
numericSeparator: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-numeric-separator",
|
||||
url: "https://git.io/vb4Sq",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-numeric-separator",
|
||||
url: "https://git.io/vb4yS",
|
||||
},
|
||||
},
|
||||
objectRestSpread: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-object-rest-spread",
|
||||
url: "https://git.io/vb4y5",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-object-rest-spread",
|
||||
url: "https://git.io/vb4Ss",
|
||||
},
|
||||
},
|
||||
optionalCatchBinding: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-optional-catch-binding",
|
||||
url: "https://git.io/vb4Sn",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-optional-catch-binding",
|
||||
url: "https://git.io/vb4SI",
|
||||
},
|
||||
},
|
||||
optionalChaining: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-optional-chaining",
|
||||
url: "https://git.io/vb4Sc",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-optional-chaining",
|
||||
url: "https://git.io/vb4Sk",
|
||||
},
|
||||
},
|
||||
pipelineOperator: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-pipeline-operator",
|
||||
url: "https://git.io/vb4yj",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-pipeline-operator",
|
||||
url: "https://git.io/vb4SU",
|
||||
},
|
||||
},
|
||||
throwExpressions: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-throw-expressions",
|
||||
url: "https://git.io/vb4SJ",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-throw-expressions",
|
||||
url: "https://git.io/vb4yF",
|
||||
},
|
||||
},
|
||||
typescript: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-typescript",
|
||||
url: "https://git.io/vb4SC",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-transform-typescript",
|
||||
url: "https://git.io/vb4Sm",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const getNameURLCombination = ({ name, url }) => `${name} (${url})`;
|
||||
|
||||
/*
|
||||
Returns a string of the format:
|
||||
Support for the experimental syntax [babylon plugin name] isn't currently enabled ([loc]):
|
||||
|
||||
[code frame]
|
||||
|
||||
Add [npm package name] ([url]) to the 'plugins' section of your Babel config
|
||||
to enable [parsing|transformation].
|
||||
*/
|
||||
export default function generateMissingPluginMessage(
|
||||
missingPluginName: string,
|
||||
loc,
|
||||
codeFrame,
|
||||
): string {
|
||||
let helpMessage =
|
||||
`Support for the experimental syntax '${missingPluginName}' isn't currently enabled ` +
|
||||
`(${loc.line}:${loc.column + 1}):\n\n` +
|
||||
codeFrame;
|
||||
const pluginInfo = pluginNameMap[missingPluginName];
|
||||
if (pluginInfo) {
|
||||
const { syntax: syntaxPlugin, transform: transformPlugin } = pluginInfo;
|
||||
if (syntaxPlugin) {
|
||||
if (transformPlugin) {
|
||||
const transformPluginInfo = getNameURLCombination(transformPlugin);
|
||||
helpMessage +=
|
||||
`\n\nAdd ${transformPluginInfo} to the 'plugins' section of your Babel config ` +
|
||||
`to enable transformation.`;
|
||||
} else {
|
||||
const syntaxPluginInfo = getNameURLCombination(syntaxPlugin);
|
||||
helpMessage +=
|
||||
`\n\nAdd ${syntaxPluginInfo} to the 'plugins' section of your Babel config ` +
|
||||
`to enable parsing.`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return helpMessage;
|
||||
}
|
||||
@@ -599,4 +599,52 @@ describe("api", function() {
|
||||
assert.ok(script.indexOf("typeof") >= 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("handle parsing errors", function() {
|
||||
const options = {
|
||||
babelrc: false,
|
||||
};
|
||||
|
||||
it("only syntax plugin available", function(done) {
|
||||
babel.transformFile(
|
||||
__dirname + "/fixtures/api/parsing-errors/only-syntax/file.js",
|
||||
options,
|
||||
function(err) {
|
||||
assert.ok(
|
||||
RegExp(
|
||||
"Support for the experimental syntax 'dynamicImport' isn't currently enabled \\(1:9\\):",
|
||||
).exec(err.message),
|
||||
);
|
||||
assert.ok(
|
||||
RegExp(
|
||||
"Add @babel/plugin-syntax-dynamic-import \\(https://git.io/vb4Sv\\) to the " +
|
||||
"'plugins' section of your Babel config to enable parsing.",
|
||||
).exec(err.message),
|
||||
);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("both syntax and transform plugin available", function(done) {
|
||||
babel.transformFile(
|
||||
__dirname + "/fixtures/api/parsing-errors/syntax-and-transform/file.js",
|
||||
options,
|
||||
function(err) {
|
||||
assert.ok(
|
||||
RegExp(
|
||||
"Support for the experimental syntax 'asyncGenerators' isn't currently enabled \\(1:15\\):",
|
||||
).exec(err.message),
|
||||
);
|
||||
assert.ok(
|
||||
RegExp(
|
||||
"Add @babel/plugin-proposal-async-generator-functions \\(https://git.io/vb4yp\\) to the " +
|
||||
"'plugins' section of your Babel config to enable transformation.",
|
||||
).exec(err.message),
|
||||
);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
1
packages/babel-core/test/fixtures/api/parsing-errors/only-syntax/file.js
vendored
Normal file
1
packages/babel-core/test/fixtures/api/parsing-errors/only-syntax/file.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var $ = import("jquery");
|
||||
4
packages/babel-core/test/fixtures/api/parsing-errors/syntax-and-transform/file.js
vendored
Normal file
4
packages/babel-core/test/fixtures/api/parsing-errors/syntax-and-transform/file.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
async function* agf() {
|
||||
await 1;
|
||||
yield 2;
|
||||
}
|
||||
Reference in New Issue
Block a user