英文:
Basic Understanding - TypeScript and HowTo properly implement JS-Modules into Webproject
问题
I am struggling with the current situation. Up to today I had my own JavaScript implementation with my own methods to load single JS files per website - when needed. This way, I had a tiny loader script with an SCP SHA-256 checksum in the header, which then loaded the "master" script that controlled everything else. Now I want to take a few steps further:
- Switch over to modules, because most libraries do so too.
- 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 loaded, and the SHA-256 hash from the header is valid.
And now where the struggle begins. This file is compiled to:
/master.ts
export class master {
constructor() {
this.init();
}
async init() {
console.log("Hello, let's 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, let's get started...");
}
}
exports.master = master;
});
This results in the browser not being able to 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 on the internet:
"use strict";
module master {
class master {
constructor() {
this.init();
}
async init() {
console.log("Hello, let's get started...");
}
}
}
This gets compiled into this:
"use strict";
var master;
(function (master_1) {
class master {
constructor() {
this.init();
}
async init() {
console.log("Hello, let's get started...");
}
}
})(master || (master = {}));
This leads to the same result. How can I get my class compiled from TypeScript to be able to call it from the loader or in the file itself?
Just for understanding, I don't want to use "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 afterward (if in production). Keeping this in mind, I am also open to different implementations. I am aiming for maximum page speed without compromises, and my current solution was working very well 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 to the 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, let's get started...");
});
}
}
And with
export class ()
I am getting this:
Cannot compile modules using option 'outFile' unless the '--module' flag is 'amd' or 'system'.
英文:
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'.
答案1
得分: 3
--module amd
这是你的问题1。
AMD 模块使用 define
语法,在浏览器中没有原生支持。要使用它们,你需要像 Require.JS 这样的工具。
相反,告诉 TypeScript 生成一个 es6
模块。
英文:
> --module amd
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论