How can I compile my Typescript into a single JS file with no module loading system?
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."
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();
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.
- 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
- 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 Buildif (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 consoleconsole.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
- 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" }
- Provide a file for rollup to consume:
src/index.ts
`export * from './myModule';`
- 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";
- run
npm run build
ornpm run build && npm run minify
to also get the minified version.