vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.7k stars 8.33k forks source link

Vue compat with Jest: "TypeError: decode_js.EntityDecoder is not a constructor" #10609

Open baffalop opened 7 months ago

baffalop commented 7 months ago

Vue version

3.4.21 (with @vue/compat 3.4.21)

Link to minimal reproduction

https://stackblitz.com/edit/vue2-jest-8qoex3?file=jest.config.js&view=editor

Steps to reproduce

yarn install
yarn test

What is expected?

I would like to run unit tests with Vue Test Utils, while on the migration build. My application has Vue 2 dependencies which cause unit tests to fail when they are run with Vue 3. I would expect to be able to use the migration build to fix this by aliasing vue to @vue/compat via moduleNameMapper. (This is the approach recommended by vue-test-utils-compat though the minimal reproduction uses latest @vue/test-utils.)

What is actually happening?

Running tests with moduleNameMapper: { '^vue$': '@vue/compat' } causes the following TypeError:

TypeError: decode_js.EntityDecoder is not a constructor
...
at new Tokenizer (node_modules/@vue/compat/dist/vue.cjs.js:13619:28)
      at Object.<anonymous> (tests/unit/example.spec.ts:6:22)

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.3 - /usr/local/bin/pnpm
  npmPackages:
    vue: ^3.3.4 => 3.4.21 

Any additional comments?

This is the same error as in https://github.com/vuejs/core/issues/10148 though it doesn't affect me at build- or runtime, only in Jest.

baffalop commented 7 months ago

Update: I was mistaken about versions. My ^3.3.4 actually resolved to 3.4. When I pin both vue and @vue/compat to ~3.3.4 the issue goes away. This fits with https://github.com/vuejs/core/issues/10148 which reports the error as only present on 3.4, not 3.3.

kumarimanjari commented 7 months ago

Is there any update on this issue further, I am also getting this issue in my project.

lzl0304 commented 5 months ago

The problem is caused by incompatible dependency versions, Vue depends on entities:^4.5.0, but there are other packages that depend on entities:^2.2.0, for some reason the dependency installed by yarn is only entities:^2.2.0, which leads to runtime errors.

I tried to use npm, pnpm to install the dependency is not error, just for reference.

mashpie commented 2 months ago

usually I don't express any emotion... and pleas don't get me wrong I don't mean to blame anyone. I came to this issue because of:

[nuxt] [request error] [unhandled] [500] decode_js.EntityDecoder is not a constructor
  at new Tokenizer (./.output/server/chunks/routes/renderer.mjs:15285:28)
  at ./.output/server/chunks/routes/renderer.mjs:16986:19
  at ModuleJob.run (node:internal/modules/esm/module_job:262:25)
  at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:482:26)
  at async Object.handler (./.output/server/chunks/runtime.mjs:2986:19)
  at async Server.toNodeHandle (./.output/server/chunks/runtime.mjs:3256:7)

which - out of a sudden - spits out after a fresh docker build of a nuxt project opting in to enable vue runtime compiler and... yes, of course working fine on local dev with node 20.12.2 but not with docker build. All builds (2 years+) without that compile() part of the project went well over node versions 18 to 22...

So:

the error remained the same, the line (with context) reads like:

    {
      this.entityDecoder = new decode_js.EntityDecoder(
        decode_js.htmlDecodeTree,
        (cp, consumed) => this.emitCodePoint(cp, consumed)
      );
    }

with (line 1483):

var decode_js = require$$1;

aha, now... what?

how much abstraction is going on here - and causing confusion. All I wanted is to transfere a <image id="123"/> to <img src="https://..../123/img.webp" /> with a vue component buried in nuxt project recieving that tag as string from a database.

God knows I am a big advocate for js and vue (in favor of react) or nuxt (in favor of next) etc. - but this time I wich to be writing perl cgi as we did 20years ago. 10min done.

...sorry no rant at all just frustration. Hope to find solution by myself over the weekend.

mashpie commented 2 months ago

...for reference (as @lzl0304 stated) the output of pnpm why entities -r shows a mix of entities@4.5.0 and entities@2.1.0 why.txt

mashpie commented 2 months ago

HA! removed all and every package that required an `entities? version < 4.5 (thanks again @lzl0304) and violá build & run works as I were running local dev in production... conclusion?

monorepos have a limit when trying to mix legacy and modern packages. Stick to single repos in that case - cheers! (hope, this helps anyone stucked similar)

came here from https://github.com/vuejs/core/issues/10148 (for ref)