【问题标题】:Sharing code between projects using TypeScript and webpack使用 TypeScript 和 webpack 在项目之间共享代码
【发布时间】:2019-02-28 10:11:19
【问题描述】:

我想在两个 TypeScript 项目之间共享代码。我不想将共享代码发布到 NPM——只想将共享代码放在一个项目中并在另一个项目中使用它。我正在使用Webpackawesome-ts-loader。当前文件夹结构(简化)是这样的:

/devroot/
  mainProject/
    tsconfig.json
    src/
      shared/
        SomeSharedTypes.ts
  apiProject/
    tsconfig.json
    webpack.config.js
    src/
      UseSomeSharedType.ts

UseSomeSharedType.ts 中,我希望能够从SomeSharedTypes.ts 导入类型。

我尝试了这样一个明显的解决方案:

import {SharedType} from '../../mainProject/src/shared/SomeSharedTypes'

但是TS编译器给了我这个错误:

TS6059:文件“/devroot/mainProject/src/shared/SomeSharedTypes.ts”是 不在“rootDir”“/devroot/apiProject”下。 'rootDir' 预计 包含所有源文件。

【问题讨论】:

    标签: typescript webpack awesome-typescript-loader


    【解决方案1】:

    我强烈建议使用Nx workspace management 工具,因为它专门用于解决此类设置问题。您可以简单地在您的存储库中创建一个库,然后可以在任何地方导入(请参阅:https://nx.dev/angular/tutorial/08-create-libs)。我和我的团队现在严重依赖 Nx 超过 6 个月,无法想象没有它来管理 TypeScript 存储库,试一试! https://nx.dev

    如果您不适合使用 Nx,您可以按照实现代码共享的方式进行建模:

    1. 创建一个新文件夹
    2. 添加一个index.ts 文件,该文件导出应可从库外部访问的所有内容
    3. 在您的 tsconfig.json -> compilerOptions -> paths 中添加一个指向您库的 index.ts 的条目
    4. 通过您在tsconfig.json 中指定的导入名称导入共享代码

    【讨论】:

      【解决方案2】:

      我从this Medium article 得到的第一个想法是使用 TypeScript 的non-relative module imports 功能。这将允许我像这样编写我的导入:

      import {SharedType} from '@foo/SomeSharedTypes'
      

      使用文章中描述的技术,我在我的tsconfig.json 中添加了一个paths 配置:

      {
        "compilerOptions": {
          "baseUrl": ".",
          "paths": {
            "@foo/*": ["../mainProject/src/shared/*"],
          },
          "rootDir": "./",
          ...
        }
      }
      

      然后,再次按照文章的建议,对于 awesome-typescript-loader 的用户,我不得不修改我的 webpack.config.js 以添加解析插件:

      const { TsConfigPathsPlugin } = require('awesome-typescript-loader');
      . . .
        resolve: {
          extensions: ['.js', '.json', '.ts'],
          plugins: [
            new TsConfigPathsPlugin(),
          ],
        }
      

      重要提示:此插件需要进入文件的resolve/plugins 部分,而不是根级别的“plugins”部分!如果你把解析器插件放在错误的地方,你会得到这个错误:

      resolver.ensureHook 不是函数

      上面的步骤让我在这个过程中更进一步——TypeScript 现在能够找到我的文件了!——但我在 webpack 的执行后期仍然遇到同样的错误:'rootDir' is expected to contain all source files.

      经过更多谷歌搜索,我在this StackOverflow answer 中找到了解决方案:TS 有一个允许多个根的rootDirs 设置,而不是单个rootDir 配置。我从tsconfig.json 中删除了我的rootDir 设置并添加了rootDirs 设置:

      "rootDirs": [
        "./",
        "../mainProject",
      ],
      

      接下来,我在包含的其他项目 TypeScript 文件中遇到了 webpack 错误:

      模块解析失败:意外令牌 (3:15)

      您可能需要适当的加载程序来处理此文件类型。

      又一个小时的故障排除后,我发现我需要告诉 webpack 加载器我的新共享文件夹。像这样:

      const path = require('path');
      . . .
        rules: [
          {
            test: /\.[jt]sx?$/,
            loader: "awesome-typescript-loader",
            include: [
              __dirname,
              path.resolve(__dirname, "../mainProject/src/shared/")
            ],
            exclude: /node_modules/
          },
      

      成功了!这个解决方案的好处是我可以在不更改源代码的情况下重构我的文件夹结构。我只需要更改tsconfig.jsonwebpack.config.js

      诚然,我是使用 webpack 和 TypeScript 的新手,所以可能有比上述解决方案更好的解决方案……但上述解决方案对我有用!

      在此处分享解决方案,以便下一个开发人员更容易找到它。

      【讨论】:

      • OMFG! JS 构建基础设施是一个暴行
      • 在我将"baseUrl"/"paths" 添加到tsconfig.jsonloader: 'awesome-typescript-loader' 和``` plugins: [ new TsConfigPathsPlugin() ] ``` 之后似乎就足够了,rootDirsinclude 没有必要。至少tscwebpack 都成功了。
      • 只是想插话并感谢您指出“rootDirs” - 这解决了我的很多头痛问题,因为我不知道这是一个选项!
      猜你喜欢
      • 2019-03-07
      • 2020-04-20
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 2014-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多