jeorfevre
jeorfevre

Reputation: 2316

Could not find my javascript classes built from Typescript

Situation

I am working on the frontsside of a webapp with typescript that I compile into JS. I want to run qunit test on the js that is generated. My typescript is merge in one file using browserify I want to run test upon my js object. I am runing the js without node in a tomcat webserver using a war package.

Problem

I could not find the classes js that I have generated (problem of access or hidden object....) ? Animal class is not accessible when I try to use animal.js in a js script!? How to access this class in a js? I want to run with no errors, animal.test.html.

animal.ts

export class Animal {

    name:string;    

    constructor(name:string) {
        this.name=name;
    }

    public run(){
        console.log('${this.name}:Animal runs.');
    }

    public eat(){
        console.log('${this.name}:Animal eats.');
    }

    public sleep(){
        console.log('${this.name}:Animal sleeps.');
    }
}

animal.js (from animal.ts)

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";
var Animal = (function () {
    function Animal(name) {
        this.name = name;
    }
    Animal.prototype.run = function () {
        console.log('${this.name}:Animal runs.');
    };
    Animal.prototype.eat = function () {
        console.log('${this.name}:Animal eats.');
    };
    Animal.prototype.sleep = function () {
        console.log('${this.name}:Animal sleeps.');
    };
    return Animal;
}());
exports.Animal = Animal;
},{}]},{},[1]);

animal.build.js

var browserify = require('browserify');
var tsify = require('tsify');

browserify()
    .add('src/test/typescript/animal.ts')
    .plugin(tsify, { noImplicitAny: true })
    .bundle()
    .on('error', function (error) { console.error(error.toString()); })
    .pipe(process.stdout);

Build run command I use node with browserify as referenced in the typescript lang site

node animal.js >  src/test/typescript/animal.js

animal.test.js

QUnit.module( "Form test" );

QUnit.test( "hello test2", function( assert ) {
 var a = new Animal("toto"); 

  assert.ok( a!==undefined && a!=null);
});

animal.test.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>QUnit Example</title>
  <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-1.23.0.css">
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>

  <script src="https://code.jquery.com/qunit/qunit-1.23.0.js"></script>
  <script src="animal.js"></script>
  <script src="animal.test.js"></script>

</body>
</html>

Qunit response qunit animal ko!

Upvotes: 3

Views: 1652

Answers (1)

mostruash
mostruash

Reputation: 4189

Because you are trying to access window.Animal but it's certainly not there. You need another JS/TS file that you should use with QUnits but don't include in development/production code:

test_main.ts:

import {Animal} from './animal';
window.Animal = Animal; // or global.Animal = Animal
                        // I don't know if browserify converts
                        // "global" to "window" or not.

Now replace .add('src/test/typescript/animal.ts') with test_main.ts.


What was wrong?

If you are using ES6 export/import modules, that means you are using "CommonJS" module system. When you use tsify, Typescript code is converted to node-compatible JS code. Then you use browserify to convert node-compatible JS code to browser compatible JS code. Browser doesn't support CommonJS module system natively. So "browserify" tries to mimic it and that's why you need to provide it a single entry point.

There are other solutions to your problem, e.g. you can write your unit tests in TypeScript or in node world. If you did that, you would access Animal class using import statement.

It's a complicated topic for beginners, I would suggest you to learn what CommonJS is and how browserify/webpack etc. converts it into browser code.


Upvotes: 0

Related Questions