CommonJsImportsParserPlugin.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { fileURLToPath } = require("url");
  7. const CommentCompilationWarning = require("../CommentCompilationWarning");
  8. const RuntimeGlobals = require("../RuntimeGlobals");
  9. const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
  10. const WebpackError = require("../WebpackError");
  11. const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
  12. const {
  13. evaluateToIdentifier,
  14. evaluateToString,
  15. expressionIsUnsupported,
  16. toConstantDependency
  17. } = require("../javascript/JavascriptParserHelpers");
  18. const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
  19. const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
  20. const CommonJsRequireDependency = require("./CommonJsRequireDependency");
  21. const ConstDependency = require("./ConstDependency");
  22. const ContextDependencyHelpers = require("./ContextDependencyHelpers");
  23. const LocalModuleDependency = require("./LocalModuleDependency");
  24. const { getLocalModule } = require("./LocalModulesHelpers");
  25. const RequireHeaderDependency = require("./RequireHeaderDependency");
  26. const RequireResolveContextDependency = require("./RequireResolveContextDependency");
  27. const RequireResolveDependency = require("./RequireResolveDependency");
  28. const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
  29. /** @typedef {import("estree").CallExpression} CallExpressionNode */
  30. /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
  31. const createRequireSpecifierTag = Symbol("createRequire");
  32. const createdRequireIdentifierTag = Symbol("createRequire()");
  33. class CommonJsImportsParserPlugin {
  34. /**
  35. * @param {JavascriptParserOptions} options parser options
  36. */
  37. constructor(options) {
  38. this.options = options;
  39. }
  40. apply(parser) {
  41. const options = this.options;
  42. const getContext = () => {
  43. if (parser.currentTagData) {
  44. const { context } = parser.currentTagData;
  45. return context;
  46. }
  47. };
  48. //#region metadata
  49. const tapRequireExpression = (expression, getMembers) => {
  50. parser.hooks.typeof
  51. .for(expression)
  52. .tap(
  53. "CommonJsImportsParserPlugin",
  54. toConstantDependency(parser, JSON.stringify("function"))
  55. );
  56. parser.hooks.evaluateTypeof
  57. .for(expression)
  58. .tap("CommonJsImportsParserPlugin", evaluateToString("function"));
  59. parser.hooks.evaluateIdentifier
  60. .for(expression)
  61. .tap(
  62. "CommonJsImportsParserPlugin",
  63. evaluateToIdentifier(expression, "require", getMembers, true)
  64. );
  65. };
  66. const tapRequireExpressionTag = tag => {
  67. parser.hooks.typeof
  68. .for(tag)
  69. .tap(
  70. "CommonJsImportsParserPlugin",
  71. toConstantDependency(parser, JSON.stringify("function"))
  72. );
  73. parser.hooks.evaluateTypeof
  74. .for(tag)
  75. .tap("CommonJsImportsParserPlugin", evaluateToString("function"));
  76. };
  77. tapRequireExpression("require", () => []);
  78. tapRequireExpression("require.resolve", () => ["resolve"]);
  79. tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]);
  80. //#endregion
  81. // Weird stuff //
  82. parser.hooks.assign
  83. .for("require")
  84. .tap("CommonJsImportsParserPlugin", expr => {
  85. // to not leak to global "require", we need to define a local require here.
  86. const dep = new ConstDependency("var require;", 0);
  87. dep.loc = expr.loc;
  88. parser.state.module.addPresentationalDependency(dep);
  89. return true;
  90. });
  91. //#region Unsupported
  92. parser.hooks.expression
  93. .for("require.main")
  94. .tap(
  95. "CommonJsImportsParserPlugin",
  96. expressionIsUnsupported(
  97. parser,
  98. "require.main is not supported by webpack."
  99. )
  100. );
  101. parser.hooks.call
  102. .for("require.main.require")
  103. .tap(
  104. "CommonJsImportsParserPlugin",
  105. expressionIsUnsupported(
  106. parser,
  107. "require.main.require is not supported by webpack."
  108. )
  109. );
  110. parser.hooks.expression
  111. .for("module.parent.require")
  112. .tap(
  113. "CommonJsImportsParserPlugin",
  114. expressionIsUnsupported(
  115. parser,
  116. "module.parent.require is not supported by webpack."
  117. )
  118. );
  119. parser.hooks.call
  120. .for("module.parent.require")
  121. .tap(
  122. "CommonJsImportsParserPlugin",
  123. expressionIsUnsupported(
  124. parser,
  125. "module.parent.require is not supported by webpack."
  126. )
  127. );
  128. //#endregion
  129. //#region Renaming
  130. const defineUndefined = expr => {
  131. // To avoid "not defined" error, replace the value with undefined
  132. const dep = new ConstDependency("undefined", expr.range);
  133. dep.loc = expr.loc;
  134. parser.state.module.addPresentationalDependency(dep);
  135. return false;
  136. };
  137. parser.hooks.canRename
  138. .for("require")
  139. .tap("CommonJsImportsParserPlugin", () => true);
  140. parser.hooks.rename
  141. .for("require")
  142. .tap("CommonJsImportsParserPlugin", defineUndefined);
  143. //#endregion
  144. //#region Inspection
  145. const requireCache = toConstantDependency(
  146. parser,
  147. RuntimeGlobals.moduleCache,
  148. [
  149. RuntimeGlobals.moduleCache,
  150. RuntimeGlobals.moduleId,
  151. RuntimeGlobals.moduleLoaded
  152. ]
  153. );
  154. parser.hooks.expression
  155. .for("require.cache")
  156. .tap("CommonJsImportsParserPlugin", requireCache);
  157. //#endregion
  158. //#region Require as expression
  159. const requireAsExpressionHandler = expr => {
  160. const dep = new CommonJsRequireContextDependency(
  161. {
  162. request: options.unknownContextRequest,
  163. recursive: options.unknownContextRecursive,
  164. regExp: options.unknownContextRegExp,
  165. mode: "sync"
  166. },
  167. expr.range,
  168. undefined,
  169. parser.scope.inShorthand,
  170. getContext()
  171. );
  172. dep.critical =
  173. options.unknownContextCritical &&
  174. "require function is used in a way in which dependencies cannot be statically extracted";
  175. dep.loc = expr.loc;
  176. dep.optional = !!parser.scope.inTry;
  177. parser.state.current.addDependency(dep);
  178. return true;
  179. };
  180. parser.hooks.expression
  181. .for("require")
  182. .tap("CommonJsImportsParserPlugin", requireAsExpressionHandler);
  183. //#endregion
  184. //#region Require
  185. const processRequireItem = (expr, param) => {
  186. if (param.isString()) {
  187. const dep = new CommonJsRequireDependency(
  188. param.string,
  189. param.range,
  190. getContext()
  191. );
  192. dep.loc = expr.loc;
  193. dep.optional = !!parser.scope.inTry;
  194. parser.state.current.addDependency(dep);
  195. return true;
  196. }
  197. };
  198. const processRequireContext = (expr, param) => {
  199. const dep = ContextDependencyHelpers.create(
  200. CommonJsRequireContextDependency,
  201. expr.range,
  202. param,
  203. expr,
  204. options,
  205. {
  206. category: "commonjs"
  207. },
  208. parser,
  209. undefined,
  210. getContext()
  211. );
  212. if (!dep) return;
  213. dep.loc = expr.loc;
  214. dep.optional = !!parser.scope.inTry;
  215. parser.state.current.addDependency(dep);
  216. return true;
  217. };
  218. const createRequireHandler = callNew => expr => {
  219. if (options.commonjsMagicComments) {
  220. const { options: requireOptions, errors: commentErrors } =
  221. parser.parseCommentOptions(expr.range);
  222. if (commentErrors) {
  223. for (const e of commentErrors) {
  224. const { comment } = e;
  225. parser.state.module.addWarning(
  226. new CommentCompilationWarning(
  227. `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
  228. comment.loc
  229. )
  230. );
  231. }
  232. }
  233. if (requireOptions) {
  234. if (requireOptions.webpackIgnore !== undefined) {
  235. if (typeof requireOptions.webpackIgnore !== "boolean") {
  236. parser.state.module.addWarning(
  237. new UnsupportedFeatureWarning(
  238. `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`,
  239. expr.loc
  240. )
  241. );
  242. } else {
  243. // Do not instrument `require()` if `webpackIgnore` is `true`
  244. if (requireOptions.webpackIgnore) {
  245. return true;
  246. }
  247. }
  248. }
  249. }
  250. }
  251. if (expr.arguments.length !== 1) return;
  252. let localModule;
  253. const param = parser.evaluateExpression(expr.arguments[0]);
  254. if (param.isConditional()) {
  255. let isExpression = false;
  256. for (const p of param.options) {
  257. const result = processRequireItem(expr, p);
  258. if (result === undefined) {
  259. isExpression = true;
  260. }
  261. }
  262. if (!isExpression) {
  263. const dep = new RequireHeaderDependency(expr.callee.range);
  264. dep.loc = expr.loc;
  265. parser.state.module.addPresentationalDependency(dep);
  266. return true;
  267. }
  268. }
  269. if (
  270. param.isString() &&
  271. (localModule = getLocalModule(parser.state, param.string))
  272. ) {
  273. localModule.flagUsed();
  274. const dep = new LocalModuleDependency(localModule, expr.range, callNew);
  275. dep.loc = expr.loc;
  276. parser.state.module.addPresentationalDependency(dep);
  277. return true;
  278. } else {
  279. const result = processRequireItem(expr, param);
  280. if (result === undefined) {
  281. processRequireContext(expr, param);
  282. } else {
  283. const dep = new RequireHeaderDependency(expr.callee.range);
  284. dep.loc = expr.loc;
  285. parser.state.module.addPresentationalDependency(dep);
  286. }
  287. return true;
  288. }
  289. };
  290. parser.hooks.call
  291. .for("require")
  292. .tap("CommonJsImportsParserPlugin", createRequireHandler(false));
  293. parser.hooks.new
  294. .for("require")
  295. .tap("CommonJsImportsParserPlugin", createRequireHandler(true));
  296. parser.hooks.call
  297. .for("module.require")
  298. .tap("CommonJsImportsParserPlugin", createRequireHandler(false));
  299. parser.hooks.new
  300. .for("module.require")
  301. .tap("CommonJsImportsParserPlugin", createRequireHandler(true));
  302. //#endregion
  303. //#region Require with property access
  304. const chainHandler = (expr, calleeMembers, callExpr, members) => {
  305. if (callExpr.arguments.length !== 1) return;
  306. const param = parser.evaluateExpression(callExpr.arguments[0]);
  307. if (param.isString() && !getLocalModule(parser.state, param.string)) {
  308. const dep = new CommonJsFullRequireDependency(
  309. param.string,
  310. expr.range,
  311. members
  312. );
  313. dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
  314. dep.optional = !!parser.scope.inTry;
  315. dep.loc = expr.loc;
  316. parser.state.current.addDependency(dep);
  317. return true;
  318. }
  319. };
  320. const callChainHandler = (expr, calleeMembers, callExpr, members) => {
  321. if (callExpr.arguments.length !== 1) return;
  322. const param = parser.evaluateExpression(callExpr.arguments[0]);
  323. if (param.isString() && !getLocalModule(parser.state, param.string)) {
  324. const dep = new CommonJsFullRequireDependency(
  325. param.string,
  326. expr.callee.range,
  327. members
  328. );
  329. dep.call = true;
  330. dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
  331. dep.optional = !!parser.scope.inTry;
  332. dep.loc = expr.callee.loc;
  333. parser.state.current.addDependency(dep);
  334. parser.walkExpressions(expr.arguments);
  335. return true;
  336. }
  337. };
  338. parser.hooks.memberChainOfCallMemberChain
  339. .for("require")
  340. .tap("CommonJsImportsParserPlugin", chainHandler);
  341. parser.hooks.memberChainOfCallMemberChain
  342. .for("module.require")
  343. .tap("CommonJsImportsParserPlugin", chainHandler);
  344. parser.hooks.callMemberChainOfCallMemberChain
  345. .for("require")
  346. .tap("CommonJsImportsParserPlugin", callChainHandler);
  347. parser.hooks.callMemberChainOfCallMemberChain
  348. .for("module.require")
  349. .tap("CommonJsImportsParserPlugin", callChainHandler);
  350. //#endregion
  351. //#region Require.resolve
  352. const processResolve = (expr, weak) => {
  353. if (expr.arguments.length !== 1) return;
  354. const param = parser.evaluateExpression(expr.arguments[0]);
  355. if (param.isConditional()) {
  356. for (const option of param.options) {
  357. const result = processResolveItem(expr, option, weak);
  358. if (result === undefined) {
  359. processResolveContext(expr, option, weak);
  360. }
  361. }
  362. const dep = new RequireResolveHeaderDependency(expr.callee.range);
  363. dep.loc = expr.loc;
  364. parser.state.module.addPresentationalDependency(dep);
  365. return true;
  366. } else {
  367. const result = processResolveItem(expr, param, weak);
  368. if (result === undefined) {
  369. processResolveContext(expr, param, weak);
  370. }
  371. const dep = new RequireResolveHeaderDependency(expr.callee.range);
  372. dep.loc = expr.loc;
  373. parser.state.module.addPresentationalDependency(dep);
  374. return true;
  375. }
  376. };
  377. const processResolveItem = (expr, param, weak) => {
  378. if (param.isString()) {
  379. const dep = new RequireResolveDependency(
  380. param.string,
  381. param.range,
  382. getContext()
  383. );
  384. dep.loc = expr.loc;
  385. dep.optional = !!parser.scope.inTry;
  386. dep.weak = weak;
  387. parser.state.current.addDependency(dep);
  388. return true;
  389. }
  390. };
  391. const processResolveContext = (expr, param, weak) => {
  392. const dep = ContextDependencyHelpers.create(
  393. RequireResolveContextDependency,
  394. param.range,
  395. param,
  396. expr,
  397. options,
  398. {
  399. category: "commonjs",
  400. mode: weak ? "weak" : "sync"
  401. },
  402. parser,
  403. getContext()
  404. );
  405. if (!dep) return;
  406. dep.loc = expr.loc;
  407. dep.optional = !!parser.scope.inTry;
  408. parser.state.current.addDependency(dep);
  409. return true;
  410. };
  411. parser.hooks.call
  412. .for("require.resolve")
  413. .tap("CommonJsImportsParserPlugin", expr => {
  414. return processResolve(expr, false);
  415. });
  416. parser.hooks.call
  417. .for("require.resolveWeak")
  418. .tap("CommonJsImportsParserPlugin", expr => {
  419. return processResolve(expr, true);
  420. });
  421. //#endregion
  422. //#region Create require
  423. if (!options.createRequire) return;
  424. let moduleName;
  425. let specifierName;
  426. if (options.createRequire === true) {
  427. moduleName = "module";
  428. specifierName = "createRequire";
  429. } else {
  430. const match = /^(.*) from (.*)$/.exec(options.createRequire);
  431. if (match) {
  432. [, specifierName, moduleName] = match;
  433. }
  434. if (!specifierName || !moduleName) {
  435. const err = new WebpackError(
  436. `Parsing javascript parser option "createRequire" failed, got ${JSON.stringify(
  437. options.createRequire
  438. )}`
  439. );
  440. err.details =
  441. 'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module';
  442. throw err;
  443. }
  444. }
  445. tapRequireExpressionTag(createdRequireIdentifierTag);
  446. tapRequireExpressionTag(createRequireSpecifierTag);
  447. parser.hooks.evaluateCallExpression
  448. .for(createRequireSpecifierTag)
  449. .tap("CommonJsImportsParserPlugin", expr => {
  450. const context = parseCreateRequireArguments(expr);
  451. if (context === undefined) return;
  452. const ident = parser.evaluatedVariable({
  453. tag: createdRequireIdentifierTag,
  454. data: { context },
  455. next: undefined
  456. });
  457. return new BasicEvaluatedExpression()
  458. .setIdentifier(ident, ident, () => [])
  459. .setSideEffects(false)
  460. .setRange(expr.range);
  461. });
  462. parser.hooks.unhandledExpressionMemberChain
  463. .for(createdRequireIdentifierTag)
  464. .tap("CommonJsImportsParserPlugin", (expr, members) => {
  465. return expressionIsUnsupported(
  466. parser,
  467. `createRequire().${members.join(".")} is not supported by webpack.`
  468. )(expr);
  469. });
  470. parser.hooks.canRename
  471. .for(createdRequireIdentifierTag)
  472. .tap("CommonJsImportsParserPlugin", () => true);
  473. parser.hooks.canRename
  474. .for(createRequireSpecifierTag)
  475. .tap("CommonJsImportsParserPlugin", () => true);
  476. parser.hooks.rename
  477. .for(createRequireSpecifierTag)
  478. .tap("CommonJsImportsParserPlugin", defineUndefined);
  479. parser.hooks.expression
  480. .for(createdRequireIdentifierTag)
  481. .tap("CommonJsImportsParserPlugin", requireAsExpressionHandler);
  482. parser.hooks.call
  483. .for(createdRequireIdentifierTag)
  484. .tap("CommonJsImportsParserPlugin", createRequireHandler(false));
  485. /**
  486. * @param {CallExpressionNode} expr call expression
  487. * @returns {string} context
  488. */
  489. const parseCreateRequireArguments = expr => {
  490. const args = expr.arguments;
  491. if (args.length !== 1) {
  492. const err = new WebpackError(
  493. "module.createRequire supports only one argument."
  494. );
  495. err.loc = expr.loc;
  496. parser.state.module.addWarning(err);
  497. return;
  498. }
  499. const arg = args[0];
  500. const evaluated = parser.evaluateExpression(arg);
  501. if (!evaluated.isString()) {
  502. const err = new WebpackError(
  503. "module.createRequire failed parsing argument."
  504. );
  505. err.loc = arg.loc;
  506. parser.state.module.addWarning(err);
  507. return;
  508. }
  509. const ctx = evaluated.string.startsWith("file://")
  510. ? fileURLToPath(evaluated.string)
  511. : evaluated.string;
  512. // argument always should be a filename
  513. return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\"));
  514. };
  515. parser.hooks.import.tap(
  516. {
  517. name: "CommonJsImportsParserPlugin",
  518. stage: -10
  519. },
  520. (statement, source) => {
  521. if (
  522. source !== moduleName ||
  523. statement.specifiers.length !== 1 ||
  524. statement.specifiers[0].type !== "ImportSpecifier" ||
  525. statement.specifiers[0].imported.type !== "Identifier" ||
  526. statement.specifiers[0].imported.name !== specifierName
  527. )
  528. return;
  529. // clear for 'import { createRequire as x } from "module"'
  530. // if any other specifier was used import module
  531. const clearDep = new ConstDependency(
  532. parser.isAsiPosition(statement.range[0]) ? ";" : "",
  533. statement.range
  534. );
  535. clearDep.loc = statement.loc;
  536. parser.state.module.addPresentationalDependency(clearDep);
  537. parser.unsetAsiPosition(statement.range[1]);
  538. return true;
  539. }
  540. );
  541. parser.hooks.importSpecifier.tap(
  542. {
  543. name: "CommonJsImportsParserPlugin",
  544. stage: -10
  545. },
  546. (statement, source, id, name) => {
  547. if (source !== moduleName || id !== specifierName) return;
  548. parser.tagVariable(name, createRequireSpecifierTag);
  549. return true;
  550. }
  551. );
  552. parser.hooks.preDeclarator.tap(
  553. "CommonJsImportsParserPlugin",
  554. declarator => {
  555. if (
  556. declarator.id.type !== "Identifier" ||
  557. !declarator.init ||
  558. declarator.init.type !== "CallExpression" ||
  559. declarator.init.callee.type !== "Identifier"
  560. )
  561. return;
  562. const variableInfo = parser.getVariableInfo(
  563. declarator.init.callee.name
  564. );
  565. if (
  566. variableInfo &&
  567. variableInfo.tagInfo &&
  568. variableInfo.tagInfo.tag === createRequireSpecifierTag
  569. ) {
  570. const context = parseCreateRequireArguments(declarator.init);
  571. if (context === undefined) return;
  572. parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, {
  573. name: declarator.id.name,
  574. context
  575. });
  576. return true;
  577. }
  578. }
  579. );
  580. parser.hooks.memberChainOfCallMemberChain
  581. .for(createRequireSpecifierTag)
  582. .tap(
  583. "CommonJsImportsParserPlugin",
  584. (expr, calleeMembers, callExpr, members) => {
  585. if (
  586. calleeMembers.length !== 0 ||
  587. members.length !== 1 ||
  588. members[0] !== "cache"
  589. )
  590. return;
  591. // createRequire().cache
  592. const context = parseCreateRequireArguments(callExpr);
  593. if (context === undefined) return;
  594. return requireCache(expr);
  595. }
  596. );
  597. parser.hooks.callMemberChainOfCallMemberChain
  598. .for(createRequireSpecifierTag)
  599. .tap(
  600. "CommonJsImportsParserPlugin",
  601. (expr, calleeMembers, innerCallExpression, members) => {
  602. if (
  603. calleeMembers.length !== 0 ||
  604. members.length !== 1 ||
  605. members[0] !== "resolve"
  606. )
  607. return;
  608. // createRequire().resolve()
  609. return processResolve(expr, false);
  610. }
  611. );
  612. parser.hooks.expressionMemberChain
  613. .for(createdRequireIdentifierTag)
  614. .tap("CommonJsImportsParserPlugin", (expr, members) => {
  615. // require.cache
  616. if (members.length === 1 && members[0] === "cache") {
  617. return requireCache(expr);
  618. }
  619. });
  620. parser.hooks.callMemberChain
  621. .for(createdRequireIdentifierTag)
  622. .tap("CommonJsImportsParserPlugin", (expr, members) => {
  623. // require.resolve()
  624. if (members.length === 1 && members[0] === "resolve") {
  625. return processResolve(expr, false);
  626. }
  627. });
  628. parser.hooks.call
  629. .for(createRequireSpecifierTag)
  630. .tap("CommonJsImportsParserPlugin", expr => {
  631. const clearDep = new ConstDependency(
  632. "/* createRequire() */ undefined",
  633. expr.range
  634. );
  635. clearDep.loc = expr.loc;
  636. parser.state.module.addPresentationalDependency(clearDep);
  637. return true;
  638. });
  639. //#endregion
  640. }
  641. }
  642. module.exports = CommonJsImportsParserPlugin;