istanbuljs / nyc

the Istanbul command line interface
https://istanbul.js.org/
ISC License
5.55k stars 354 forks source link

Coverage for Single-File Vue Components Not Found #718

Open tenkiller opened 6 years ago

tenkiller commented 6 years ago

Expected Behavior

When running nyc with the lcov reporter, I expect there to be an HTML file for viewing the code coverage of my single-file Vue components (files with the .vue extension).

Observed Behavior

The index.html page of the lcov reporter output shows the coverage of my component, but when clicking on it to get a deeper view, the file cannot be found. It's listing the file's path twice:

<rootDir>/src/components/src/components/Menu.vue

When it should be:

<rootDir>/src/components/Menu.vue

Repository that Reproduces Issue

https://github.com/tenkiller/vue_nyc

Forensic Information

Operating System: Mac OS Sierra 10.12.6 Environment Information: output.txt

bcoe commented 6 years ago

👋 hey @tenkiller sorry for the slow reply. For starters, thanks for the reproduction (it makes digging into things much easier).

This definitely sounds like a bug; I'm not sure if the root cause will be in nyc itself, or one of the underlying istanbul repos that power nyc.

If you have any interest in contributing to this project, this feels like it could be a great first contribution for someone (and I'd help make sure it lands quickly).

wweellddeerr commented 6 years ago

Hey guys, I had a similar problem and I found a workaround (and probably the root cause of the bug).

When webpack uses inline-source-map, nyc don't works correctly.

Try to change 'devtool' in the file build/webpack.conf.test.js to devtool: '#eval'

This works, but the problem with istanbul + webpack with inline-source-map persist.

tenkiller commented 6 years ago

@wweellddeerr Thank you! That was indeed the problem. Setting the devtool option in the Webpack config to 'eval' corrected the paths in the report.

branquito commented 6 years ago

I can confirm this is still an issue, thanks @wweellddeerr for a quick fix!

meowtec commented 6 years ago

@bcoe The same problem here if I set devtool to source-map.

Now I have just two files: src/index.js and src/app.vue, and execute the dist file both in the browser and in node:

If I execute the dist js file in the browser, and print the __coverage__ in the console, it is like:

{
'/path/to/project-demo/src/app.vue': {path: '/path/to/project-demo/src/app.vue', statementMap: {…}, fnMap: {…}, branchMap: {…}, s: {…}, …}
'/path/to/project-demo/src/index.js': {path: '/path/to/project-demo/src/index.js', statementMap: {…}, fnMap: {…}, branchMap: {…}, s: {…}, …}
}

All are correct.

But after I execute dist file using nyc --reporter=html node dist/index.js and open coverage/index.html, there will be a wrong file list:

- dist/webpack:/node_modules/_vue-loader@14.2.2@vue-loader/lib/runtime
- dist/webpack:/src
- dist/webpack:/webpack
- src
  - index.js
- src/src
  - app.vue

The path src/src/app.vue is incorrect: Unable to lookup source: /path/to/project-demo/src/src/app.vue(ENOENT: no such file or directory, open '/path/to/project-demo/src/src/app.vue')

I am not sure but i think it is a bug in nyc

factoidforrest commented 6 years ago

cheap-module-eval-source-map works right? That's the default with the new vue-cli

daemoncron commented 5 years ago

Thank you @wweellddeerr! @light24bulbs - that sounds right but a lot of folks will hit this if they're using vue-test-utils which recommends you use inline-cheap-module-source-map.

tyler36 commented 4 years ago

Coverage was working for me in .vue files in 13.3.0. After, update to 14.1.1, coverage is no longer working.

Adding the following to my .nycrc restored coverage in 14.1.1

    "extension": [
        ".js",
        ".vue"
    ],
fargies commented 4 years ago

Hello,

Using Karma I did experience this issue, here's some additional information: Downgrading karma-coverage from v2.0.1 to v1.1.2 removes the issue, main difference is that v2.0.1 uses istanbul-lib-source-maps.

By digging a bit the issue seems to be at istanbul-lib-source-maps/lib/get-mapping.js#L168

When being called from istanbul-lib-source-maps/lib/transformer.js#L111 both original and source map paths contains the project relative path and it gets concatenated.

A small modification there fixes it, but not sure if it should be done that way (so not creating a merge-request).

I hope it helps !

lsapan commented 4 years ago

Unfortunately it looks like cheap-module-eval-source-map doesn't work either. The only one I was able to get to work was eval, which while it works, results in jumbled highlighting and line numbers for all files (not just .vue ones).

As @fargies mentioned, the issue can be alleviated by changing a line in istanbul-lib-source-maps/lib/get-mapping.js. While this is absolutely awful, a dirty automated solution looks like this (Mac/Linux):

const { execSync } = require('child_process')

# I put this in chainWebpack in vue.config.js
execSync("sed -i '' 's/source: pathutils.relativeTo(start.source, origFile),/source: origFile,/' node_modules/istanbul-lib-source-maps/lib/get-mapping.js")

That'll fix the offending line before your tests run. Awful of course, but it works for now! Proper line numbers and highlighting in JS and Vue files.

ericpres commented 4 years ago

I have just followed this chain and have the code coverage tool working and creating output for my repo, but I still cannot view the details of any of my ".vue" components. I get the same error that is at the beginning of this thread. Has anyone come up with a scalable solution? I am using:

@vue/cli-service - 4.4.6 nyc - 15.1.0