我对 JavaScript 生态系统不是很熟悉,所以不太确定我的标题是否正确......我在大量“谷歌搜索”的帮助下用纯 ES6 编写了一个简单的应用程序,但我一直在获取类型错误,因此决定切换到 TypeScript。
一开始我很兴奋,
let blah: String = "hello world";
console.log(blah);
并运行tsc blah.ts
输出
var blah = "hello world";
console.log(blah);
这看起来很简单,我只是包含
<script src="ts/blah.js"></script>
并且 console.log 将会打印。
我决定利用模块来看看如何构建更大的东西,所以我创建了一个 lib.ts
export class StringUtil {
private rawValue: String;
constructor(input: String) {
this.rawValue = input;
}
upper(): String {
return this.rawValue.toUpperCase();
}
}
并将我的原始示例更新为
import { StringUtil } from "./lib";
let blah: String = "hello world";
// console.log(blah);
console.log(new StringUtil(blah).upper());
运行 tsc *.ts
现在输出:
"use strict";
exports.__esModule = true;
var lib_1 = require("./lib");
var blah = "hello world";
// console.log(blah);
console.log(new lib_1.StringUtil(blah).upper());
刷新浏览器,我现在得到
Uncaught ReferenceError: exports is not defined
at blah.js:2
所以经过大量阅读后,我看到很多人建议我添加一个 TypeScript 配置文件,我这样做了,
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"watch": true
}
}
输出完全相同,但仍然有相同的错误:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var lib_1 = require("./lib");
var blah = "hello world";
// console.log(blah);
console.log(new lib_1.StringUtil(blah).upper());
//# sourceMappingURL=blah.js.map
有人建议使用 amd 作为模块类型:
{
"compilerOptions": {
"target": "es5",
"module": "amd",
"sourceMap": true,
"watch": true
}
}
现在输出:
define(["require", "exports", "./lib"], function (require, exports, lib_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var blah = "hello world";
// console.log(blah);
console.log(new lib_1.StringUtil(blah).upper());
});
//# sourceMappingURL=blah.
浏览器提示:
Uncaught ReferenceError: define is not defined
at blah.js:1
切换到模块的“umd”,浏览器错误消失,但由于输出位于我不知道如何调用的匿名函数内,因此 console.log
不再触发
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "./lib"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var lib_1 = require("./lib");
var blah = "hello world";
// console.log(blah);
console.log(new lib_1.StringUtil(blah).upper());
});
//# sourceMappingURL=blah.js.map
我尝试按照一些 StackOverflow 帖子的建议删除模块参数,但它仍然输出与 commonjs 选项相同的内容。
切换到目标“es6”和模块“amd”,console.logs仍然在函数内,
{
"compilerOptions": {
"target": "es6",
"module": "amd",
"sourceMap": true,
"watch": true
}
}
define(["require", "exports", "./lib"], function (require, exports, lib_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
let blah = "hello world";
// console.log(blah);
console.log(new lib_1.StringUtil(blah).upper());
});
//# sourceMappingURL=blah.js.map
但是浏览器提示
Uncaught ReferenceError: define is not defined
at blah.js:1
我读的越多,看到的相互矛盾的建议就越多,大多数帖子从未提及他们正在使用的 TypeScript 版本,所以我假设根据您的版本有不同的方法来执行操作?
tsc --version
说我使用的是 3.6.3
使 tsc blah.ts
输出我可以通过 index.html 中的脚本标记包含的内容的正确方法是什么?我没有使用 NodeJS,这只是一个静态 HTML 文件。在控制台中没有显示错误的“umd”也在使用导出,所以我想如果我设法以某种方式调用生成的匿名函数,它也会提示导出.
由于这将是一个执行基本 DOM 操作的小型应用程序,我如何让 tsc 将所有文件合并到一个 JS 文件中,这样我就没有 js 文件在运行时加载?或者是否可以通过脚本标签单独包含每个生成的 js 文件,执行类似的操作?
<script src="ts/lib.js"></script>
<script src="ts/blah.js"></script>
我不想使用任何额外的东西,我看到了很多关于 webpack、babel、gulp 等的帖子。这似乎让事情变得更加复杂。
其他一些 StackOverflow 帖子建议使用
tsc --out app.js blah.ts lib.ts --module
然后提示
Cannot compile modules using option 'out' unless the '--module' flag is 'amd' or 'system'.
所以我添加了“amd”模块标志:
tsc --out app.js blah.ts lib.ts --module amd
然后输出:
define("lib", ["require", "exports"], function (require, exports) {
"use strict";
exports.__esModule = true;
var StringUtil = /** @class */ (function () {
function StringUtil(input) {
this.rawValue = input;
}
StringUtil.prototype.upper = function () {
return this.rawValue.toUpperCase();
};
return StringUtil;
}());
exports.StringUtil = StringUtil;
});
define("blah", ["require", "exports", "lib"], function (require, exports, lib_1) {
"use strict";
exports.__esModule = true;
var blah = "hello world";
// console.log(blah);
console.log(new lib_1.StringUtil(blah).upper());
});
通过脚本标签添加app.js
<script src="ts/app.js"></script>
浏览器控制台再次提示:
app.js:1 Uncaught ReferenceError: define is not defined
at app.js:1
从“amd”切换到“system”,浏览器提示
app.js:1 Uncaught ReferenceError: System is not defined
at app.js:1
除了浏览器控制台中的错误之外,我的 console.log
代码片段仍然位于一个我不知道如何调用的匿名函数中。
关于如何使用 TypeScript 实现如此简单的事情,有什么建议吗?
最佳答案
在 tsconfig.json
中使用 ES2015
作为 module
和 target
将其加载为:
<script src="ts/blah.js" type="module"></script>
编辑:
您可能会收到 404 not found
错误,因为根据今天(2020 年 1 月 18 日),javascript 模块功能需要使用文件扩展名完成导入。即:
import {myLib} from 'path/to/my/file.js'
但是 javascript 不会发出 .js
This is a know issue/feature request for Typescript regarding modules .
作为解决方法,您可以编写一个 npm 脚本来解析生成的 javascript 文件并修复扩展名,如 this Logger lib 中使用的扩展名。
关于javascript - 如何使用常规脚本标签运行模块 typescript 输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59801793/