For example ...
index.ts
import { x } from "./other-funcs";
function y() {
alert("test");
}
x(y);
other-funcs.ts
import { z } from "some-module";
export function x(callback: () => void): void {
z();
callback();
}
(Note that "other-funcs.ts" uses an import statement to import a function from some other module.)
I'd like to compile index.ts
and have it result in a JS file which can be directly included in an HTML file, e.g. <script src="index.js"></script>
, and have it immediately execute in the browser (show the alert).
sample output
function x(callback) {
callback();
}
function y() {
alert("test");
}
x(y);
I can't seem to get the proper TS config to get this outcome. Please advise.
Note: This is not the same as this question because I need to use import
, etc. I just want the result to be simple JS output without a module loader.
Since TypeScript can’t locate such module files at compile-time, they do not become part of the compilation. Therefore, it becomes your responsibility to manually include these module files using files and include compiler-options of the tsconfig.json ( see the compilation lesson (coming soon) ).
TypeScript’s Module Output Options. There are two options which affect the emitted JavaScript output: target which determines which JS features are downleveled (converted to run in older JavaScript runtimes) and which are left intact. module which determines what code is used for modules to interact with each other.
In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).
TypeScript consists of a few parts. The first is the TypeScript language — this is a new language which contains all JavaScript features . Check out the specs for more information. The second is the TypeScript compiler, tsc (the type system engine) which is a compilation engine that builds ts files and yields js files.
Whenever you use import
it will always build out to a module. You can however use namespaces
alongside "module": "system"
, this can then be output to a single file (or multiple files).
so, for a very basic project you would have the following:
{
"compilerOptions": {
"target": "es2016",
"module": "system",
"outFile": "./lib.js"
},
"include": [
"./**/*.ts"
]
}
Next you would then create your files to look like this:
namespace MyNamespace {
// This is a private method that cannot be accessed in other files
// the reason for that is because it isn't exported.
function y() {
alert("test");
}
x(y)
}
namespace MyNamespace {
// This method can be referenced in other files because it is exported.
export function x(callback: () => void): void {
callback();
}
}
var MyNamespace;
(function(MyNamespace) {
function x(callback) {
callback();
}
MyNamespace.x = x;
})(MyNamespace || (MyNamespace = {}));
var MyNamespace;
(function(MyNamespace) {
function y() {
alert("test");
}
MyNamespace.x(y);
})(MyNamespace || (MyNamespace = {}));
You can then use these methods/functions outside of the namespace by simply by calling them via the namespace:
MyNamespace.y()
MyNamespace.x(MyNamespace.y)
// etc.
To use import
within your project, you will need a 3rd party library requirejs. This will allow you to use modules within the browser.
So, to do this, we first need to have the proper config file which looks similar to above the only difference is "module": "amd"
.
{
"compilerOptions": {
"target": "es2016",
"module": "amd",
"outFile": "./lib.js"
},
"include": [
"./**/*.ts"
]
}
Next we need to create the proper typescript main file:
requirejs(['functions'], function (util: any) {
function y() {
alert("test");
}
util.x(y)
})
Since this is using a 3rd party library, it is initialized differently (using requirejs()
). This tells requirejs that this is the entry point to the application thus this is only needed once.
export function x(callback: () => void): void {
callback();
}
define("functions", ["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function x(callback) {
callback();
}
exports.x = x;
});
requirejs(['functions'], function (util) {
function y() {
alert("test");
}
util.x(y);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>
If your script is in an external file, you can use data-main
on the script tag, requirejs will then load the file automatically.
<script data-main="./lib" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>
This feature is still experimental, and not supported in all browsers. All you need to do is use the type="module"
attribute on your script tag:
<script type="module" src="./path/to/main.js"></script>
Note: that here we use both a different target
and module
, and also an outDir
.
Note: es2016
is not a valid module type.
{
"compilerOptions": {
"target": "es2016",
"module": "es2015",
"outDir": "./lib"
},
"include": [
"./**/*.ts"
]
}
Note: import
uses a .js
extension otherwise the browser can't load it unless you have rewrite rules in place.
import { x } from './functions.js'
function y() {
alert("test");
}
x(y)
export function x(callback: () => void): void {
callback();
}
This will output nearly the same as the ts files (Stackoverflow doesn't support external js files unless they are hosted somewhere, so no snippet here):
// index.js
import { x } from './functions.js';
function y() {
alert("test");
}
x(y);
// functions.js
export function x(callback) {
callback();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With