Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardcoded Babel config prevents code coverage for ESM TypeScript modules #614

Closed
yinzara opened this issue May 28, 2021 · 9 comments · Fixed by #692
Closed

Hardcoded Babel config prevents code coverage for ESM TypeScript modules #614

yinzara opened this issue May 28, 2021 · 9 comments · Fixed by #692

Comments

@yinzara
Copy link

yinzara commented May 28, 2021

If I create an "src/index.ts" file with the following contents:

import { dirname } from 'path'
import { fileURLToPath } from 'url'

const __dirname = dirname(fileURLToPath(import.meta.url))

export function someFunction() {
   console.log(__dirname)
}

and run jest --coverage, I get:

STACK: SyntaxError: unknown: import.meta may appear only with 'sourceType: "module"' (3828:53)
Consider renaming the file to '.mjs', or setting sourceType:module or sourceType:unambiguous in your Babel config for this file.

Unfortunately I can't rename my file to "mjs" as it would not be a TypeScript file and would fail compilation.

This seems to be caused by the packages/istanbul-lib-instrument/src/read-coverage.js lines:

function getAst(code) {
    if (typeof code === 'object' && typeof code.type === 'string') {
        // Assume code is already a babel ast.
        return code;
    }

    if (typeof code !== 'string') {
        throw new Error('Code must be a string');
    }

    // Parse as leniently as possible
    return parseSync(code, {
        babelrc: false,
        configFile: false,
        parserOpts: {
            allowImportExportEverywhere: true,
            allowReturnOutsideFunction: true,
            allowSuperOutsideMethod: true,
            sourceType: 'script',
            plugins: defaults.instrumenter.parserPlugins
        }
    });
}

Because the "sourceType" is hard coded as 'script', there is no way to change it to use 'module' and no way to modify the babel config otherwise.

@yinzara
Copy link
Author

yinzara commented May 28, 2021

Just to note my jest.config.cjs is:

module.exports = {
  transform: { '\\.tsx?$': 'ts-jest' },
  testEnvironment: 'node',
  extensionsToTreatAsEsm: ['.ts'],
  collectCoverageFrom: ['**/*.{js,jsx}'],
  coveragePathIgnorePatterns: [
    '/dist/',
    '/node_modules/',
    '.*\\.d\\.ts',
  ],
  moduleFileExtensions: ['js', 'json', 'jsx', 'node', 'ts', 'tsx'],
  testEnvironment: 'node',
  testMatch: ['**/?(*.)+(spec|test).(j|t)s?(x)'],
  globals: {
    'ts-jest': {
      useESM: true
    }
  }
}

If I do not set the 'ts-jest' config to useESM: true, I get a slightly different error:

STACK: 
Failed to collect coverage from /myprojectpath/src/index.ts
ERROR: src/index.ts:25:46 - error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'esnext', or 'system'.

@gitawego
Copy link

gitawego commented Oct 6, 2021

any update on this issue ? it prevents us from collecting coverage with jest

@piranna
Copy link
Contributor

piranna commented Oct 12, 2021

It seems I'm facing exactly the same issue, any clue?

@marceloavf
Copy link

Trying to migrate to ESM due to many packages from @sindresorhus requires it now, but really hard to get through these problems

Also: sindresorhus/p-queue#152

@bcoe
Copy link
Member

bcoe commented Nov 30, 2021

@marceloavf @piranna for what it's worth, I've been using c8 these days for my projects that are ESM.

It's not perfect, but I find it works well enough for me.

@freshollie
Copy link

freshollie commented Dec 8, 2021

FYI for those using jest. Using the v8 coverage provider is not only faster, but fixes this problem:

https://jestjs.io/docs/configuration#coverageprovider-string

Edit: There are some drawbacks from using v8: jestjs/jest#11188

@jasonk
Copy link

jasonk commented Jun 4, 2022

For anybody else struggling with this, here is a gist with some patches you can apply using patch-package to kludge your way around the issue...
https://gist.github.com/jasonk/8616825033ba94cc77840c8c872497d9

@fohletex
Copy link

Unfortunately this patch didn't work for me (probably because I do not use babel in my project and just ts-node, resp. having anorther software version). I just fixed it be directly replacing the script-sourceType with module. Here's my patch for that to run in patch-package: https://github.com/fohletex/esm-patch-istanbul-lib-instrument

@SimenB
Copy link
Member

SimenB commented Oct 4, 2023

https://github.com/istanbuljs/istanbuljs/releases/tag/istanbul-lib-instrument-v6.0.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants