使用Typescript输出纯JS,而不是模块?

时间:2019-03-20 20:27:53

标签: javascript typescript

例如...

index.ts

import { x } from "./other-funcs";

function y() {
    alert("test");
}

x(y);

other-funcs.ts

import { z } from "some-module";

export function x(callback: () => void): void {
    z();
    callback();
}

(请注意,“ other-funcs.ts”使用import语句从其他模块中导入函数。)

我想编译index.ts并将其生成一个JS文件,该文件可以直接包含在HTML文件中,例如<script src="index.js"></script>,并使其立即在浏览器中执行(显示警报)。

示例输出

function x(callback) {
    callback();
}

function y() {
    alert("test");
}

x(y);

我似乎无法获得适当的TS配置来获得此结果。请告知。

注意:这与this question不同,因为我需要使用import等。我只希望结果是没有模块加载器的简单JS输出。

1 个答案:

答案 0 :(得分:3)

Vanilla JavaScript

无论何时使用import,它都将始终扩展到模块中。不过,您可以在namespaces旁使用"module": "system",然后将其输出到单个文件(或多个文件)中。

因此,对于一个非常基础的项目,您将拥有以下内容:

tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",
    "module": "system",
    "outFile": "./lib.js"
  },
  "include": [
    "./**/*.ts"
  ]
}

接下来,您将创建文件,如下所示:

index.ts

namespace MyNamespace {
  // This is a private method that cannot be accessed in other files
  // the reason for that is because it isn't exported.
  function y() {
    alert("test");
  }

  x(y)
}

functions.ts

namespace MyNamespace {
  // This method can be referenced in other files because it is exported.
  export function x(callback: () => void): void {
    callback();
  }
}

生成的浏览器代码

var MyNamespace;
(function(MyNamespace) {
  function x(callback) {
    callback();
  }
  MyNamespace.x = x;
})(MyNamespace || (MyNamespace = {}));
var MyNamespace;
(function(MyNamespace) {
  function y() {
    alert("test");
  }
  MyNamespace.x(y);
})(MyNamespace || (MyNamespace = {}));

然后,您可以在名称空间之外使用这些方法/功能,只需通过名称空间调用即可:

MyNamespace.y()
MyNamespace.x(MyNamespace.y)
// etc.

使用requirejs

要在项目中使用import,您将需要一个第三方库requirejs。这将允许您在浏览器中使用模块。

因此,要执行此操作,我们首先需要具有正确的配置文件,该配置文件看起来与上面相似,唯一的区别是"module": "amd"

tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",
    "module": "amd",
    "outFile": "./lib.js"
  },
  "include": [
    "./**/*.ts"
  ]
}

接下来,我们需要创建正确的打字稿主文件:

index.ts

requirejs(['functions'], function (util: any) {
  function y() {
    alert("test");
  }

  util.x(y)
})

由于它使用的是第三方库,因此初始化方式有所不同(使用requirejs())。这告诉requirejs这是应用程序的入口点,因此只需要一次。

functions.ts

export function x(callback: () => void): void {
  callback();
}

生成的浏览器代码

define("functions", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    function x(callback) {
        callback();
    }
    exports.x = x;
});
requirejs(['functions'], function (util) {
    function y() {
        alert("test");
    }
    util.x(y);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>

如果脚本位于外部文件中,则可以在脚本标签上使用data-main,然后requirejs将自动加载文件。

<script data-main="./lib" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>

实验模块

This feature is still experimental, and not supported in all browsers。您需要做的就是在脚本标签上使用type="module"属性:

<script type="module" src="./path/to/main.js"></script>

tsconfig.json

注意:在这里,我们既使用了不同的targetmodule,也使用了outDir
注意es2016不是有效的模块类型。

{
  "compilerOptions": {
    "target": "es2016",
    "module": "es2015",
    "outDir": "./lib"
  },
  "include": [
    "./**/*.ts"
  ]
}

index.ts

注意:import使用.js扩展名,否则浏览器将无法加载它,除非您有适当的重写规则。

import { x } from './functions.js'
function y() {
  alert("test");
}

x(y)

functions.ts

export function x(callback: () => void): void {
  callback();
}

这将输出与ts文件几乎相同的内容(除非Stackoverflow不支持外部js文件,除非它们托管在某个地方,因此这里没有代码段):

// index.js
import { x } from './functions.js';
function y() {
    alert("test");
}
x(y);

// functions.js
export function x(callback) {
    callback();
}