Autocallable Typescript file - javascript

Anyone knows how to make a class or function on Typescript that executes its self on document ready?
I have a view, loaded with ajax, and I want to init some components on document ready without using javascript directly.
The Typescript is beeing transpiled to javascript with AMD.
So, if I use imports or exports, all the code is surrounded by a function call.
For example:
Typescript:
import Module from 'module';
class initTest {
public constructor() {
//init something here
}
}
let test = new initTest();
Javascript generated:
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var initTest = /** #class */ (function () {
function initTest() {
//init something here
}
return initTest;
}());
var test = new initTest();
});
//# sourceMappingURL=test.js.map

Related

Basic Understanding - TypeScript and HowTo properly implement JS-Modules into Webproject

I am struggeling with the current situation. Up to today i had my own JavaScript implementation with own methods to load single js files per website - when needed. This way i had a tiny loader script with an scp sha256-checksum in the header which then loaded the "master" script which controlled everything else.
Now i want to go some steps further and a) switch over to modules, because most libs do so too, i was unable to load modules from normal scripts and b) implement typescript into my system.
What starts my script implementation:
/scripts/modules-loader.js
<html>
...
<script async type=module>
"use strict";
import {master} from '/scripts/modules/master-28021723540.js';
new master();
</script>
...
</html>
So far so good. This loader executes as expected, the js file is been loaded and the sha-256 hash from the header is valid.
And now where the struggle begins. This file is been compiled to
/master.ts
export class master {
constructor() {
this.init();
}
async init() {
console.log( "Hello, lets get started...");
}
}
compiled file:
define("wkwussmxlyk4d7ainbsq93pnpnugjs5g", ["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.master = void 0;
class master {
constructor() {
this.init();
}
async init() {
console.log("Hello, lets get started...");
}
}
exports.master = master;
});
with the result that the browser cannot find the module called "master"
Uncaught SyntaxError: The requested module '/scripts/modules/master-28021723540.js'
does not provide an export named 'master' (at (Index):11:9)
However i also tried this, which i found in the internet:
"use strict";
module master {
class master {
constructor() {
this.init();
}
async init() {
console.log( "Hello, lets get started...");
}
}
}
which gets compiled into this
"use strict";
var master;
(function (master_1) {
class master {
constructor() {
this.init();
}
async init() {
console.log("Hello, lets get started...");
}
}
})(master || (master = {}));
which leads to the same result.
How can i get my class get compiled from ts to be able to call it from the loader or in the file itself?
Just for understanding, i dont want to use the "tsc --watch" over my entire project. I am using single js/ts files and compile/optimize them in the request thread and put them into static optimized files afterwards ( if in production ). Keeping this in mind i am also open into different implementations. I am aiming for maximum pagespeed without compromises and my current solution was working very good but just limited because it was unable to load modules, so now i want to switch over to modules only.
i am compiling like this
/usr/bin/tsc --alwaysStrict --strict --module amd --target es2020 /srv/http/domain.local/tmp/domain.local/ncumh5cnk5uq2s7b64oa31cv19agr2s9.ts --outfile /srv/http/domain.local/tmp/domain.local/compiled-ncumh5cnk5uq2s7b64oa31cv19agr2s9.ts
Thanks in advance
Response on answer from #Quentin
/usr/bin/tsc --alwaysStrict --strict --target es6 /srv/http/domain.local/tmp/domain.local/ncumh5cnk5uq2s7b64oa31cv19agr2s9.ts --outfile /srv/http/domain.local/tmp/domain.local/compiled-ncumh5cnk5uq2s7b64oa31cv19agr2s9.ts
i am getting this compilation
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
class master {
constructor() {
this.init();
}
init() {
return __awaiter(this, void 0, void 0, function* () {
console.log("Hello, lets get started...");
});
}
}
and with
export class()
i am getting this:
Cannot compile modules using option 'outFile' unless the '--module' flag is 'amd' or 'system'.
--module amd
This is your problem.
AMD modules use the define syntax and do no have native support in browsers. To use them you’ll need to use something like Require.JS.
Instead, tell TypeScript to generate an es6 module.

Including multiple typescript files

I have a really simple question but I couldn't find any documentations for it.
I have 4 ts files.
/main.ts
/sub/forms.ts
/sub/validators.ts
/sub/location.ts
I'm using Visual Studio Code to code and when I save a TypeScript file, it auto compiles it and creates a JS file (ES5).
my problem is.. when I save main.ts file, how can I have forms.ts, validators.ts and location.ts in it as well?
In PHP, we simple use include('filename.php');
Is there way to do it in TypeScript?
main.ts;
import { Forms } from "./sub/forms";
import { Validators } from "./sub/validators";
import { Location } from "./sub/location";
let emp1 = new Validators('TEST');
emp1.greet();
/sub/validators.ts;
export class Validators {
employeeName: string;
constructor(name: string) {
this.employeeName = name;
}
greet() {
console.log(`Good morning ${this.employeeName}`);
}
}
main.js (after auto save compile)
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var validators_1 = require("./sub/validators");
var emp1 = new validators_1.Validators('TEST');
emp1.greet();
it doesn't import the validators.ts code into main.js

How to access exported TypeScript class from JavaScript using AMD and RequireJS

I have the following TypeScript class in the file: bar.ts
export class Bar {
log(message:string):void {
console.log(message);
}
}
In the file foo.ts I have:
import { Bar } from "bar";
window.onload = () => {
var foo = new Bar();
foo.log("Hello World");
};
I am compiling with:
lib: ["dom", "es2015.promise", "es2015"]
module: "amd"
declarationFiles: true
target: "ES5"
noImplicitAny: true
out: "test.js
How can I instantiate the Bar class? The window.onload event is not called. The following is the generated code:
define("bar", ["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Bar = (function () {
function Bar() {
}
Bar.prototype.log = function (message) {
console.log(message);
};
return Bar;
}());
exports.Bar = Bar;
});
define("foo", ["require", "exports", "bar"], function (require, exports, bar_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
window.onload = function () {
var foo = new bar_1.Bar();
foo.log("Hello World");
};
});
Is there a way to reference Bar from standard JavaScript? I have included require.js in the HTML page and there are no JavaScript errors when the page loads.
This is a simplified version of the problem but I need to use export as the project has many classes each stored in separate files and I need to combine them into a single file.
You should be able to reference Bar from regular javascript. Try to do it from the requirejs data-main script.
In the HTML:
<script data-main="scripts/main" src="scripts/require.js"></script>
In scripts/main:
requirejs(["bar"], function(bar) {});

Applying RequireJS to a modular one page application

I actually have two questions concerning requirejs and singleton objects. I want to form a singleton object playing the role of my application core and pass it to modules as a parameter. How should this be done?
The other issue I have is related to a private object inside the application core. It's suppose to act as a container for modules but for some reason when I try to start the application, this container seems to have those modules but it can't be looped through. Any ideas why this is happening?
Here's an example code of the situation:
// applicationConfig.js
require.config({
baseUrl: 'js',
paths: {
jquery: 'jquery-3.1.1.min',
core: 'utils/applicationCore',
domReady: '../lib/domReady'
}
});
require(['modules']);
// modules.js
define(['core', 'domReady'], function(Core, domReady) {
require([
'modules/module1'
]);
domReady(function() {
var modules = Core.getModules();
var name = '';
for (name in modules) {
modules[name].creator(); // Start a module...
}
});
});
// applicationCore.js
define(function() {
return (function() {
var _modules = {};
return {
add: function(name, creator) {
_modules[name] = {
creator: creator
};
},
getModules: function() {
return _modules;
}
}
}());
});
// module1.js
define(['core', 'jquery'], function(Core, $) {
Core.add('module1', function() {
// Module constructor function.
});
});

How do I use SystemJS Builder buildStatic?

I am trying to do a simple example using SystemJS Builder by building a SFX bundle, but I cannot get it to work. I cannot figure out how to call exported functions that were in the bundle. Am I missing something obvious?
index.html
<html>
<head>
<script src="app.bundle.js"></script>
<script>
all();
</script>
</head>
<body>
</body>
</html>
gulpfile.js
var path = require('path');
var gulp = require('gulp');
var Builder = require('systemjs-builder');
gulp.task('default', function(cb) {
var builder = new Builder('.', './jspm.config.js');
builder.buildStatic('src/app.js', 'dist/app.bundle.js').then(cb());
});
app.js
import { hello } from 'src/app/hello';
export function all() {
hello();
}
hello.js
export function hello() {
console.log("hello");
};
When I try to load index.html, it loads the app.bundle.js file correctly, but I can't seem to figure out how to call all() and I get Uncaught ReferenceError: all is not defined in Chrome.
The bundle file looks reasonable, I think:
// ... Some minified SystemJS content...
(["1"], [], function($__System) {
$__System.register("2", [], function (_export) {
"use strict";
_export("hello", hello);
function hello() {
console.log("hello");
}
return {
setters: [],
execute: function () {
;
}
};
});
$__System.register('1', ['2'], function (_export) {
'use strict';
var hello;
_export('all', all);
function all() {
hello();
}
return {
setters: [function (_) {
hello = _.hello;
}],
execute: function () {}
};
});
})
(function(factory) {
if (typeof define == 'function' && define.amd)
define([], factory);
else if (typeof module == 'object' && module.exports && typeof require == 'function')
module.exports = factory();
else
factory();
});
Exporting the all function does not mean it's accessible by the global object (window in the browser).
It just means that it can be imported using a module loaded (e.g. systemjs).
When creating a self-executing bundle you should just load the bundle file in the browser (as you already do) and do all bootstrapping also in the js files that are going to be in the bundle.
If you really need to access the all function in that script tag you must add the function to the global object.
in your app.js
window.all = all;
But i don't think this is the way its intended to be used.

Categories

Resources