How can I compile my Typescript into a single JS file with no module loading system?
Asked Answered
W

6

24

I have a small Typescript project of about 10 ts files. I want to compile all my files into es5 and into a single es5 file called all.js.

Currently, with my tsconfig.json set up as

{
  "compilerOptions": {
    "module": "system",
    "target": "es5",
    "outFile": "./all.js"
}

everything is getting compiled, but each file is being wrapped by

System.register("SomeTSFile", [], function(exports_4, context_4) {
...
}

SystemJS looks cool but I am not in the mood to learn it now and I don't believe it is necessary. If I could get all my JS into one file, that will be perfectly sufficient for my needs.

If I remove "module": "system",from my compiler options, my all.js file comes out completely blank. Apparently, this is because for some reason, you cannot use "modules": none when outputting to one file. (I don't get why)

How can I compile all the TS into one JS file without having to involve SystemJS or any other complications?

Wanton answered 7/9, 2016 at 2:42 Comment(2)
Every .ts file is a module. If one .ts file references another, you can not make it work without module loading system. If you don't want it, concatenate all your .ts file into one and compile that file. This might require changing your code though.Stinger
Another option is to set "module": "amd", then you will need AMD loader instead of SystemJS.Stinger
J
10

The contents of your .ts files determines if this is possible or not...

If you avoid turning your TypeScript code a module (by avoiding top-level import or export declarations), the output from single-file compile will not include any dependency on a module loader.

For example: typescript compiler itself is written without any top-level import or export declarations, and thus compiles into a single-file .js without any loader dependency.

Note that its use of export within a namespace is not a "top level" export. Imports inside a namespace are possible but severely limited: an example here

"In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module."

The typescript handbook

Jerkin answered 13/9, 2016 at 2:20 Comment(4)
Hmmm so I can have imports within a module section but not outside?Wanton
I don't think its that simple @CodyBugstein. Some forms of import are OK, but importing from a module isn't (if you are trying to avoid depending on a module loader.)Jerkin
Note that you can use triple-slash directives to reference types in other typescript files without using imports, but that this does not take care of loading the other files (but of course compiling down to a single .js can make that moot.)Jerkin
Ok i will try thatWanton
D
7

Use triple slash directives for the typescript-compiler (tsc)

Triple-slash references instruct the compiler to include additional files in the compilation process.

index.ts:

/// <reference path="./domHelpers.ts" />

function add(a: number, b: number): number {
    return a + b;
}

q('#sum').textContent = add(2, 5).toString();

domHelpers.ts

function q(query: string): Element {
    return document.querySelector(query);
}

function qa(query: string): NodeListOf<Element> {
    return document.querySelectorAll(query);
}

Build step:

tsc --out bundle.js ts/index.ts

Will produce bundle.js with contents

function q(query) {
    return document.querySelector(query);
}
function qa(query) {
    return document.querySelectorAll(query);
}
/// <reference path="./domHelpers.ts" />
function add(a, b) {
    return a + b;
}
q("#sum").textContent = add(2, 5).toString();
Demarcusdemaria answered 28/4, 2019 at 21:31 Comment(0)
A
2

Here's the method I ended up using. This process will create a file that can be linked with a <script src="myModuleName.min.js"></script> tag on an HTML page for use in a browser.

  1. Install rollup and plugins (many plugins listed here are optional but this config should cover any way in which you use modules)

npm install rollup-plugin-buble rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-typescript rollup-plugin-uglify typescript --save-dev


  1. This example rollup configuration file shows how to prevent rollup from also bundling your dependencies. In this case, I'm using jQuery and Angular, but I don't want to include that in the package I'm providing to users--so I list them as external, and they both happen to have a global variable--this example file shows how to deal with that scenario:

rollup.config.js

'use strict';

import 'rollup';
import typescript from 'rollup-plugin-typescript';
import buble from 'rollup-plugin-buble';
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import uglify from 'rollup-plugin-uglify';
import {minify} from 'uglify-js';

/**
 * Default/development Build
 */
const config = {
    entry: 'src/index.ts',
    exports: 'auto',
    globals: {
        'jquery': '$',
        'angular': 'angular'
    },
    external: ['angular', 'jquery'],
    targets: [{dest: 'dist/myModuleName.js', format: 'umd', moduleName: 'myModuleName', sourceMap: true}],
    plugins: [

        typescript({
            typescript: require('typescript')
        }),
        buble(),
        nodeResolve({
            jsnext: true,
            main: true
        }),
        commonjs({
            namedExports: {
                'node_modules/jquery/dist/jquery.min.js': ['jquery'],
                'node_modules/angular/angular.min.js': ['angular']
            }
        })
    ]
}

// Minified JS Build
if (process.env.BUILD === 'minify') {
    config.targets = [{dest: 'dist/myModuleName.min.js', format: 'umd', moduleName: 'myModuleName', sourceMap: false}];
    config.plugins.push(
        uglify({}, minify)
    );
}

// Report destination paths on console
console.info(`\u001b[36m\[Rollup ${process.env.BUILD} build\]\u001b[97m \nConverting Typescript from ${
config.entry} to javascript, exporting to: ${config.targets[0].dest}`);

export default config

  1. Add scripts to package.json
    "scripts": {
        "build": "rollup -c rollup.config.js --no-conflict --environment BUILD:development",
         "minify": "rollup -c rollup.config.js --environment INCLUDE_DEPS,BUILD:minify"
    }

  1. Provide a file for rollup to consume:

src/index.ts

`export * from './myModule';`

  1. Optionally use a file to collect your modules for export if you're writing a library, these are the functions you intend to be publically available.

src/myModule.ts

export {myOtherClass, myFunction} from './myUtils/myFile';
export * from "./myUtils/myOtherFile";

  1. run npm run build or npm run build && npm run minify to also get the minified version.
Anniceannie answered 9/1, 2017 at 23:2 Comment(0)
C
2

Using TypeScript 3.4, I have no problem transpiling many *.ts scripts into a single .js output file.

Here is the minimalist version of the tsconfig.json I am using with tsc --project src/test/tsconfig.json

{
  "compilerOptions": {
    "outFile": "../../build/test/Code.js",
    "module": "none",
    "skipLibCheck": true,
  },
  "include": ["**/*.ts"],
}
Connivent answered 28/4, 2019 at 22:23 Comment(2)
but then how do you import from one file to the other?Wanton
You don't have to use import less require with this settings. The output Code.js will be the concatenation of all valid source files. Valid source files are defined with the include and files properties of your tsconfig.json. The order in which files are concatenated can be controlled using the files property and /// <reference path="some.ts" /> directives. You can look at this repository for complete sample.Connivent
W
1

Can you use the compiler itself? - as a post build process. TSC takes arguments allowing you to do this.

tsc --out compiledSingleFile.js one.ts two.ts

Or by using Gulp in your build pipeline -

https://www.npmjs.com/package/gulp-tsc

Wallet answered 7/9, 2016 at 2:46 Comment(1)
I am doing this but it forces me to use SystemJSWanton
H
1

This is how i did it

  1. tsconfig file should set moduleResolution to classic
  2. tsconfig file should set module to none
  3. use Typescript namespace syntax and keep all your files in same namespace

Done !!!

this sol will only work who want no module system, with this sol you won't be able to use import export module system syntaxes

Hubbs answered 25/9, 2020 at 11:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.