refactor and add test cases

add `parser.exportPresence`, `parser.importExportPresence`, `parser.reeexportExportPresence` `"error" | "warn" | "auto" | false`
This commit is contained in:
Tobias Koppers 2021-11-02 18:16:59 +01:00
parent e189971705
commit d9c592738a
22 changed files with 381 additions and 72 deletions

View File

@ -2843,6 +2843,10 @@ export interface JavascriptParserOptions {
* Enable/disable parsing of magic comments in CommonJs syntax.
*/
commonjsMagicComments?: boolean;
/**
* Specifies the behavior of invalid export names in "import ... from ..." and "export ... from ...".
*/
exportsPresence?: "error" | "warn" | "auto" | false;
/**
* Enable warnings for full dynamic dependencies.
*/
@ -2867,14 +2871,18 @@ export interface JavascriptParserOptions {
* Enable/disable parsing of import() syntax.
*/
import?: boolean;
/**
* Specifies the behavior of invalid export names in "import ... from ...".
*/
importExportsPresence?: "error" | "warn" | "auto" | false;
/**
* Include polyfills or mocks for various node stuff.
*/
node?: Node;
/**
* Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).
* Specifies the behavior of invalid export names in "export ... from ...". This might be useful to disable during the migration from "export ... from ..." to "export type ... from ..." when reexporting types in TypeScript.
*/
reexportExportsPresence?: "error" | "warn" | false;
reexportExportsPresence?: "error" | "warn" | "auto" | false;
/**
* Enable/disable parsing of require.context syntax.
*/
@ -2892,7 +2900,7 @@ export interface JavascriptParserOptions {
*/
requireJs?: boolean;
/**
* Emit errors instead of warnings when imported names don't exist in imported module.
* Deprecated in favor of "exportsPresence". Emit errors instead of warnings when imported names don't exist in imported module.
*/
strictExportPresence?: boolean;
/**

View File

@ -442,13 +442,6 @@ const applyJavascriptParserOptionsDefaults = parserOptions => {
D(parserOptions, "wrappedContextRegExp", /.*/);
D(parserOptions, "wrappedContextRecursive", true);
D(parserOptions, "wrappedContextCritical", false);
D(parserOptions, "strictExportPresence", false);
D(
parserOptions,
"reexportExportsPresence",
parserOptions.strictExportPresence ? "error" : "warn"
);
D(parserOptions, "strictThisContextOnImports", false);
};

View File

@ -11,6 +11,7 @@ const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDepe
const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency");
const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency");
const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency");
const { ExportPresenceModes } = require("./HarmonyImportDependency");
const {
harmonySpecifierTag,
getAssertions
@ -21,10 +22,18 @@ const { HarmonyStarExportsList } = HarmonyExportImportedSpecifierDependency;
module.exports = class HarmonyExportDependencyParserPlugin {
constructor(options) {
this.reexportExportsPresence = options.reexportExportsPresence;
this.exportPresenceMode =
options.reexportExportPresence !== undefined
? ExportPresenceModes.fromUserOption(options.reexportExportPresence)
: options.exportPresence !== undefined
? ExportPresenceModes.fromUserOption(options.exportPresence)
: options.strictExportPresence
? ExportPresenceModes.ERROR
: ExportPresenceModes.AUTO;
}
apply(parser) {
const { exportPresenceMode } = this;
parser.hooks.export.tap(
"HarmonyExportDependencyParserPlugin",
statement => {
@ -128,7 +137,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
name,
harmonyNamedExports,
null,
this.reexportExportsPresence,
exportPresenceMode,
null,
settings.assertions
);
@ -160,7 +169,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
name,
harmonyNamedExports,
harmonyStarExports && harmonyStarExports.slice(),
this.reexportExportsPresence,
exportPresenceMode,
harmonyStarExports
);
if (harmonyStarExports) {

View File

@ -40,6 +40,8 @@ const processExportInfo = require("./processExportInfo");
/** @typedef {"missing"|"unused"|"empty-star"|"reexport-dynamic-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-namespace-object"|"reexport-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */
const { ExportPresenceModes } = HarmonyImportDependency;
const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids");
class NormalReexportItem {
@ -325,7 +327,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
* @param {string | null} name the export name of for this module
* @param {Set<string>} activeExports other named exports in the module
* @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency> | Iterable<HarmonyExportImportedSpecifierDependency>} otherStarExports other star exports in the module before this import
* @param {string | boolean} reexportExportsPresence when true, missing exports in the imported module lead to errors instead of warnings
* @param {number} exportPresenceMode mode of checking export names
* @param {HarmonyStarExportsList} allStarExports all star exports in the module
* @param {Record<string, any>=} assertions import assertions
*/
@ -336,7 +338,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
name,
activeExports,
otherStarExports,
reexportExportsPresence,
exportPresenceMode,
allStarExports,
assertions
) {
@ -346,7 +348,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
this.name = name;
this.activeExports = activeExports;
this.otherStarExports = otherStarExports;
this.reexportExportsPresence = reexportExportsPresence;
this.exportPresenceMode = exportPresenceMode;
this.allStarExports = allStarExports;
}
@ -735,21 +737,29 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
}
}
/**
* @param {ModuleGraph} moduleGraph module graph
* @returns {number} effective mode
*/
_getEffectiveExportPresenceLevel(moduleGraph) {
if (this.exportPresenceMode !== ExportPresenceModes.AUTO)
return this.exportPresenceMode;
return moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
? ExportPresenceModes.ERROR
: ExportPresenceModes.WARN;
}
/**
* Returns warnings
* @param {ModuleGraph} moduleGraph module graph
* @returns {WebpackError[]} warnings
*/
getWarnings(moduleGraph) {
if (!this.reexportExportsPresence) return null;
if (
this.reexportExportsPresence === "error" ||
moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
) {
return null;
const exportPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
if (exportPresence === ExportPresenceModes.WARN) {
return this._getErrors(moduleGraph);
}
return this._getErrors(moduleGraph);
return null;
}
/**
@ -758,14 +768,10 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
* @returns {WebpackError[]} errors
*/
getErrors(moduleGraph) {
if (!this.reexportExportsPresence) return null;
if (
this.reexportExportsPresence === "error" ||
moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
) {
const exportPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
if (exportPresence === ExportPresenceModes.ERROR) {
return this._getErrors(moduleGraph);
}
return null;
}

View File

@ -27,6 +27,25 @@ const ModuleDependency = require("./ModuleDependency");
/** @typedef {import("../util/Hash")} Hash */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
const ExportPresenceModes = {
NONE: /** @type {0} */ (0),
WARN: /** @type {1} */ (1),
AUTO: /** @type {2} */ (2),
ERROR: /** @type {3} */ (3),
fromUserOption(str) {
switch (str) {
case "error":
return ExportPresenceModes.ERROR;
case "warn":
return ExportPresenceModes.WARN;
case false:
return ExportPresenceModes.NONE;
default:
throw new Error(`Invalid export presence value ${str}`);
}
}
};
class HarmonyImportDependency extends ModuleDependency {
/**
*
@ -334,3 +353,5 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
return emittedModules.get(referencedModule) || false;
}
};
module.exports.ExportPresenceModes = ExportPresenceModes;

View File

@ -11,6 +11,7 @@ const ConstDependency = require("./ConstDependency");
const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
const HarmonyExports = require("./HarmonyExports");
const { ExportPresenceModes } = require("./HarmonyImportDependency");
const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
@ -19,6 +20,7 @@ const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDepend
/** @typedef {import("estree").Identifier} Identifier */
/** @typedef {import("estree").ImportDeclaration} ImportDeclaration */
/** @typedef {import("estree").ImportExpression} ImportExpression */
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("../optimize/InnerGraph").InnerGraph} InnerGraph */
/** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */
@ -60,8 +62,18 @@ function getAssertions(node) {
}
module.exports = class HarmonyImportDependencyParserPlugin {
/**
* @param {JavascriptParserOptions} options options
*/
constructor(options) {
this.strictExportPresence = options.strictExportPresence;
this.exportPresenceMode =
options.importExportPresence !== undefined
? ExportPresenceModes.fromUserOption(options.importExportPresence)
: options.exportPresence !== undefined
? ExportPresenceModes.fromUserOption(options.exportPresence)
: options.strictExportPresence
? ExportPresenceModes.ERROR
: ExportPresenceModes.AUTO;
this.strictThisContextOnImports = options.strictThisContextOnImports;
}
@ -70,6 +82,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
* @returns {void}
*/
apply(parser) {
const { exportPresenceMode } = this;
parser.hooks.isPure
.for("Identifier")
.tap("HarmonyImportDependencyParserPlugin", expression => {
@ -128,7 +141,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
settings.ids,
settings.name,
expr.range,
this.strictExportPresence,
exportPresenceMode,
settings.assertions
);
dep.shorthand = parser.scope.inShorthand;
@ -150,7 +163,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
ids,
settings.name,
expr.range,
this.strictExportPresence,
exportPresenceMode,
settings.assertions
);
dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
@ -171,7 +184,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
ids,
settings.name,
callee.range,
this.strictExportPresence,
exportPresenceMode,
settings.assertions
);
dep.directImport = members.length === 0;

View File

@ -28,6 +28,8 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
const idsSymbol = Symbol("HarmonyImportSpecifierDependency.ids");
const { ExportPresenceModes } = HarmonyImportDependency;
class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
constructor(
request,
@ -35,14 +37,14 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
ids,
name,
range,
strictExportPresence,
exportPresenceMode,
assertions
) {
super(request, sourceOrder, assertions);
this.ids = ids;
this.name = name;
this.range = range;
this.strictExportPresence = strictExportPresence;
this.exportPresenceMode = exportPresenceMode;
this.namespaceObjectAsContext = false;
this.call = undefined;
this.directImport = undefined;
@ -153,19 +155,29 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
return [ids];
}
/**
* @param {ModuleGraph} moduleGraph module graph
* @returns {number} effective mode
*/
_getEffectiveExportPresenceLevel(moduleGraph) {
if (this.exportPresenceMode !== ExportPresenceModes.AUTO)
return this.exportPresenceMode;
return moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
? ExportPresenceModes.ERROR
: ExportPresenceModes.WARN;
}
/**
* Returns warnings
* @param {ModuleGraph} moduleGraph module graph
* @returns {WebpackError[]} warnings
*/
getWarnings(moduleGraph) {
if (
this.strictExportPresence ||
moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
) {
return null;
const exportPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
if (exportPresence === ExportPresenceModes.WARN) {
return this._getErrors(moduleGraph);
}
return this._getErrors(moduleGraph);
return null;
}
/**
@ -174,10 +186,8 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
* @returns {WebpackError[]} errors
*/
getErrors(moduleGraph) {
if (
this.strictExportPresence ||
moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
) {
const exportPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
if (exportPresence === ExportPresenceModes.ERROR) {
return this._getErrors(moduleGraph);
}
return null;

File diff suppressed because one or more lines are too long

View File

@ -1474,6 +1474,10 @@
"description": "Enable/disable parsing of magic comments in CommonJs syntax.",
"type": "boolean"
},
"exportsPresence": {
"description": "Specifies the behavior of invalid export names in \"import ... from ...\" and \"export ... from ...\".",
"enum": ["error", "warn", "auto", false]
},
"exprContextCritical": {
"description": "Enable warnings for full dynamic dependencies.",
"type": "boolean"
@ -1506,12 +1510,16 @@
"description": "Enable/disable parsing of import() syntax.",
"type": "boolean"
},
"importExportsPresence": {
"description": "Specifies the behavior of invalid export names in \"import ... from ...\".",
"enum": ["error", "warn", "auto", false]
},
"node": {
"$ref": "#/definitions/Node"
},
"reexportExportsPresence": {
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"enum": ["error", "warn", false]
"description": "Specifies the behavior of invalid export names in \"export ... from ...\". This might be useful to disable during the migration from \"export ... from ...\" to \"export type ... from ...\" when reexporting types in TypeScript.",
"enum": ["error", "warn", "auto", false]
},
"requireContext": {
"description": "Enable/disable parsing of require.context syntax.",
@ -1530,7 +1538,7 @@
"type": "boolean"
},
"strictExportPresence": {
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \"exportsPresence\". Emit errors instead of warnings when imported names don't exist in imported module.",
"type": "boolean"
},
"strictThisContextOnImports": {

View File

@ -217,8 +217,7 @@ Object {
"exprContextRecursive": true,
"exprContextRegExp": false,
"exprContextRequest": ".",
"reexportExportsPresence": "warn",
"strictExportPresence": false,
"strictExportPresence": undefined,
"strictThisContextOnImports": false,
"unknownContextCritical": true,
"unknownContextRecursive": true,

View File

@ -1437,6 +1437,24 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-auto-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript/auto.exportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-auto-expr-context-critical": Object {
"configs": Array [
Object {
@ -1521,6 +1539,24 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-auto-import-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript/auto.importExportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-auto-node": Object {
"configs": Array [
Object {
@ -1598,7 +1634,7 @@ Object {
"module-parser-javascript-auto-reexport-exports-presence": Object {
"configs": Array [
Object {
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"path": "module.parser.javascript/auto.reexportExportsPresence",
"type": "enum",
@ -1609,7 +1645,7 @@ Object {
],
},
],
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"simpleType": "string",
},
@ -1668,13 +1704,13 @@ Object {
"module-parser-javascript-auto-strict-export-presence": Object {
"configs": Array [
Object {
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"path": "module.parser.javascript/auto.strictExportPresence",
"type": "boolean",
},
],
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"simpleType": "boolean",
},
@ -1949,6 +1985,24 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-dynamic-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript/dynamic.exportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-dynamic-expr-context-critical": Object {
"configs": Array [
Object {
@ -2033,6 +2087,24 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-dynamic-import-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript/dynamic.importExportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-dynamic-node": Object {
"configs": Array [
Object {
@ -2110,7 +2182,7 @@ Object {
"module-parser-javascript-dynamic-reexport-exports-presence": Object {
"configs": Array [
Object {
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"path": "module.parser.javascript/dynamic.reexportExportsPresence",
"type": "enum",
@ -2121,7 +2193,7 @@ Object {
],
},
],
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"simpleType": "string",
},
@ -2180,13 +2252,13 @@ Object {
"module-parser-javascript-dynamic-strict-export-presence": Object {
"configs": Array [
Object {
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"path": "module.parser.javascript/dynamic.strictExportPresence",
"type": "boolean",
},
],
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"simpleType": "boolean",
},
@ -2422,6 +2494,24 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-esm-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript/esm.exportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-esm-expr-context-critical": Object {
"configs": Array [
Object {
@ -2506,6 +2596,24 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-esm-import-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript/esm.importExportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-esm-node": Object {
"configs": Array [
Object {
@ -2583,7 +2691,7 @@ Object {
"module-parser-javascript-esm-reexport-exports-presence": Object {
"configs": Array [
Object {
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"path": "module.parser.javascript/esm.reexportExportsPresence",
"type": "enum",
@ -2594,7 +2702,7 @@ Object {
],
},
],
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"simpleType": "string",
},
@ -2653,13 +2761,13 @@ Object {
"module-parser-javascript-esm-strict-export-presence": Object {
"configs": Array [
Object {
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"path": "module.parser.javascript/esm.strictExportPresence",
"type": "boolean",
},
],
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"simpleType": "boolean",
},
@ -2840,6 +2948,24 @@ Object {
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript.exportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-expr-context-critical": Object {
"configs": Array [
Object {
@ -2924,6 +3050,24 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-import-exports-presence": Object {
"configs": Array [
Object {
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"path": "module.parser.javascript.importExportsPresence",
"type": "enum",
"values": Array [
"error",
"warn",
false,
],
},
],
"description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".",
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-node": Object {
"configs": Array [
Object {
@ -3001,7 +3145,7 @@ Object {
"module-parser-javascript-reexport-exports-presence": Object {
"configs": Array [
Object {
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"path": "module.parser.javascript.reexportExportsPresence",
"type": "enum",
@ -3012,7 +3156,7 @@ Object {
],
},
],
"description": "Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).",
"description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.",
"multiple": false,
"simpleType": "string",
},
@ -3071,13 +3215,13 @@ Object {
"module-parser-javascript-strict-export-presence": Object {
"configs": Array [
Object {
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"path": "module.parser.javascript.strictExportPresence",
"type": "boolean",
},
],
"description": "Emit errors instead of warnings when imported names don't exist in imported module.",
"description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module. ",
"multiple": false,
"simpleType": "boolean",
},

View File

@ -53,7 +53,7 @@ const diffItems = (actual, expected, kind) => {
const diff = [];
if (missing.length > 0) {
diff.push(`The following expected ${kind}s are missing:
${missing.map(item => `${item}`).join("\n\n")}`);
${missing.map(item => `${explain(item)}`).join("\n\n")}`);
}
if (tooMuch.length > 0) {
diff.push(`The following ${kind}s are unexpected:

View File

@ -0,0 +1,4 @@
import { NoNo } from "../stub";
export { NotHere } from "../stub";
export default `${typeof NoNo}`;

View File

@ -0,0 +1,4 @@
import { NoNo } from "../stub";
export { NotHere } from "../stub";
export default `${typeof NoNo}`;

View File

@ -0,0 +1,4 @@
import { NoNo } from "../stub";
export { NotHere } from "../stub";
export default `${typeof NoNo}`;

View File

@ -0,0 +1,4 @@
import { NoNo } from "../stub";
export { NotHere } from "../stub";
export default `${typeof NoNo}`;

View File

@ -0,0 +1,10 @@
module.exports = [
{
moduleName: /ccc/,
message: /NotHere.+not found/
},
{
moduleName: /ccc/,
message: /NoNo.+not found/
}
];

View File

@ -0,0 +1,11 @@
import { NotHere as aaa } from "./aaa/index.js";
import { NotHere as bbb } from "./bbb/index.js";
import { NotHere as ccc } from "./ccc/index.js";
import { NotHere as ddd } from "./ddd/index.js";
it("should do nothing", () => {
expect(aaa).toBe(undefined);
expect(bbb).toBe(undefined);
expect(ccc).toBe(undefined);
expect(ddd).toBe(undefined);
});

View File

@ -0,0 +1,3 @@
const foo = 'bar'
export default foo

View File

@ -0,0 +1,14 @@
module.exports = [
{
moduleName: /bbb/,
message: /NotHere.+not found/
},
{
moduleName: /bbb/,
message: /NoNo.+not found/
},
{
moduleName: /ddd/,
message: /NoNo.+not found/
}
];

View File

@ -0,0 +1,34 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
mode: "production",
module: {
rules: [
{
test: /aaa/,
parser: {
exportPresence: false
}
},
{
test: /bbb/,
parser: {
exportPresence: "warn"
}
},
{
test: /ccc/,
parser: {
exportPresence: "error"
}
},
{
test: /ddd/,
parser: {
exportPresence: "error",
importExportPresence: "warn",
reexportExportPresence: false
}
}
]
}
};

16
types.d.ts vendored
View File

@ -5289,6 +5289,11 @@ declare interface JavascriptParserOptions {
*/
commonjsMagicComments?: boolean;
/**
* Specifies the behavior of invalid export names in "import ... from ..." and "export ... from ...".
*/
exportsPresence?: false | "error" | "warn" | "auto";
/**
* Enable warnings for full dynamic dependencies.
*/
@ -5319,15 +5324,20 @@ declare interface JavascriptParserOptions {
*/
import?: boolean;
/**
* Specifies the behavior of invalid export names in "import ... from ...".
*/
importExportsPresence?: false | "error" | "warn" | "auto";
/**
* Include polyfills or mocks for various node stuff.
*/
node?: false | NodeOptions;
/**
* Determines how parser handles of export-import failures (usually due to TypeScript import elision failures).
* Specifies the behavior of invalid export names in "export ... from ...". This might be useful to disable during the migration from "export ... from ..." to "export type ... from ..." when reexporting types in TypeScript.
*/
reexportExportsPresence?: false | "error" | "warn";
reexportExportsPresence?: false | "error" | "warn" | "auto";
/**
* Enable/disable parsing of require.context syntax.
@ -5350,7 +5360,7 @@ declare interface JavascriptParserOptions {
requireJs?: boolean;
/**
* Emit errors instead of warnings when imported names don't exist in imported module.
* Deprecated in favor of "exportsPresence". Emit errors instead of warnings when imported names don't exist in imported module.
*/
strictExportPresence?: boolean;