Home » vue » Jest keeps throwing error while parsing json file in node_modules

Jest keeps throwing error while parsing json file in node_modules

Posted by: admin November 26, 2021 Leave a comment

Questions:

I’ve been trying to configure my jest.config.js file to run some tests on my Vuejs app written with TypeScript. Jest keeps giving an error that says it encountered an unexpected token whilst parsing a json file in the node_modules. Not sure what the issue is because when I try to import a vue file which is plain javascript it works well. Below is the error that jest throws

Test suite failed to run
    Jest encountered an unexpected token
    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html
    Details:
    SyntaxError: Unexpected token ] in JSON at position 774
        at JSON.parse (<anonymous>)
      at parse (node_modules/tsconfig/src/tsconfig.ts:195:15)
      at readFileSync (node_modules/tsconfig/src/tsconfig.ts:181:10)
      at Object.loadSync (node_modules/tsconfig/src/tsconfig.ts:151:18)
      at find (node_modules/vue-jest/lib/load-typescript-config.js:33:39)
      at loadTypescriptConfig (node_modules/vue-jest/lib/load-typescript-config.js:73:26)
      at compileTypescript (node_modules/vue-jest/lib/compilers/typescript-compiler.js:9:20)
      at processScript (node_modules/vue-jest/lib/process.js:23:12)
      at Object.module.exports [as process] (node_modules/vue-jest/lib/process.js:42:18)
      at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:453:35)

Here is my jest.config.js file

module.exports = {
  preset: 'ts-jest',
  transform: {
    '^.+\.js$': '<rootDir>/node_modules/babel-jest',
    '.*\.(vue)$': '<rootDir>/node_modules/vue-jest',
    '^.+\.tsx?$': '<rootDir>/node_modules/ts-jest',
    '.+\.json': '<rootDir>/node_modules/json5-jest',
    '^.+\.json5$': 'json5-jest',
  },
  testEnvironment: 'jsdom',
  moduleFileExtensions: ['ts', 'js', 'json', 'node', 'jsx', 'tsx', 'vue'],
  moduleDirectories: ['node_modules', 'src'],
  testMatch: [
    '**/__tests__/**/*.+(ts|tsx|js)',
    '**/?(*.)+(spec|test).+(ts|tsx|js)',
  ],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '^vue$': 'vue/dist/vue.common.js',
  },
  transformIgnorePatterns: [
    '<rootDir>/node_modules/',
    '<rootDir>/node_modules/(?!(@jest)/)',
    '<rootDir>/node_modules/(?!(@vue-jest)/.*)',
    '<rootDir>/node_modules/(?!tsconfig/.*)',
    '<rootDir>/node_modules/(?!vue-jest/.*)',
    '<rootDir>/node_modules/([email protected]/.*)',
  ],
  testURL: 'http://localhost/',
}

Also here is one of the vue files I tried to import:

<template>
  <tr>
    <td class="link">{{ originalUrl }}</td>
    <td class="link">{{ shortUrl }}
      <button class="copy-clipboard" @click="handleCopyClipboard">Copy</button>
    </td>
    <td>
      <button class="delete-one" @click="handleDeleteUrl">Delete</button>
    </td>
  </tr>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend ({
  props: {
    shortUrl: {
      type: String,
      required: true
    },
    id: {
      type: String,
      required: true
    },
    originalUrl: {
      type: String,
      required: true
    },
    shortUrlHash: {
      type: String,
      required: true
    },
    handleDelete: {
      type: Function,
      required: true
    }
  },
  name: 'Url' as string,
  data: () => ({}),
  methods: {
    handleDeleteUrl() : void {
      this.handleDelete(this.id)
    },

    handleCopyClipboard() : void {
      navigator.clipboard.writeText(this.shortUrl)
      alert('copied to clipboard')
    }
  }
})
</script>

<style scoped>
  .copy-clipboard {
    display: inline-block;
    background: green;
    color: white;
    height: 32px;
    margin-left: 10px;
    width: 60px;
    font-weight: bold;
    text-transform: uppercase;
    border-radius: 5px;
    border: 0;
    box-shadow: none;
    cursor: pointer;
  }

  .delete-one {
    height: 32px;
    background: #dc3545;
    color: white;
    font-weight: bold;
    text-transform: uppercase;
    border-radius: 5px;
    border: 0;
    box-shadow: none;
    text-align: center;
    cursor: pointer;
  }

  button:hover {
    background: #556476;
  }

  .link {
    color: blue;
    cursor: pointer;
    text-decoration: underline;
  }

  @media only screen and (max-width: 540px) {
    .copy-clipboard {
      display: none;
    }

    .delete-one {
      display: none;
    }
  }
</style>
Answers:

Error call stack implies that this happen in Vue loader when parsing TypeScript configuration when transforming <script lang="ts"> block.

It’s most likely a real syntax error in .json file. Unfortunately, file location isn’t mentioned and this needs to be debugged. Since this happens on TypeScript initialization, the problem is in tsconfig.json or associated file.

There’s no need for a separate json5-jest transformer for .json, it can be handled by TypeScript and Babel, and providing JSON5 with .json extension would be a mistake that would cause a problem like this one.