【问题标题】:Import of local typescript package not resolved本地打字稿包的导入未解决
【发布时间】:2021-05-17 19:44:09
【问题描述】:

这是我想要实现的目标。

我想制作一个包,用于共享 typescript 界面,或在前端 (react) 和后端 (nestjs) 之间共享的通用配置

我创建了一个名为“shared”的项目,并在我的 package.json 中创建了一个链接。

像这样:"shared": "file:../shared",

我的 React 非常好用,可以在哪里使用我的界面或“共享”中的任何内容而不会出现任何错误!

我在我的nestjs项目中做了同样的事情,编辑器中没有错误,我可以在node_modules中看到共享包。但是当我编译项目时,它失败了:

错误:找不到模块“共享/接口/用户”

所以我猜问题出在我的 nestjs conf 或 webpack 中……但我不知道是什么。

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "moduleResolution": "node",
  },
}

webpack-hmr.config.js

const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = function (options) {

    return {
        ...options,
        entry: ['webpack/hot/poll?500', options.entry],
        watch: true,
        externals: [
            nodeExternals({
                allowlist: ['webpack/hot/poll?500'],
            }),
        ],
        plugins: [
            ...options.plugins,
            new webpack.HotModuleReplacementPlugin(),
            new RunScriptWebpackPlugin({ name: options.output.filename }),
            new webpack.WatchIgnorePlugin( {paths: [/\.js$/, /\.d\.ts$/] }),

        ],
        
    };
};

如果您有任何想法 :) 谢谢大家!

【问题讨论】:

  • 我认为使用 lerna & yarn 命名空间 & typescripts 路径别名,你可以实现它
  • 在运行 webpack 时,是否可以尝试添加 --display-error-details 参数并发布结果?这在过去对我有所帮助,您会惊讶地发现,有时根本原因实际上是一个完全不相关的问题。

标签: typescript nestjs importerror


【解决方案1】:

您还应该显示导入模块的代码。问题可能是由于路径应该相对于您的文件而不是绝对路径的导入。同:https://stackoverflow.com/a/54049216/532695

如果你真的想要一个更短的链接,比如import {myInterface} from @shared/myModule,你可以在你的tsconfig.json文件中设置路径别名。

{
...
  "compilerOptions": {
    "paths": {
      "@shared/*": ["path/to/shared/folder/*"],
    }
  },
...
}

但这只有 ts 或者可能是 ts-node 才能理解。如果您使用 webpack 编译它,您可能还需要在其配置中创建一个别名:

...
resolve: {
  alias: {
    shared: path.resolve(__dirname,'path/to/shared/folder/')
  }
}
...

这是一篇关于如何setup aliases for webpack的文章

【讨论】:

    【解决方案2】:

    我通常在我的多组件后端应用程序中做什么,例如app server、kafka consumer、k8s cron jobs等等,就是我使用了所谓的monorepo结构。我假设你可以为你的前端 + 后端项目做同样的事情。我的项目中会有以下目录结构:

    - apps
      - server
        - package.json
        - tsconfig.json
      - internal-kafka-events-consumer
        - package.json
        - tsconfig.json
      - sqs-consumer
        - package.json
        - tsconfig.json
      - resource-deleter-job
        - package.json
        - tsconfig.json
    - packages
      - resource-repo
        - package.json
        - tsconfig.json
      - resource-validator
        - package.json
        - tsconfig.json
    - package.json
    - tsconfig.json
    - tsconfig-base.json
    

    Apps 是代表组件的私有 npm 包,packages 也是私有 npm 包,代表apps 中的一些可重用库。 在您的情况下,前端和后端部分都将是 apps 目录中的单独组件。要使此存储库成为 monorepo,您​​可以使用 yarn workspaces。我将描述tsconfig.jsonpackage.json 文件中的重要部分。

    // package.json
    {
      "private": true,
      "workspaces": {
        "packages": [
          "packages/*",
          "apps/*"
        ]
      }
    }
    

    根项目中的 package.json 文件告诉 yarn 您将使用工作空间以及哪些目录应该被视为工作空间。

    // tsconfig.json
    {
      "files": [],
      "include": [],
      "references": [
        { "path": "./apps/server" },
        { "path": "./apps/internal-kafka-events-consumer" },
        { "path": "./apps/sqs-consumer" },
        { "path": "./apps/resource-deleter-job" },
        { "path": "./packages/resource-repo" },
        { "path": "./packages/resource-validator" }
      ]
    }
    

    根目录中的tsconfig.json 文件将references 保存到存储库中的所有打字稿项目。这样,如果您从根目录运行 tsc --build,它可以一次构建您的所有子项目,并且可以正确地从引用的项目中导入模块。

    我还喜欢使用tsconfig-base.json 文件来保存共享配置,即所有appspackages 的所有TS 配置都相同:

    // tsconfig-base.json
    {
      "compilerOptions": {
        ... // compiler options shared by TS sub-projects
      }
    }
    

    假设server 项目同时依赖于resource-reporesource-validator 包。 resource-repo 的 package.json 文件如下所示:

    // packages/resource-repo/package.json
    {
      "name": "@my-project/resource-repo",
      "private": true,
      "version": "1.0.0"
    }
    

    包的tsconfig.json 文件如下所示:

    // packages/resource-repo/tsconfig.json
    {
      "extends": "../../tsconfig-base.json",
      "compilerOptions": {
        ... // project-specific compiler options
      }
    }
    

    apps/server/package.json 如下所示:

    // apps/server/package.json
    {
      "private": true,
      "dependencies": {
        "@my-project/reource-repo": "1.0.0",
        "@my-project/resource-validator": "1.0.0"
      }
    }
    

    它的tsconfig.json 文件看起来是这样的:

    // apps/server/tsconfig.json
    {
      "extends": "../../tsconfig-base.json",
      "compilerOptions": {
        ... // project-specific compiler options
      },
      "references": [
        { "path": "../../packages/resource-repo" },
        { "path": "../../packages/resource-validator" }
      ]
    }
    

    我对 TypeScript 前端项目没有太多经验,但我认为考虑到这种具有正确 yarn workspace 和 TS 设置的 monorepo 结构,通过 Webpack 或类似方式添加捆绑应该不是什么大问题。一个简单的谷歌搜索“webpack typescript monorepo”给了我this article

    【讨论】:

      猜你喜欢
      • 2019-04-23
      • 2021-04-11
      • 2021-05-08
      • 1970-01-01
      • 2016-10-27
      • 1970-01-01
      • 2023-02-18
      • 1970-01-01
      • 2020-04-19
      相关资源
      最近更新 更多