typescript编译为单个文件

IT技术 javascript typescript
2021-01-24 08:08:50

我正在使用 TS 1.7 并且我正在尝试将我的项目编译为一个大文件,我将能够将其包含在我的 html 文件中。

我的项目结构如下所示:

-build // Build directory
-src // source root
--main.ts // my "Main" file that uses the imports my outer files
--subDirectories with more ts files.
-package.json
-tsconfig.json

我的 tsconfig 文件是:

 {
  "compilerOptions": {
    "module":"amd",
    "target": "ES5",
    "removeComments": true,
    "preserveConstEnums": true,
    "outDir": "./build",
    "outFile":"./build/build.js",
    "sourceRoot": "./src/",
    "rootDir": "./src/",
    "sourceMap": true
  }
}

当我构建我的项目时,我希望 build.js 文件是从我的源代码编译的一个大文件。但是这个 build.js 文件是空的,我把所有的文件都编译成了 js 文件。

我的每个 TS 文件看起来有点像这样

import {blabla} from "../../bla/blas";

export default class bar implements someThing {
    private variable : string;
}

我究竟做错了什么 ?

3个回答

这将在TypeSript 1.8 中实现使用该版本时,outFile选项在moduleamdsystem时起作用

目前该功能在 Typescript 的开发版中可用。要安装该运行:

$ npm install -g typescript@next

对于以前的版本,即使moduleoutFile选项不明显,也不能一起工作。

您可以查看问题以获取更多详细信息。


如果要输出版本低于 1.8 的单个文件,则不能使用tsconfig.json 中module选项相反,您必须使用module 关键字来创建名称空间

您的tsconfig.json文件应如下所示:

{
  "compilerOptions": {
    "target": "ES5",
    "removeComments": true,
    "preserveConstEnums": true,
    "outFile": "./build/build.js",
    "sourceRoot": "./src/",
    "rootDir": "./src/",
    "sourceMap": true
  }
}

此外,您的 TS 文件应如下所示:

module SomeModule {
  export class RaceTrack {
    constructor(private host: Element) {
      host.appendChild(document.createElement("canvas"));
    }
  }
}

而不是使用 import 语句,您必须通过命名空间来引用导入。

window.addEventListener("load", (ev: Event) => {
  var racetrack = new SomeModule.RaceTrack(document.getElementById("content"));
});
您指出的问题似乎已解决,github.com/Microsoft/TypeScript/wiki/Compiler-Options建议将 --outFile 标志与 --module 标志一起使用。
2021-03-16 08:08:50
使用 TypeScript 3.x 有没有更好的方法来做到这一点?
2021-04-02 08:08:50
确实如此,但它似乎不起作用。:( 也许在 github 上提出问题?
2021-04-05 08:08:50
我编辑了答案以包含@next 部分,只是为了更清楚。:)
2021-04-07 08:08:50
顺便说一句,github 上问题的解决方案似乎并未指向代码库的任何实际更改,它们总是以默认行为结束。
2021-04-10 08:08:50

选项 1 - 如果您不使用module

如果您的代码仅包含常规 Typescript,而没有module(导入/导出),则您只需将参数添加outfiletsconfig.json.

// tsconfig.json
{
    "compilerOptions": {
        "lib": ["es5", "es6", "dom"],
        "rootDir": "./src/",
        "outFile": "./build/build.js"
    }
}

但是这个选项有一些限制。

如果您收到此错误:

Cannot compile modules using option 'outFile' unless the '--module' flag is 'amd' or 'system'

试试下面的“选项 2”。

选项 2 - 使用module加载器

如果您使用module(导入/导出),您将需要一个module加载器来在浏览器中运行您编译的脚本。

当您编译为单个文件(使用outFile)时,Typescript 本机支持编译为amdsystemmodule加载器。

在 tsconfig 中,您需要设置moduleamdsystem

// tsconfig.json
{
    "compilerOptions": {
        "module": "AMD",
        "lib": ["es5", "es6", "dom"],
        "rootDir": "./src/",
        "outFile": "./build/build.js"
    }
}

如果选择AMD,则需要使用require.js运行时。AMD 需要一个 AMD 加载器,require.js 是最受欢迎的选项(https://requirejs.org/)。

如果选择 System,则需要使用 SystemJS module加载器 ( https://github.com/systemjs/systemjs )。

选项 3 - 使用module打包器/构建工具

或许,最好的选择是使用module打包器/构建工具,比如 Webpack。

Webpack 会将您的所有 TypeScript 文件编译为单个 JavaScript 包。

因此,您将使用webpack编译,而不是tsc.

首先安装 webpack,webpack-cli然后ts-loader

npm install --save-dev webpack webpack-cli typescript ts-loader

如果您使用的是带有typescript的WebPack,也最好使用modulecommonjs

// tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "lib": ["es5", "es6", "dom"],
        "rootDir": "src"
    }
}

网络包webpack.config.js示例:

//webpack.config.js
const path = require('path');

module.exports = {
  mode: "development",
  devtool: "inline-source-map",
  entry: {
    main: "./src/YourEntryFile.ts",
  },
  output: {
    path: path.resolve(__dirname, './build'),
    filename: "[name]-bundle.js" // <--- Will be compiled to this single file
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js"],
  },
  module: {
    rules: [
      { 
        test: /\.tsx?$/,
        loader: "ts-loader"
      }
    ]
  }
};

现在,要编译,而不是使用tsc命令执行,请使用webpack命令。

package.json 例子:

{
  "name": "yourProject",
  "version": "0.1.0",
  "private": true,
  "description": "",
  "scripts": {
    "build": "webpack" // <---- compile ts to a single file
  },
  "devDependencies": {
    "ts-loader": "^8.0.2",
    "typescript": "^3.9.7",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}

Webpack 的 TypeScript 文档

最后,使用以下命令编译所有内容(最好在监视模式下):

npx webpack -w
@JohnF 该文件是“package.json”,位于根目录。我更新了答案。docs.npmjs.com/creating-a-package-json-file
2021-03-15 08:08:50
@AlkisMavridis 如果您使用module,我会使用其他选项更新我的答案以编译为单个文件。
2021-03-30 08:08:50
您的解决方案不起作用。我得到“无法使用选项 'outFile' 编译module,除非 '--module' 标志是 'amd' 或 'system'。”
2021-04-07 08:08:50
@AlkisMavridis 对我来说也是一样。你找到解决办法了吗?
2021-04-13 08:08:50
不要忘记安装 CLInpm i webpack-cli并使用npx webpack -w.
2021-04-14 08:08:50

最简单的方法

您可以使用名为ncc的自定义工具来完成此操作,该工具Vercel构建和维护以下是他们在create-next-app 中使用它的方式

ncc build ./index.ts -w -o dist/

用纱线安装它:

yarn add @vercel/ncc

或 npm:

npm install @vercel/ncc
@rambi 您可以通过一个小技巧在浏览器中运行它。在您的 HTML 文件中,var __dirname = "", module = {}ncc. 在单独的脚本标签中执行它可能是最简单的。
2021-03-17 08:08:50
我不知道,但根据您分享的内容,答案似乎是否定的。__dirname是一个特定于 node.js 的环境变量。
2021-03-31 08:08:50
这是否会创建可以直接在浏览器中运行的代码?我的浏览器说未定义“__dirname”
2021-04-07 08:08:50
ncc 用于 Node.js 项目,例如,如果您想构建从 TypeScript 到 JavaScript 的数据库播种脚本。通常,这些脚本是用 JavaScript“手工”编写的,使用 ncc,您可以将在 TypeScript 中编写的代码重用于您的应用程序。
2021-04-08 08:08:50