如何在没有模块加载系统的情况下将我的 Typescript 编译成单个 JS 文件?

Posted

技术标签:

【中文标题】如何在没有模块加载系统的情况下将我的 Typescript 编译成单个 JS 文件?【英文标题】:How can I compile my Typescript into a single JS file with no module loading system? 【发布时间】:2017-01-14 14:06:19 【问题描述】:

我有一个大约 10 个 ts 文件的小型 Typescript 项目。我想将我的所有文件编译成 es5 并编译成一个名为 all.jses5 文件。

目前,我的tsconfig.json 设置为


  "compilerOptions": 
    "module": "system",
    "target": "es5",
    "outFile": "./all.js"

一切都在编译,但每个文件都被

System.register("SomeTSFile", [], function(exports_4, context_4) 
...

SystemJS 看起来很酷,但我现在没有心情学习它,我认为没有必要。如果我可以将所有 JS 放入一个文件中,那将完全满足我的需求。

如果我从我的编译器选项中删除"module": "system",,我的all.js 文件就会完全空白。显然,这是因为某种原因,you cannot use "modules": none when outputting to one file。 (我不明白为什么)

如何将所有 TS 编译成一个 JS 文件,而不必涉及 SystemJS 或任何其他复杂问题?

【问题讨论】:

每个 .ts 文件都是一个模块。如果一个 .ts 文件引用另一个文件,则没有模块加载系统就无法使其工作。如果您不想要它,请将所有 .ts 文件连接成一个并编译该文件。不过,这可能需要更改您的代码。 另一个选项是设置"module": "amd",那么你将需要 AMD loader 而不是 SystemJS。 【参考方案1】:

你可以使用编译器本身吗? - 作为后期构建过程。 TSC 接受允许您执行此操作的参数。

tsc --out compiledSingleFile.js one.ts two.ts

或者在你的构建管道中使用 Gulp -

https://www.npmjs.com/package/gulp-tsc

【讨论】:

我正在这样做,但它迫使我使用 SystemJS【参考方案2】:

.ts 文件的内容决定了这是否可行...

如果您避免将 TypeScript 代码转换为模块(通过避免*** importexport 声明),单文件编译的输出将不包含对模块加载器的任何依赖。

例如:typescript compiler itself 是在没有任何***导入或导出声明的情况下编写的,因此编译成单个文件 .js 没有任何加载程序依赖项。

请注意,它在命名空间中使用export 不是“***”导出。命名空间内的导入是可能的,但受到严格限制:an example here

“在 TypeScript 中,就像在 ECMAScript 2015 中一样,任何包含 ***导入或导出被视为一个模块。”

The typescript handbook

【讨论】:

嗯,所以我可以在模块部分而不是外部进行导入? 我不认为它那么简单@CodyBugstein。某些形式的导入是可以的,但从模块导入不是(如果您试图避免依赖于模块加载器。) 请注意,您可以使用triple-slash directives 来引用其他打字稿文件中的类型而不使用导入,但这并不能加载其他文件(但当然编译成单个 .js 可能会产生争议。) 好的,我会试试的【参考方案3】:

这是我最终使用的方法。此过程将创建一个文件,该文件可以与 html 页面上的 <script src="myModuleName.min.js"></script> 标记链接,以供在浏览器中使用。

    安装汇总和插件(此处列出的许多插件是可选的,但此配置应涵盖您使用模块的任何方式)

npm install rollup-plugin-buble rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-typescript rollup-plugin-uglify typescript --save-dev


    此示例汇总配置文件显示了如何防止汇总也捆绑您的依赖项。在这种情况下,我使用的是 jQuery 和 Angular,但我不想将它们包含在我提供给用户的包中——所以我将它们列为外部变量,它们都恰好有一个全局变量——这个示例文件展示了如何处理这种情况:

rollup.config.js

'use strict';

import 'rollup';
import typescript from 'rollup-plugin-typescript';
import buble from 'rollup-plugin-buble';
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
import uglify from 'rollup-plugin-uglify';
import minify from 'uglify-js';

/**
 * Default/development Build
 */
const config = 
    entry: 'src/index.ts',
    exports: 'auto',
    globals: 
        'jquery': '$',
        'angular': 'angular'
    ,
    external: ['angular', 'jquery'],
    targets: [dest: 'dist/myModuleName.js', format: 'umd', moduleName: 'myModuleName', sourceMap: true],
    plugins: [

        typescript(
            typescript: require('typescript')
        ),
        buble(),
        nodeResolve(
            jsnext: true,
            main: true
        ),
        commonjs(
            namedExports: 
                'node_modules/jquery/dist/jquery.min.js': ['jquery'],
                'node_modules/angular/angular.min.js': ['angular']
            
        )
    ]


// Minified JS Build
if (process.env.BUILD === 'minify') 
    config.targets = [dest: 'dist/myModuleName.min.js', format: 'umd', moduleName: 'myModuleName', sourceMap: false];
    config.plugins.push(
        uglify(, minify)
    );


// Report destination paths on console
console.info(`\u001b[36m\[Rollup $process.env.BUILD build\]\u001b[97m \nConverting Typescript from $
config.entry to javascript, exporting to: $config.targets[0].dest`);

export default config

    将脚本添加到 package.json
    "scripts": 
        "build": "rollup -c rollup.config.js --no-conflict --environment BUILD:development",
         "minify": "rollup -c rollup.config.js --environment INCLUDE_DEPS,BUILD:minify"
    

    提供一个用于汇总使用的文件:

src/index.ts

`export * from './myModule';`

    如果您正在编写库,可以选择使用文件来收集要导出的模块,这些是您打算公开使用的功能。

src/myModule.ts

export myOtherClass, myFunction from './myUtils/myFile';
export * from "./myUtils/myOtherFile";

    运行npm run buildnpm run build && npm run minify 也可以获得缩小版。

【讨论】:

【参考方案4】:

使用 triple slash directives 作为 typescript-compiler (tsc)

三斜杠引用指示编译器在编译过程中包含其他文件。

index.ts:

/// <reference path="./domHelpers.ts" />

function add(a: number, b: number): number 
    return a + b;


q('#sum').textContent = add(2, 5).toString();

domHelpers.ts

function q(query: string): Element 
    return document.querySelector(query);


function qa(query: string): NodeListOf<Element> 
    return document.querySelectorAll(query);

构建步骤:

tsc --out bundle.js ts/index.ts

将生成带有内容的 bundle.js

function q(query) 
    return document.querySelector(query);

function qa(query) 
    return document.querySelectorAll(query);

/// <reference path="./domHelpers.ts" />
function add(a, b) 
    return a + b;

q("#sum").textContent = add(2, 5).toString();

【讨论】:

【参考方案5】:

使用 TypeScript 3.4,我可以毫无问题地将许多 *.ts 脚本转换为单个 .js 输出文件。

这是我与tsc --project src/test/tsconfig.json一起使用的 tsconfig.json 的极简版本


  "compilerOptions": 
    "outFile": "../../build/test/Code.js",
    "module": "none",
    "skipLibCheck": true,
  ,
  "include": ["**/*.ts"],

【讨论】:

但是如何从一个文件导入到另一个文件? 您不必在此设置中使用 import 更少 require。输出Code.js 将是所有有效源文件的串联。有效的源文件是用tsconfig.jsonincludefiles 属性定义的。可以使用files 属性和/// &lt;reference path="some.ts" /&gt; 指令控制文件连接的顺序。您可以查看this repository 以获取完整示例。【参考方案6】:

我就是这样做的

    tsconfig 文件应将 moduleResolution 设置为经典 tsconfig 文件应将模块设置为无 使用 Typescript 命名空间语法并将所有文件保存在同一个命名空间中

完成!!!

此 sol 仅适用于不需要模块系统的人,使用此 sol 您将无法使用导入导出模块系统语法

【讨论】:

以上是关于如何在没有模块加载系统的情况下将我的 Typescript 编译成单个 JS 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有用户停机的情况下将我的 CloudFront 分配替换为另一个

如何在没有私钥的情况下将我的元掩码钱包中的 erc20 代币发送到其他地址?

如何在没有 Index.html 或.php 的情况下将我的 Web 应用程序文件运行到服务器?

如何在不使用和拆分测试集的情况下将我的数据集拆分为训练和验证?

如何在不杀死 /health 的情况下将我的 Spring Boot 应用程序默认为 application/xml?

在没有证书的情况下将 iPhone 应用程序侧加载到设备