7

I am trying to write my frontend code in Typescript and want to export the code, that my browser can load in <script src="..."></script>.

I did so by way of browserify and tsify. My trouble is that not on my code is accessible in the global namespace. Loading the script in a <script> tag will execute it, sure, but what if I intend it to be loaded like a library of functions that can be used in inline <script>s or similar?

Update

An example would be

index.ts

function foo(): void {
    console.log("bar");
}

Compiling with the following conf produces the following javascript

tsconfig.json

{
    "compilerOptions": {
        "module": "UMD",
        "target": "es5",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "sourceMap": true
    }
}

index.js

function foo() {
    console.log("bar");
}

This is fine. However, if index.js imports something, e.g. my notification function, then I get this

(function (factory) {
    if (typeof module === 'object' && typeof module.exports === 'object') {
        var v = factory(require, exports); if (v !== undefined) module.exports = v;
    }
    else if (typeof define === 'function' && define.amd) {
        define(["require", "exports", "./notifications"], factory);
    }
})(function (require, exports) {
    "use strict";
    var notifications_1 = require("./notifications");
    notifications_1.notification("blerp");
    function foo() {
        console.log("bar");
    }
});

Now foo is wrapped in some scope, and is not available when I load it on my website: <script src="require.js" data-main="index"></script>

foo is undefined
Eldamir
  • 9,888
  • 6
  • 52
  • 73
  • Just to be clear, you multiple typescript files and you're using browserfy to compile them. And then, you want those functions to be available globally? – thitemple Apr 21 '16 at 12:43

1 Answers1

4

Until module loading lands in browsers as a native JavaScript feature, you can use a library such as RequireJS or SystemJS to load modules.

When using RequireJS, you simply pass the compiler option:

-module UMD

And then point RequireJS at your main file:

<script src="require.js" data-main="app"></script>

Modules are then loaded asynchronously on demand and life is good.

Fenton
  • 241,084
  • 71
  • 387
  • 401
  • 2
    Is module loading even to be desired? If my main file imports/requires some files, rather than leaving the "require" statement in the transpiled code, couldn't the required files just be concatenated – Eldamir Apr 21 '16 at 12:26
  • Yes - module loading is so derirable it is becoming a native ECMAScript feature. File mergining only gets you so far... https://www.stevefenton.co.uk/2016/02/bundling-is-the-new-parrot-word/ *"The difference between bundling and module loading is less visible at the far left of the scale (i.e. small amounts of code) and ends massively in favour of modules at the far right of the scale."* – Fenton Apr 21 '16 at 15:26
  • Good read. So now I have my .ts source file in my static folder alongside require.js. I've compiled the .ts file with `-module UMD`. Now I load the compiled .js file with require.js, as you showed me. However, I still cannot access the functions. They seem to be in a hidden scope – Eldamir Apr 25 '16 at 08:11
  • Can you share a short example of your code. When you compile using UMD, you should see in the JavaScript that the module you import is getting assigned to a variable. If you share an example of how you are importing, that will help. – Fenton Apr 25 '16 at 13:29
  • I updated my question with some code examples. Hope it sheds some light on the situation. As a temporary fix, I am writing small ts modules that import my library and execute the desired functions, so that I can import such a module when I need it, instead of having this code in script tags on each page. I guess that is alright too, but not what I wanted initially – Eldamir Apr 26 '16 at 09:14
  • Its a little more complex than that. I wrote my solution to setting up with requireJs at https://stackoverflow.com/a/48436147/1019307. – HankCa Jan 29 '18 at 06:36