在TypeScript中从根路径导入模块

38

假设我有一个项目,它的主要源代码目录是:

C:\product\src

根据该目录,每个导入路径都将相对于它。例如,假设:

// Current script: C:\product\src\com\name\product\blah.ts

import { thing } from '/com/name/product/thing';

同上:

// Current script: C:\product\src\com\name\product\blah.ts

import { thing } from '../../../com/name/product/thing';

我的编译入口文件位于:

C:\product\src
例如。那么,有没有一种方法可以在编译器选项中指定这样的条目路径(例如C:\product\src)?我需要在tsconfig.json文件中指定这个,因为我将使用webpack。
我已经尝试了上面的示例,但TypeScript表示找不到所请求的模块:
// Current script: A.ts

import { B } from '/com/B';


// Current script: B.ts

export const B = 0;

我的tsconfig.json文件(在另一个项目中,但两者类似):

{
    "compilerOptions": {
        "module": "commonjs",
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "strictNullChecks": true,
        "target": "ES6"
    },

    "include": [
        "./src/**/*.ts",
        "./src/**/*.d.ts"
    ]
}

C:\product\src + ../../../com/name/product/thing 不等于 C:\product\src\com\name\product\blah.ts。我有什么遗漏的吗?您想禁止向上跨越某个根目录吗? - Tomáš Hübelbauer
@TomášHübelbauer “// C:\product\src\com\name\product\blah.ts” 的注释意味着以下带有导入声明的脚本是 blah.ts 文件,与导入路径无关。抱歉!我不确定你所说的“..”是什么意思,我的英语不是很好 :/。 - user7536774
1
请发布您的 tsconfig.json 文件。 - Teddy Sterne
@TeddySterne 已添加。 - user5066707
5个回答

28

(重新发布我的答案以避免puppy-socket。)

使用compilerOptions.baseUrl属性,我能够进行以下导入操作。这使得我可以拥有一个完整的从根目录到预期路径的路径,有助于我的代码维护,并且在任何文件中都可以独立工作,而不受当前文件夹的影响。下面的示例将把我的项目的src文件夹作为模块的根目录。

重要建议:这个baseUrl属性不会影响入口webpack文件(至少对我来说是这样的?),所以在src文件夹中单独分离一个主文件,并从入口运行它(即import { Main } from './src/Main'; new Main;),只运行一次。

// browser: directory inside src;
//   * net: A TS file.
import { URLRequest } from 'browser/net';

tsconfig.json 示例:

{
    "compilerOptions": {
        "baseUrl": "./src",
        "module": "commonjs",
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "strictNullChecks": true,
        "target": "ES6"
    },

    "include": [
        "./src/**/*.ts",
        "./src/**/*.d.ts"
    ]
}

然而,它不能直接与webpack一起使用。相同的事情必须在webpack选项中完成。这就是在webpack 2中的工作方式:

module.exports = {
  ...
  , resolve: {
      ...
      , modules: [ path.join(__dirname, './src') ]
    }
}

6
好的,我会翻译这句话:"Awesome, answer but don't forget to also put node_modules in there."。 我会尽量使翻译通俗易懂且保留原意,但不会写任何解释。请注意,如果这句话本身存在歧义或与上下文相关,则我的翻译可能不够准确。"非常好,回答得很棒,但别忘了也把 node_modules 放进去。" - Eyal Perry
1
我发现 includes 部分是不必要的,甚至会尝试编译 node_modules 中的内容。我在 tsconfig 中设置了 baseUrl、rootDir 和 ouputDir。在 webpack 中,我像 @EyalPerry 指出的那样添加了 node_modules。看起来效果很好。 - Greg
我正在使用 create-react-app,只设置了 baseUrl 就足够了。谢谢! - porges

20

我需要在tsconfig.json中设置baseUrlrootDir都指向我的src文件夹。

{
  "compilerOptions": {
    "baseUrl": "./src",
    "rootDir": "./src",
  ...
}

我可以直接导入.tsx文件而无需添加前缀'/'或相对路径。

例如: import BreadCrumb from 'components/BreadCrumb'


10
这在 VSCode 的 Linting 中可行,而且 tsc 也能成功构建它,但是当我尝试运行编译后的代码时,会出现“找不到模块”的错误。 - Mr5o1
1
对我来说,我只需要提供一个“baseUrl”。 - derpedy-doo
不要忘记重新启动开发服务器,以使其生效。 - joematune

4
TypeScript的导入使用/来表示根目录。要相对于当前文件导入文件,可以省略初始斜杠或使用./
// Current script: C:\product\src\com\name\product\blah.ts
import { thing } from './com/name/product/thing';

默认情况下,TypeScript编译器假定项目的根目录与您的tsconfig.json文件的位置相同。
您可以通过在tsconfig中指定compilerOptions属性的rootDir属性来指定新的根目录。
有关所有可用属性设置的列表,请参阅此处找到的tsconfig定义。

2
感谢您提供根目录的假设,但是我仍然无法相对于其根目录导入文件,因为TypeScript仍然会说找不到导入模块。我已经尝试过使用和不使用斜杠,但是没有用,使用“./”也是一样。 - user5066707
尝试将“module”切换为“node”。 - Teddy Sterne
15
/ 总是指文件系统的根目录。更多详情 - raphinesse

3

仅供记录

如果你想从你的项目中使用绝对导入,不要使用/作为前缀,例如/src/config/cfg,只需使用src/config/cfg

正如https://dev59.com/WJnga4cB1Zd3GeqPZ4r9#46229294所指出的那样,/代表系统根目录

tsc会抱怨无法找到模块


这不是真的。支持已于2017年添加-> https://github.com/Microsoft/TypeScript/issues/19318 - Matthew Dean
1
为了让像 src/config/cfg 这样的路径对我起作用,我必须在我的 tsconfig.json 中提供一个 baseUrl - derpedy-doo

-5

你在 thing.ts 文件中的导入语句的解决方案如下:

import {} './product/blah'

你的项目结构可能如下所示

enter image description here

其他可能的选项及说明


我有以下的应用程序结构并将其放置在 C:\\Users\\(用户名)\\Documents\firstAngular2App 如屏幕截图中所示。

enter image description here

我正在将组件导入到app.module.ts文件中

  1. ./ 会显示当前文件夹(应用程序)

    import { } from './'; 
    

enter image description here

  1. ../将指向根文件夹(firstAngular2App-master)

    import { } from '../'; 
    

enter image description here

  1. ../../将指向根文件夹(文档文件夹)

    import { } from '../../'; 
    

enter image description here

  • ../app/ 指的是应用程序文件夹,但是它是从根目录(firstAngular2App)中引用的。

    import {} from '../app/';
    
  • enter image description here


    感谢您的解释,但那并不完全是我要找的。我知道可以使用“..”和“./”标记进行相对导入,但我的问题中还没有例子。 - user5066707
    你在寻找什么? - Aravind
    1
    我试图避免使用深度相对路径,我想要指定一个相对于项目根目录的路径,而不是当前文件根目录。例如,我的根目录现在将是src文件夹。假设我有一个文件src/blah/Class.ts,其中import { Export } from 'export'将引用src/Export.ts。我不想依赖于.../标记,不幸的是它们几乎让我创建了一种新的编程语言来替换TypeScript,它们使我的代码维护变得丑陋。 - user5066707
    1
    让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/135538/discussion-between-aravind-and-handoncloud。 - Aravind

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接