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

TypeScript support is unreliable #17

Open
foxbunny opened this issue Apr 22, 2017 · 7 comments
Open

TypeScript support is unreliable #17

foxbunny opened this issue Apr 22, 2017 · 7 comments

Comments

@foxbunny
Copy link
Contributor

It feels a bit weird submitting an issue report against a feature for which I created a PR originally. Anyway...

It appears that TS support I hacked together originally is a bit flaky. It sometimes works and sometimes does not. Apparently, this has something to do with the fact that Vue.js dist contains different types of modules depending on how you import it, and the wrong type (CommonJS vs ESM) gets selected at runtime. TypeScript's compiler will make assumptions that don't hold true when the code is run. For example, it will assume that exports.default is defined by the module, when it's not, and so on.

Long story short, while you can write tests that work with TypeScript and Jest, the code may break when the same code is used with Webpack. I'm currently trying to hack together a workaround for this, but thus far, it's not looking very promising. It also feels wrong to hack around this issue as sooner or later community will realize that this issue is a thing, and may come up with their own solution that breaks this code.

For now, I suggest reverting the TS patches. I'll let you know if I have a promising fix some time in future.

@vire
Copy link
Owner

vire commented Apr 22, 2017

@foxbunny thanks for your feedback, I have/had the same issues with Vue.js and Typescript, from a certain it get too complex and complicated with all the webpack tweaks (vue-loader, ts-awesome-loader which was at that time not supported)

Long story short, I'm convinced that using Vue with TS brings more trouble into the project than it solves. If someone want's to use TS I highly would recommend him TS + Angular which is fully supported or React/Redux + TS.

@foxbunny
Copy link
Contributor Author

I generally don't have issues with Vue and TS combo as long as everything is being done by webpack (e.g., karma-webpack plugin works really well).

@patrickhousley
Copy link

For anyone finding this bug report, I am able to work around the issues using the below Jest mock:

jest.setMock('vue', (() => {
  const Vue = require('vue');
  return {
    default: Vue,
    Vue
  };
})());

TSConfig:

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "alwaysStrict": true,
    "baseUrl": "",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "importHelpers": true,
    "module": "es6",
    "moduleResolution": "node",
    "newLine": "LF",
    "noEmitHelpers": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true,
    "strictNullChecks": true,
    "target": "es5",
    "lib": [
      "dom",
      "es5",
      "es2015",
      "es2016",
      "es2017"
    ],
    "paths": {
      "src/*": [
        "./src/*"
      ]
    }
  }
}

Jest configuration:

  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,ts}",
      "!src/*.{js,ts}",
      "!src/**/*.spec.{js,ts}",
      "!**/*.interface.ts",
      "!src/test-lib/**/*.ts"
    ],
    "collectCoverage": true,
    "coverageReporters": [
      "lcov"
    ],
    "coverageDirectory": "./coverage",
    "globals": {
      "__TS_CONFIG__": "tsconfig.json",
      "__TRANSFORM_HTML__": true
    },
    "moduleDirectories": [
      "node_modules",
      "<rootDir>/"
    ],
    "moduleFileExtensions": [
      "ts",
      "js"
    ],
    "moduleNameMapper": {
      "^vue$": "vue/dist/vue.common.js"
    },
    "setupTestFrameworkScriptFile": "<rootDir>/src/setup-jest.ts",
    "testRegex": "\\.spec\\.(ts|js)$",
    "transform": {
      ".js$": "<rootDir>/node_modules/babel-jest",
      ".vue$": "<rootDir>/node_modules/jest-vue-preprocessor",
      ".ts$": "<rootDir>/node_modules/ts-jest/preprocessor"
    }
  }

@blocka
Copy link

blocka commented Jul 9, 2017

Most issues I can get around by using vue.esm and letting babel-jest go into node_modules/vue. I have one big deal breaker however. The problem is illustrated in this jest test: https://github.com/blocka/strange-jest-behavior/blob/master/src/test.test.ts

Basically, in certain cases, the <script lang="ts"> get's ignored completely.

@DorianGrey
Copy link

The problem should be this line:

const transformedScript = script ? transforms[script.lang || 'babel'](script.content) : '';

Basically, the content of the script tag is handled over here, so things should fail in one of these circumstances:

  • The content is not recognized correctly.
  • There is no content at all, but only an external reference (which is allowed and valid - see attribute src).

@blocka
Copy link

blocka commented Jul 18, 2017

@foxbunny does it make sense to run the code through babel after TS? When everything is esm (jest is pointing to vue.esm, and typescript is generating es2015 modules), we wind up with a module that jest doesn't understand.

I'm not sure exactly when in the pipeline babel-jest kicks in, but seems that it is not in the right place. However, calling transformBabel right after compiling the TS will compile the module to commonjs (assuming the correct setting in .babelrc).

I've tried this out locally and it seems to solve all issues.

@foxbunny
Copy link
Contributor Author

@blocka The ts-jest guys are doing something like that, and it seems to help. Probably why it worked for you as well.

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

No branches or pull requests

5 participants