Understanding TypeScript and SystemJS WITHOUT Angular

I recently studied and made simple “hello worlds” with TypeScript. There is something that I think I can’t wrap my head around, and here's how to use System.js with TypeScript. Every tutorial or demo there on the Internet is about Angular2, and I don't want to participate in Angular 2.

As an example, I have the following project structure:

RootFolder | | _lib | ...... ts (where .ts files are) | | components (where compiled .js files are) | libraries | ......... systemjs (where system.js is) | | index.html | tsconfig.json 

My tsconfig.json file looks like this:

 { "compileOnSave": true, "compilerOptions": { "noImplicitAny": true, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "target": "es5", "module": "system", "moduleResolution": "node", "outDir": "./components" }, "exclude": [ "node_modules", "wwwroot" ], "include": [ "./_lib/ts/**/*" ] } 

TypeScript compilation works as expected, and there is no problem with this. I created a simple class called "Alerter" containing the following code:

 //alerter.ts class Alerter { showMessage(): void { alert("Message displayed."); } } export default Alerter 

And app.ts (which is my "main" application file) with the following code:

 //app.ts import Alerter from "./alerter"; console.log("app.js included & executed"); function test() { console.log("test called"); const alt = new Alerter(); alt.showMessage(); }; 

And in my index.html, I just want to import this .js application into System.js and just want to call the "test" function from the console. But that does not work. No matter what I did, I just can't access this feature. I see that the first console.log is running, but when I try to call test () from the Chrome console, it is undefined.

If I remove the "alerter" class dependency from my main.ts, everything will work. Since compiled app.js contain only console.log calls and function definitions.

Here are my calls to System.js in index.html

 System.config({ packages: { "components": { defaultExtension: "js" } } }); System.import("components/app"); 

I am really desperate now and think I should just go back to the days of jQuery. It is so simple but cannot make it work.

+5
source share
1 answer

I see what is happening here. This is due both to the proper use of the TypeScript export keyword and SystemJS.

From your description, you basically want to use SystemJS to import a JavaScript file, similar to using only the <script> , and then use its globally defined functions.

But that means you need to know how TypeScript will compile your files. The documentation at https://www.typescriptlang.org/docs/handbook/modules.html says:

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

This is what you do. The app.ts file has one import , and the alerter.ts file has one export statement, which must be compiled as modules. Then from your tsconfig.json I see that you are using the system format (however, it does not matter here).

One of the main advantages of modules is that they do not pass any global objects outside their area. Therefore, when you call System.import("components/app") , the test() function only exists inside this module. But you can export the function and call it after loading the module:

This means that you need to export the function first:

 // app.ts export function test() { ... }; 

Then System.import() returns the promise that is resolved with the module export object, so we can call the test() method.

 System.import("components/app").then(function(m) { m.test(); }); 

It really works the way you expect.

However, it looks like you wanted to define the test() function globaly. In this case, you need to define the function on the global window object yourself:

 // app.ts function test() { ... } declare const window; window.test = test; 

Now you can use it whenever you want after importing the package:

 System.import("components/app").then(function(m) { test(); }); 

SystemJS has several ways to manipulate global objects, but I don’t think there is an easier way to use them when your imported package has dependencies that also need to be resolved (otherwise look at this, but this is not your use -case https: / /github.com/systemjs/systemjs/blob/master/docs/module-formats.md#exports ).

+2
source

Source: https://habr.com/ru/post/1266115/


All Articles