【问题标题】:Compiling typescript with Webpack for other projects使用 Webpack 为其他项目编译 typescript
【发布时间】:2017-05-30 14:23:35
【问题描述】:

如何将我的 Typescript 项目编译为 TS 编译,然后将其导入其他 TS 项目并使用类型定义?为了向后兼容,我也想将它们导出为纯 JS,以便其他不使用 TS 的人仍然可以使用该项目。

【问题讨论】:

    标签: javascript typescript webpack typescript-typings


    【解决方案1】:

    您需要将项目发布为 npm 包。如果你愿意,你可以在 npm 上创建一个私有包(但你需要一个付费帐户),或者你可以公开发布它,或者你可以使用sinopia,它基本上是一个 npm 的本地实例。

    这些选项中的任何一个都要求您拥有指定项目依赖项的最新 package.json 文件。

    您将以编译的形式发布您的包。因此,如果您正确指定 tsconfig 和 package.json,您将导出 js 文件和 d.ts。文件和包将可以通过 typescript 或 vanilla javascript 使用。

    【讨论】:

    • 我了解项目的发布方式。我不知道(或找不到任何文档),关于配置需要编译和导出 JS 和 d.ts 文件
    【解决方案2】:

    这就是我的做法:

    // package.json
    // The property name: @my-org/... means that the package is scoped - 
    // you can point a @scope at a specific NPM registry.
    // See https://docs.npmjs.com/misc/scope
    // We use myget.org to host our private packages.
    {
      "name": "@my-org/ng-lib",
      "version": "1.0.8",
      "main": "dist/index.js",
      "scripts": {
        "transpile": "tsc --outDir ./",
        "clean": "rimraf ./services && rimraf ./*.js && rimraf ./*.d.ts"
      },
      "author": "*** <me@my-org.com>",
      "license": "ISC",
      "files": [
        "**/*.js",
        "**/*.d.ts"
      ],
      "typings": "index.d.ts",
      "dependencies": {
        "@types/angular": "^1.5.20",
        "angular": "^1.5.9"
      },
      "devDependencies": {
        "rimraf": "^2.5.4"
      }
    }
    

    编辑:

    注意到 "typings": "index.d.ts" 行了吗?这描述了包的主要“类型”文件。因此,当您执行 import * as ngLib from '@my-org/ng-lib' 时,它将使用来自 node_modules/@my-org/ng-lib/index.d.ts 的类型intellisense,在编译后,webpack 会在 node_modules/@my-org/ng-lib/dist/index.js

    找到主 js 文件

    因此,如果您手动创建了一个 index.d.ts 并且您要导出的只是接口,您可以将类型字段指向该 index.d.ts,因为接口没有实现,只需描述物体的形状。

    但是,如果您有具有逻辑的对象(方法、getter/setter 等),它们很可能是类,您需要将其转换为 .js 和 .d.ts 文件。

    示例:

    ./index.ts # Re-exports both my-class and my-interface
    ./my-class.ts # Implements my-interface.d.ts
    ./my-interface.d.ts
    

    这个转译后的输出应该如下在一个“类型化”的 NPM 包中:

    ./index.d.ts
    ./index.js
    ./my-class.js
    ./my-class.d.ts
    ./my-interface.d.ts
    

    而 package.json 将包含以下几行:

    "main": "./index.js",
    "typings": "./index.d.ts",
    "files": [
        "./index.d.ts",
        "./index.js",
        "./my-class.js",
        "./my-class.d.ts",
        "./my-interface.d.ts"
      ]
    

    ...在使用包时(一旦它被发布并安装在另一个项目中)可以通过以下方式完成:

    import * as ngLib from '@my-org/ng-lib'
    import { MyClass } from '@my-org/ng-lib'
    import { MyInterface } from '@my-org/ng-lib'
    import { MyClass } from '@my-org/ng-lib/my-class'
    import { MyInterface } from '@my-org/ng-lib/my-interface'
    

    结束编辑

    tsconfig.json 中的 declaration 属性将发出 .d.ts 文件,描述您导出对象的“形状”。

    // tsconfig.json
    {
      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "sourceMap": false,
        "emitDecoratorMetadata": true,
        "declaration": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "noImplicitAny": false,
        "suppressImplicitAnyIndexErrors": false,
        "baseUrl": "./src",
        "listFiles": true,
        "noImplicitUseStrict": false
      },
      "exclude": [
        "node_modules"
      ]
    }
    

    如果它是一个复杂的包,我将有单独的模块并将它们聚合在 index.ts 中,如下所示:

    // index.ts
    export * from './module-one'
    export * from './module-two'
    export * from './module-three'
    

    您还可以有子目录,每个子目录都有自己的索引。

    这将创建 index.js 和 index.d.ts 文件,允许执行以下操作:

    import * as ngLib from '@my-org/ng-lib'
    import { ModuleOne } from '@my-org/ng-lib/module-one'
    import { SubModuleOne } from '@my-org/ng-lib/submodules/submodule-one'
    

    【讨论】:

    • 这会扫描我的整个文件并为我拥有的每个文件创建一个.d.ts。我已经创建了我的接口。我只想将它们导出到一个文件中。我所有的接口文件都在一个目录./interfaces 中,我创建了一个index.d.ts 包括我想要公开的文件。那么我该如何导出呢?
    猜你喜欢
    • 1970-01-01
    • 2018-02-05
    • 2017-12-21
    • 1970-01-01
    • 2020-10-11
    • 2016-03-02
    • 2018-03-12
    • 2020-09-13
    • 2017-07-25
    相关资源
    最近更新 更多