I am using imports and exports because references are said to be outdated. However, I want to compile to one file, and I'm using the "system" module, but it is turning everything into a module even if nothing is being exported. If anything is imported, the code is not executed, but if nothing is imported or exported, the code is executed. I need to import files to be able to use them, but I cannot because the code becomes a module function.
This is my tsconfig.json:
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": false,
"outFile": "{PATH}"
}
}
My TypeScript code:
import { Button } from "UI/Button";
new Button("Hello World!");
console.log("HELLO!");
The compiled code turns it into this:
System.register("Main/main", ["UI/Button"], function (exports_4, context_4) {
"use strict";
var Button_1;
var __moduleName = context_4 && context_4.id;
return {
setters: [
function (Button_1_1) {
Button_1 = Button_1_1;
}
],
execute: function () {
new Button_1.Button("Hello World!");
console.log("HELLO!");
}
};
});
If I remove the import and only keep the console.log:
console.log("HELLO!");
It removes everything without the import, even the previous modules because I guess it does not detect them being used.
I am assuming I am misunderstanding how the import/export system works? I want to be able to run functions and import/export files, but as of now it looks like I can only import/export files, not run them. I want all of it to be compiled into one file, too. Any help would be appreciated!
CodePudding user response:
You'll need to run these scripts from your HTML file, invoking them using SystemJS (as in your tsconfig.json).
The presence of import
or export
is one of the ways that TypeScript can infer whether you are writing a script versus a module. The drastic change in compiled output comes from TypeScript interpreting your file as a module if and only if it has import
or export
statements.
The idea behind modules, from Mozilla's cartoon introduction:
Modules give you a better way to organize these variables and functions. With modules, you group the variables and functions that make sense to go together.
This puts these functions and variables into a module scope. The module scope can be used to share variables between the functions in the module.
But unlike function scopes, module scopes have a way of making their variables available to other modules as well. They can say explicitly which of the variables, classes, or functions in the module should be available.
The whole idea behind Modules is that you can defer the loading that happens as part of your UI/Button
module (or any others that you write) until you need it. That UI/Button
initialization happens exactly once, and only gives you access to the variables, functions, and classes that you export
. (That said, modules can also have "side effects" like your console.log
: Those aren't exported values, they're just visible things that happen when the module is executed.) Furthermore, each module executes within its own namespace (here, its own execute
function), so if one module defines a counter
variable it won't interfere with a separate module's counter
variable.
You've chosen the system
TypeScript module format, otherwise known as SystemJS. In doing so, you're signing up to have SystemJS manage your module loading, which would allow you to call System.import
to load your Main/main
module from the compiled Javascript you've posted. At that point you would see the output you expect because you've specifically requested it. When specifying an outFile
as you have, you can also pick AMD (which will also require specifying your "entry point") or "None" (which will prohibit import
and export
).
Once you have a better understanding of modules, you can look into a "bundler" like Webpack. These systems traverse all of your modules--which might be one file, or might be many--and bundle them together into a single file as you've described. You can even tell Webpack which module you intend as an entry point, and it will run that automatically as soon as the script loads--exactly like an old-fashioned JS script would.