requirejstypescriptweb-worker

How can typescript import external modules in a web worker


I am trying to use external modules in typescript in a web worker and am having problems. All the code for a test example is at www.windward.net/temp/WebWorkerRequireJs.zip (key ones listed below).

The typescript I want (and this works fine in the main thread is:

import myClass = require('my-class');
class WorkerThread {
}
self.onmessage = function (e) {
    console.log("client received message = " + e.data);
    var mc = new myClass.MyClass();
    console.log("worker thread toUpper = " + mc.toUpper("dave"));
    self.postMessage("from client");
}

This generates the following javascript which fails as define is not defined:

define(["require", "exports", 'my-class'], function(require, exports, __myClass__) {
    var myClass = __myClass__;

    var WorkerThread = (function () {
        function WorkerThread() {
        }
        return WorkerThread;
    })();
    self.onmessage = function (e) {
        console.log("client received message = " + e.data);
        var mc = new myClass.MyClass();
        console.log("worker thread toUpper = " + mc.toUpper("dave"));
        self.postMessage("from client");
    };
});
//# sourceMappingURL=worker-thread.js.map

So step 1, I added importScripts and called this .js file:

importScripts('../../scripts/require.js');

define(["require", "exports", 'my-class'], function(require, exports, __myClass__) {
    var myClass = __myClass__;

    var WorkerThread = (function () {
        function WorkerThread() {
        }
        return WorkerThread;
    })();
    self.onmessage = function (e) {
        console.log("client received message = " + e.data);
        var mc = new myClass.MyClass();
        console.log("worker thread toUpper = " + mc.toUpper("dave"));
        self.postMessage("from client");
    };
});
//# sourceMappingURL=worker-thread.js.map

This did not work and gave the error:

Uncaught Error: Mismatched anonymous define() module: function (require, exports, __myClass__) {
    var myClass = __myClass__;

    var WorkerThread = (function () {
        function WorkerThread() {
        }
        return WorkerThread;
    })();
    self.onmessage =...<omitted>...ch 

I then switched "define" to "require" and this worked:

importScripts('../../scripts/require.js');

require(["require", "exports", 'my-class'], function(require, exports, __myClass__) {
    debugger;
    var myClass = __myClass__;

    var WorkerThread = (function () {
        function WorkerThread() {
        }
        return WorkerThread;
    })();
    self.onmessage = function (e) {
        console.log("client received message = " + e.data);
        var mc = new myClass.MyClass();
        console.log("worker thread toUpper = " + mc.toUpper("dave"));
        self.postMessage("from client");
    };
});
//# sourceMappingURL=worker-thread.js.map

Which leads to the question - how do I get typescript to generate this so it runs. Is the solution to set up a main javascript file that is the initial web worker app that then calls the typescript part? And if so, how do I set that up?

Or is the solution to somehow tell the typescript compiler to change from define to require and insert importScripts()?

Update: It looks like a (best?) solution is the main web worker file is a javascript file. That has the importScripts() and a require of the main typescript class. You create that class and it runs from there. And at that point the typescript "import" which cuses "define" all works. So far...


Solution

  • The worker file is not going to be loaded by an AMD loader and will be loaded by the browser. So you need to break out of AMD code generation and use raw "require" calls yourself.