How to compile TypeScript code in the browser?
Asked Answered
R

3

69

Is it possible to run the TypeScript compiler in the browser for transpiling TS to JS 100% in the browser. The use case would be implementing an online TypeScript IDE that runs 100% client side and it has a "Play" button to execute the project. So I need to transpile the project to JavaScript in order for the browser to execute the code.

I presume it should be as simple as loading the relevant typescript JS files, creating an instance of the right class (compiler?) and calling a method or two.

What would be the means suitable to load the Compiler in the browser? Where is the TypeScript Compiler API Reference Documentation ? Where should I start digging in ?

This isn't asking for any specific tool, but ANY way to do this with this particular computer language, and thus is on topic.

Rawls answered 15/4, 2014 at 6:0 Comment(9)
Why would you want to do that? You should use TypeScript for development only, have a file watcher (or have a build script) to compile the ts file to js file when the files is changed, and load the compiled js to the browser (both in development and production). Since the compiler adds reference to the source map (compile it using the --sourcemap option) you'll be able to debug in the browser on the TypeScript file, so you get it all...Sultry
For many reasons, but yes for production code you wouldn't normally want to. But some reasons could be building a playground like that on typescriptlang.org, or in building a web IDE, or web based compiler, or maybe a compiler than then copies files to servers via cloud services. In my case i'm just looking for a pithy example without the full burden of TSC to do compilation of a single file. My scenario wasn't actually in the browser, but in a PowerShell script hosting the Chakra JS engine, but the simplest way to get there was a simple browser based script.Rawls
A comment, because the Q is closed: You're looking for the transpile() method on the default exported module of the Typescript npm package. import * as TS from 'typescript'; TS.transpile(sourceTS) -> returns transpiled JS. github.com/Microsoft/TypeScript/blob/master/lib/…Dogs
It's sad so many useful questions are closed as off-topic. You may ask about a string manipulation function as long as it is simple, like how to reverse a string. As soon as it is a complex function like transpile, it is off topic.Primate
This is what I have: a typescript playground in the browser cancerberosgx.github.io/typescript-in-the-browser/… BTW I'm sad you have closed this question, since this kind of questions, although incorrect, are one of the few places when beginers can get started with compiler API which has insufficient high level docs, yet, i hope. thanksArianna
@NitzanTomer are you 100% sure codepen compiles your ts code server side ? Now that IDEs in the web are more common I think this question is relevant given that ts is a language service and given editors like monaco :)Arianna
I tried to answer this question here: #46059813 hope we can share more experiences and don't close that one tooArianna
To @JeremyJStarcher and other voters, I don't understand why this is considered a library recommendation question, can you explain?Dicrotic
@Dogs I think you mean this? Remember to specify a specific commit / tag when you link to Github, because as the source code changes the function, etc. you're talking about might not still be line 3,343 or whatever you linked to.Dicrotic
M
26

You can use typescript-script : https://github.com/basarat/typescript-script

However do not do this in production as it is going to be slow.

You can use webpack (or a similar module bundler) to load npm packages in the browser.

Monosymmetric answered 15/4, 2014 at 7:8 Comment(6)
Why would it be unsafe?Sympathize
@DavidGiven I don't know why I thought that he will be serving TypeScript input by the user. So removed. Thanks!Monosymmetric
For transpiling in the browser you don't need to do any hack - just include node_modules/typescript.js in your html file will allow you to use the COmpiler API. Here is a playground that transpile to js 100% in the browser : cancerberosgx.github.io/typescript-in-the-browser/…Arianna
I re-wrote it to a working up-to date lib last night for same cause. It also resolves import dependencies now.Odessa
Haha, @ArturKlesun, I did the same thing! Yours looks a bit more elegant (I flat-out did not allow circular dependencies), but how do you handle lib imports like lib.dom.d.ts? Is yours able to have typescript embedded in the html as you would js too? It's so funny we did this a week apart on a topic that hadn't been touched for over a yearCorpus
Lol indeed =-D. And the question got re-opened, seems like it was my birthday yesterday... Answering your questions here: github.com/klesun/ts-browser/issues/1Odessa
O
31

Transpiling ts to js is as simple as loading the typescript.js file from typescript repo or npm, and using it's window.ts.transpile(tsCode)

JSFiddle

<script src="https://unpkg.com/typescript@latest/lib/typescript.js"></script>
<script>
const tsCode = 'let num: number = 123;';
const jsCode = window.ts.transpile(tsCode);
document.write(jsCode);
</script>

Outputs:

var num = 123;

You can also pass the ts compiler options object as second argument like:

ts.transpile(tsxCode, { jsx: "react", target: "es2015" });

Though for meaning of values you'll likely have to dive into the source code.




Since this question got re-opened (just as planned >:D), I'm also re-posting my comment here.

@basarat's solution was great; even though his lib is outdated and abandoned, it helped me a lot in writing another, self-sufficient modern lib with support for sub-dependencies: ts-browser

Usage: (given you use relative paths in all your ts files)

<!-- index.html -->
<script type="module">
    import {loadModule} from 'https://klesun.github.io/ts-browser/src/ts-browser.js';
    // language=file-reference
    const entryScriptPath = './index.ts';
    loadModule(entryScriptPath).then(indexModule => {
        return indexModule.default(document.getElementById('composeCont'));
    });
</script>
// index.ts
import {makePanel} from './utils/SomeDomMaker'; // will implicitly use file with .ts extension

export default (composeCont) => {
    composeCont.appendChild(makePanel());
};
Odessa answered 23/1, 2020 at 8:54 Comment(8)
I couldn't find the compiler options that does type check. window.ts.transpile('let num : number= "1232";', {noEmitOnError: true, strict: true}) But it wouldn't failGoatherd
Looks like ts.transpile/ts.transpileModule only does transpilation without type checking by design. There are possibly some other methods in window.ts that would allow type checking, but finding that out would require some research...Odessa
may it be, that "typescriptServices.js" is no longer available for TS versions 5.x and above? The latest one I could find was for 4.9.5. Is there an alternative?Dismissal
Yeah, looks like it. Hopefully someone will eventually update the answer to reflect the source of that module in latest typescript.Odessa
It looks like this can be replaced by just using typescript.js github.com/microsoft/TypeScript/issues/50758Yaw
@douglas-gaskell thanks, you're my hero! Updated the answer to typescript.js, seems to work fine in all versions of typescript.Odessa
@Odessa The output when I run it for TSX is really weird, any chance you can take a look? :please: added source and output here: pastebin.com/xMe0cedyAlmazan
Answer to my own question - I needed to add const jsCode = window.ts.transpile(tsCode, { jsx: 'react'});Almazan
M
26

You can use typescript-script : https://github.com/basarat/typescript-script

However do not do this in production as it is going to be slow.

You can use webpack (or a similar module bundler) to load npm packages in the browser.

Monosymmetric answered 15/4, 2014 at 7:8 Comment(6)
Why would it be unsafe?Sympathize
@DavidGiven I don't know why I thought that he will be serving TypeScript input by the user. So removed. Thanks!Monosymmetric
For transpiling in the browser you don't need to do any hack - just include node_modules/typescript.js in your html file will allow you to use the COmpiler API. Here is a playground that transpile to js 100% in the browser : cancerberosgx.github.io/typescript-in-the-browser/…Arianna
I re-wrote it to a working up-to date lib last night for same cause. It also resolves import dependencies now.Odessa
Haha, @ArturKlesun, I did the same thing! Yours looks a bit more elegant (I flat-out did not allow circular dependencies), but how do you handle lib imports like lib.dom.d.ts? Is yours able to have typescript embedded in the html as you would js too? It's so funny we did this a week apart on a topic that hadn't been touched for over a yearCorpus
Lol indeed =-D. And the question got re-opened, seems like it was my birthday yesterday... Answering your questions here: github.com/klesun/ts-browser/issues/1Odessa
B
1

I wrote this specifically for the purpose of compiling TypeScript in the browser so that I could write quick and simple examples to share.

https://github.com/Sean-Bradley/text-typescript

Usage,

<script type="text/typescript">
    // Your TypeScript code here
</script>

And include dependencies.

<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]"></script>

A complete example you can copy/paste into a HTML doc and try locally.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>"text/typescript" example</title>
        <meta name="description" content="Transpiling and executing TypeScript in the browser" />
        <style>
            body {
                overflow: hidden;
                margin: 0px;
                font-size: 15vw;
            }
        </style>
        <script type="text/typescript">
            function foo(bar: string) {
                return "Hello " + bar;
            }

            let baz = "World!";

            document.getElementById("root").innerHTML = foo(baz);
        </script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
        <script defer src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
    </head>
    <body>
        <div id="root"></div>
    </body>
</html>

And you can see it working here, right now, today.

https://editor.sbcode.net/f1f4b5a73ec40283d1ddb37bb1e71f7e4e31b487

Blackington answered 9/1 at 9:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.