unplugin-vue2-script-setup icon indicating copy to clipboard operation
unplugin-vue2-script-setup copied to clipboard

Will this play nicely with jest?

Open Aaron-Pool opened this issue 4 years ago • 18 comments

First of all--thank you SO much. I've been hoping one of the core Vue members would backport script setup to Vue 2.

The only adoption concern I have left after reading the readme is whether this will break my jest tests. I guess it wouldn't be too hard for me to write a basic jest transform using the JavaScript API. But I wasn't sure whether that would play nicely with vue-jest. Any thoughts on this.

Aaron-Pool avatar Aug 21 '21 14:08 Aaron-Pool

I think there should be no problem on that. /cc @lmiller1990 WDYT?

We could ships a simple jest transformer via submodules just like other plugins, tho I am not very familiar with jest, pr will be great welcome!

antfu avatar Aug 22 '21 02:08 antfu

@antfu I did a little digging, and it looks like running multiple transforms on the same file extension is a non-trivial problem. See the discussion here: https://github.com/facebook/jest/issues/8725

So it seems like the PR would need to be to submitted to vue-jest, rather than here.

Aaron-Pool avatar Aug 22 '21 13:08 Aaron-Pool

Or we could bypass the transform to vue-jest (as ppl are likely to use it when using jest), something like:

const { transform } = require('vue2-script-setup-transform')

module.exports = (source, id, ...args) {
  const transformed = transform(source, id)

  return require('vue-jest')(source, id, ...args)
}

antfu avatar Aug 22 '21 13:08 antfu

First off, I am amazed this has been ported to Vue 2. Well done! I haven't looked at how it's implemented exactly, but assuming there is no technical blocker, we could support this in vue-jest.

Considering Vue 2 will not have many more big updates, maintenance should not be too difficult. I am not sure I have time to work on this right now, but since most of the work is done in this code base, I'm guess we just:

  • import this into vue-jest
  • before we do the usual vue-jest transform, we pass the input to this module, changing the code into a regular SFC
  • let vue-jest do the rest of the transform

lmiller1990 avatar Aug 24 '21 00:08 lmiller1990

Ok so for those running into this issue here's the solution:

create a file vue-setup-transformer.js:

const { transform } = require('vue2-script-setup-transform');
const vueJest = require('vue-jest');

module.exports = {
  process(source, filename, ...args) {
    const transformed = transform(source, filename);
    return vueJest.process(transformed.code, filename, ...args);
  },
};

and then in your jest.config.js replace vue-jest with this custom transformer:

'.*\\.(vue)$': '<rootDir>/vue-setup-transformer.js',

I don't know where i could submit this PR or how to do it, but if you let me know i could most likely do a pr here or for vue-jest?

Edit: This still seems to have trouble when transforming with external dependencies. it fails at the const transformed = transform(source, filename); and never goes into the vue-jest.process

Trying to figure out why

Neophen avatar Aug 24 '21 16:08 Neophen

Glad to see it works!

v0.4.1 ships an experimental support for jest:

npm i -D vue-jest
// jest.config.js
module.exports = {
  transform: {
    '.*\\.(vue)$': 'unplugin-vue2-script-setup/jest',
  },
}

Let me know if it works for you

antfu avatar Aug 24 '21 16:08 antfu

@antfu is this gonna play havoc with source maps? I was actually planning to do a PR for this myself, but I ran into an issue where I wasn't sure how to properly handle combining the source map for this transform with the one vue-jest generates.

Aaron-Pool avatar Aug 24 '21 17:08 Aaron-Pool

@antfu i found a super weird issue

if you have the word link in a v-for item like so:

<div v-for="(link, index) in links" :key="index" class="py-4 space-y-2">

this will break the transformation with:

ERROR: Unexpected token (1:1)
STACK: SyntaxError: Unexpected token (1:1)

and it doesn't matter it could be just link or adminLink or linkItem it will always break

Neophen avatar Aug 25 '21 06:08 Neophen

This is actually not a problem with jest, but with the whole plugin, added more details here: link to issue

Neophen avatar Aug 25 '21 08:08 Neophen

@antfu I tried it with Jest like described in the README.md, but I get the following error:

Module unplugin-vue2-script-setup/jest in the transform option was not found.

There seems to be something missing in the bundle.

dm4t2 avatar Oct 20 '21 19:10 dm4t2

I am getting same as @dm4t2

sh786 avatar Oct 22 '21 13:10 sh786

@dm4t2 @sh786 I ran into this as well. I'm sure @antfu will fix the issue as soon as he can, but until then, a simple work around is creating a sibling file to your jest config with the below contents:

// jest-script-setup-transform
const { transform } = require('unplugin-vue2-script-setup');

module.exports = {
  process(source, filename, ...args) {
    const transformed = transform(source, filename);
    const code = transformed ? transformed.code : source;
    return require('vue-jest').process.call(this, code, filename, ...args);
  },
};

and then using it like you would the real transform:

// jest.config.js
module.exports = {
  // with your other config options
  transforms: {
    '.*\\.(vue)$': require.resolve('./jest-script-setup-transform.js'),
  }
}

Aaron-Pool avatar Oct 22 '21 14:10 Aaron-Pool

I've created a PR for this.

dm4t2 avatar Oct 22 '21 14:10 dm4t2

It still does not work for me. I tried it in a newly created Vue CLI project, but got the following error:

image

Any advice? Thanks!

dm4t2 avatar Nov 11 '21 22:11 dm4t2

It still does not work for me. I tried it in a newly created Vue CLI project, but got the following error:

image

Any advice? Thanks!

Same here

sh786 avatar Nov 11 '21 22:11 sh786

I tried to look into this and don't exactly understand what went wrong here, but on the generated index.js file the CommonJS export doesn't seem to be having the transform import where as it seems to ~~exported properly in the ES module~~. I am not really familiar with the toolchain used here, but if I get time I will try to look into this and open a PR.

Meanwhile, the following hacky workaround snippet seems to work to get transform running for me in the meantime, just not a big fan of it.

// jest-script-setup-transform.js
const { raw } = require("unplugin-vue2-script-setup")

const transform = raw().transform

module.exports = {
  process(source, filename, ...args) {
    const transformed = transform(source, filename)
    const code = transformed ? transformed.code : source
    return require("vue-jest").process.call(this, code, filename, ...args)
  },
}

UPDATE: I created a separate empty node project, import this package, and try to run with the "type": "module" mode (basically enabling ESModule), even in that, the following snippet logs undefined

import { transform } from "unplugin-vue2-script-setup";

console.log(transform);

AndrewBastin avatar Nov 17 '21 16:11 AndrewBastin

So is this fixed? Cause I believe I am running in to the same problems

wesley-spencer avatar Feb 10 '22 23:02 wesley-spencer

I would suggest moving to https://github.com/vitest-dev/vitest, there isn't much space for us to support plugin transformations in jest properly

antfu avatar Feb 11 '22 02:02 antfu