javascriptwebpackwebpack-plugin

Trouble with HarmonyImportSpecifierDependency


I am writing plugin, which inlines some code. And I have troubles with internal webpack plugin

Intro

My aim is to transpile this code

// a.js

export const getFoo = x => x.foo;

// b.js
import {getFoo} from './a.js';

export const func = x => getFoo(x);

to this one


// b.js
export const func = x => x.foo;

Using this comment I implemented such logic

  1. Hook on compiler.hooks.beforeCompile and find all imports of transpiled modules with parser.hooks.importSpecifier and
  2. Then using the same compiler hook, I find all CallExpressions and remember all functions which will be transpiled and their position
  3. In compiler.hooks.compilation in compilation.hooks.buildModule I add template dependency which will replace CallExpressions with MemberExpression

The problem

Webpack has internal plugin HarmonyImportSpecifierDependency. Apparently, it does the same logic replacing

import {getFoo} from './a.js';

export const func = x => x.foo;

with

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return func; });
/* harmony import */ var _getters_uno__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);

const func = x => {
  // NEXT LINE IS THE RESULT OF `HarmonyImportSpecifierDependency` WORK
  return Object(_getters_uno__WEBPACK_IMPORTED_MODULE_0__[/* getFoo */ "e"])(x);
};

My problem is that both plugins (mine and HarmonyImportSpecifierDependency) remembers the original source and original places of CallExpressions. The result of both plugins is invalid code:

return Object(_getters_uno__WEBPACK_IMPORTED_MODULE_0__[/* getFoo */ "e"])x.foo);

The question

Is there a way how to give HarmonyImportSpecifierDependency the result of my plugin? I've tried to reparse module in compilation phase, but whith no success


Solution

  • I solved my problem with patching replacements object in source in succeedBuild hook

    source.replacements = source.replacements
      .filter(r => !r.content.includes(`/* ${callExpression.callee.name} */`));
    

    Still wonder if there is a better solution