vuejs / vue-jest

Jest Vue transformer
MIT License
746 stars 157 forks source link

bug: variable naming collision when importing and using function inside setup #456

Open liamdebeasi opened 2 years ago

liamdebeasi commented 2 years ago

@vue/vue3-jest version: 27.0.0-alpha.4

When importing a function from a 3rd party library and calling it in setup(), there is a variable naming collision where the contents of the 3rd party library get overridden with the contents of vue.

Steps to Reproduce

  1. Clone https://github.com/liamdebeasi/vtu-import.
  2. Run npm install.
  3. Run cd test-module && npm pack to create an archive of the test package.
  4. In the root directory, run npm install ./test-module/ionic-vue-0.0.1.tgz.
  5. Run npm run test:unit. Observe that you receive the following error:
TypeError: (0 , vue_1.testFunction) is not a function

       8 | export default {
       9 |   setup() {
    > 10 |     testFunction();
         |     ^
      11 |   }
      12 | };
      13 | </script>
  1. Remove everything from the template.
  2. Re-run npm run test:unit. Observe that no error is thrown.

Expected Behavior

I would expect that calling testFunction() does not result in a TypeError: (0 , vue_1.testFunction) is not a function error.

Actual Behavior

Calling testFunction() results in a TypeError: (0 , vue_1.testFunction) is not a function error.

Other Information

Debugging in node_modules/@vue/vue3-jest/lib/process.js reveals the following output:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var vue_1 = require("@ionic/vue");

exports.default = {
  setup: function () {
    (0, vue_1.testFunction)();
  }
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.render = void 0;
var vue_1 = require("vue");
function render(_ctx, _cache) {
    return ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)("div", null, "Hello World"));
}
exports.render = render;
exports.default = {...exports.default, render};

Notice that @ionic/vue is assigned to vue_1, but vue is then assigned to vue_1 which overrides @ionic/vue. As a result, testFunction is being imported from vue.

Removing everything from the template results in vue not being imported which is why this collision does not happen.

Both of these vue_1 usages happen in separate functions with the results being concatenated. The processTemplate function returns var vue_1 = require('vue'), and the processScript function returns var vue_1 = require('@ionic/vue').

nielsvanrijn commented 2 years ago

@liamdebeasi Did you find any workaround? I'm running into this issue specifically with @ionic/vue.

liamdebeasi commented 2 years ago

I am not aware of any good workaround besides migrating to Vite/Vitest. I had moderate success with disabling TypeScript too, but that may not be feasible for larger applications.

nielsvanrijn commented 2 years ago

Ah that is somewhat good news, I already was using Vite but not Vitest. Thx for the quick reply

jacksongross commented 1 year ago

Any updates on this? I am getting the same issue whilst using @tiptap/vue-3. Seems to be trying to interpret the variable name from the package, ignoring dashes in my cause, causing a clash in variables when transformed.

priiduneemre commented 1 year ago

Any news on this? Has anyone found a clever workaround, maybe?

I am facing the same naming collision issue with another unrelated library.