简体   繁体   English

本地typescript package导入未解决

[英]Import of local typescript package not resolved

Here is what I want to achieve.这是我想要实现的目标。

I want to make a package that I will use to share typescript interface, or common config that will be shared between my front-end (react) and my back-end (nestjs)我想制作一个 package 用于共享 typescript 接口,或者在我的前端(react)和我的后端(nestjs)之间共享的通用配置

I have created project called "shared" and made a link in my package.json.我创建了一个名为“共享”的项目,并在我的 package.json 中创建了一个链接。

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

It works great my React, where can use my interface or anything from "shared" without any error !它在我的 React 中效果很好,可以在哪里使用我的界面或“共享”中的任何内容,而不会出现任何错误!

I did the same in my nestjs project, there is not error in the editor and I can see the shared package in the node_modules.我在我的nestjs项目中做了同样的事情,编辑器中没有错误,我可以在node_modules中看到共享的package。 But when I compile the project, it fails with:但是当我编译项目时,它失败了:

Error: Cannot find module 'shared/interfaces/user'错误:找不到模块“共享/接口/用户”

So I guess the problem comes from something in my nestjs conf or webpack... But I don't know what.所以我想问题出在我的nestjs conf或webpack ......但我不知道是什么。

tsconfig.json 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 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$/] }),

        ],
        
    };
};

If you have any idea:) Thanks guys !如果你有任何想法:) 谢谢大家!

What I usually do in my multi-component backend applications, eg app server, Kafka consumers, k8s cron jobs, etc., is that I use a so-called monorepo structure.我通常在我的多组件后端应用程序中,例如应用服务器、Kafka 消费者、k8s cron 作业等,我使用所谓的 monorepo 结构。 I assume you could do the same for your frontend + backend project.我假设你可以为你的前端 + 后端项目做同样的事情。 I would have the following directory structure in my projects:我的项目中将具有以下目录结构:

- 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 are private npm packages representing the components and packages are also private npm package representing some re-usable libraries across the apps . Apps是私有 npm 包,代表组件和packages也是私有 npm package 代表跨apps的一些可重用库。 In your case, both the frontend and backend pieces would be separate components in the apps directory.在您的情况下,前端和后端部分都将是apps目录中的单独组件。 To make this repository a monorepo, you can use yarn workspaces .要使这个存储库成为 monorepo,您可以使用yarn workspaces I will describe the important bits in the tsconfig.json and package.json files.我将描述tsconfig.jsonpackage.json文件中的重要位。

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

The package.json file in your root project is the one that tells yarn that you're going to work with a workspace and which directories should be considered workspaces.根项目中的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" }
  ]
}

The tsconfig.json file in your root holds references to all the typescript projects in your repository.根目录中的tsconfig.json文件包含对存储库中所有 typescript 项目的引用 This so that if you run tsc --build from the root, it can build all your subprojects at once, and that it can import modules from the referenced projects properly.这样,如果您从根目录运行tsc --build ,它可以一次构建您的所有子项目,并且可以从引用的项目中正确导入模块。

I also like to use a tsconfig-base.json file to hold the shared configuration, ie all the TS configuration that is the same for all the apps and packages :我还喜欢使用tsconfig-base.json文件来保存共享配置,即所有appspackages都相同的所有 TS 配置:

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

Assume that the server project depends on both resource-repo and resource-validator packages.假设server项目同时依赖于resource-reporesource-validator包。 The resource-repo 's package.json file would look the following way: resource-repo的 package.json 文件如下所示:

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

The tsconfig.json file for the package would look this way: package 的tsconfig.json文件看起来是这样的:

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

The apps/server/package.json would look the following way: 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"
  }
}

And its tsconfig.json file would look this way:它的tsconfig.json文件看起来是这样的:

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

I don't have much experience with TypeScript front-end projects but I think that given this monorepo structure with the proper yarn workspace and TS setup adding bundling via Webpack or similar should not be a big issue.我对 TypeScript 前端项目没有太多经验,但我认为考虑到这种具有适当yarn workspace和 TS 设置的 monorepo 结构,通过 Webpack 或类似方式添加捆绑应该不是一个大问题。 A simple Google search for "webpack typescript monorepo" gave me this article .一个简单的谷歌搜索“webpack typescript monorepo”给了我这篇文章

You should display the code importing your module as well.您还应该显示导入模块的代码。 The issue might be due to the import where the path should be relative to you file and not an absolute path.问题可能是由于路径应该相对于您的文件而不是绝对路径的导入。 Same as: https://stackoverflow.com/a/54049216/532695同: https://stackoverflow.com/a/54049216/532695

If you really want to have a shorter link, like import {myInterface} from @shared/myModule you can setup path alias in your tsconfig.json file.如果你真的想要一个更短的链接,比如import {myInterface} from @shared/myModule你可以在你的tsconfig.json文件中设置路径别名。

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

But this is only understood by ts or possibly ts-node.但这只有 ts 或可能 ts-node 才能理解。 If you compile this using webpack, you might need to create an alias in its configuration as well:如果您使用 webpack 编译它,您可能还需要在其配置中创建一个别名:

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

Here is an article about how to setup aliases for webpack这是一篇关于如何为 webpack 设置别名的文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM