在Angular CLI中避免相对路径

时间:2017-01-04 09:52:33

标签: angular typescript webpack angular-cli

我使用最新的Angular CLI,并且我已经创建了一个自定义组件文件夹,它是所有组件的集合。

例如,TextInputComponent有一个TextInputConfiguration类放在src/components/configurations.ts内,而在src/app/home/addnewuser/add.user.component.ts我使用它的地方有:{/ p>

import {TextInputConfiguration} from "../../../components/configurations";

这很好但随着我的应用越来越大../增加,我该如何处理?

以前,对于SystemJS,我会通过system.config.js配置路径,如下所示:

System.config({
..
 map : {'ng_custom_widgets':'components' },
 packages : {'ng_custom_widgets':{main:'configurations.ts', defaultExtension: 'ts'},
)};

如何使用Angular CLI为webpack生成相同内容?

7 个答案:

答案 0 :(得分:63)

根据this comment,您可以通过paths中的tsconfig.json添加您的申请来源:

{
  "compilerOptions": {
    ...,  
    "baseUrl": ".",
    "paths": {
      ...,
      "@app/*": ["app/*"],
      "@components/*": ["components/*"]
    }
  }
}

然后您可以完全从app/components/导入,而不是相对于当前文件:

import {TextInputConfiguration} from "@components/configurations";

注意:baseUrl必须指定 paths

另见

答案 1 :(得分:15)

感谢 jonrsharpe's answer 指示我正确的方向。虽然在添加paths之后,如答案中所定义的那样,我仍然无法使其工作。对于将来遇到与我相同问题的其他人,我在这里解决了这些问题。

我有一个共享模块,其服务正在多个组件中使用,所以......

<强> tsconfig.json:

{
    "compilerOptions": {
        ...
        "baseUrl": ".", //had to add this too
        "paths": {
            "@shared/*": ["src/app/modules/shared/*"]
        }
    }
}

在此之后, VS Code 能够解析import但我在编译时仍然遇到webpack的错误。

  

找不到模块:错误:无法解决

要解决此问题,我必须添加

    baseUrl of tsconfig
  1. webpack's resolve.modules paths of tsconfig
  2. webpack's resolve.alias

    <强> webpack.config.js:

    resolve: {
      extensions: ['*', '.js', '.ts'],
      modules: [
        rootDir,
        path.join(rootDir, 'node_modules')
      ],
      alias: {
        '@shared': 'src/app/modules/shared'
      }
    },
    

    <强> component.ts:

    import { FooService } from '@shared/services/foo.service'
    import { BarService } from '@shared/services/bar.service'
    import { BazService } from '@shared/services/baz.service'
    

    为了让它更清洁,我在 services 文件夹中添加了index.d.ts并从那里导出了我的所有服务,如下所示:

    <强> index.d.ts:

    export * from './foo.service';
    export * from './bar.service';
    export * from './baz.service';
    

    现在位于任何组件内:

    import { FooService, BarService, BazService } from '@shared/services';
    

答案 2 :(得分:14)

最重要的是回答是正确的,但在通过搜索互联网努力了解究竟是什么问题并尝试不同的故障排除选项后,我开始认识 baseUrl 路径如何与他人合作

如果您使用 baseUrl:&#34;。&#34; ,如下所示,它适用于VScode但不适用于编译

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "baseUrl": "src",
    "paths": {
      "@myproject/*": ["app/*"],
      "testing/*": ["testing/*"]
    }    
}

根据我的理解和我的工作应用并检查 angular aio 代码,我建议使用 baseUrl:&#34; src&#34; ,如下所示

{{1}}

通过将基本URL作为源(src目录),编译器可以正确解析模块。

我希望这有助于人们解决这类问题。

答案 3 :(得分:5)

不确定为什么但是当我在VS2017中尝试其他答案时,我能够无错误地编译Angular但我仍然看到VS&#34中的错误;找不到模块...&#34;。当我从"src"将baseUrl设置为"."时,每个人都很高兴。

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "baseUrl": "src",                 // Main source directory same level as tsconfig
    "paths": {
      "app/*": [ "app/*" ],           // src/app
      "ui/*": [ "ui/*" ],             // src/ui       
      "services/*": [ "services/*" ], // src/services
      "assests/*": [ "assests/*" ],     // src/assests
      "models/*": [ "models/*" ]      // src/models
    },
    "lib": [
      "es2017",
      "dom"
    ]
  }
}

然后导入:

import { AppMenuComponent } from 'ui/app-menu/app-menu.component';

注意:如果Visual Studio仍然出现错误,请尝试关闭并重新打开文件,或者重新启动Visual Studio以使其识别新路径。

答案 4 :(得分:1)

在Angular 8中,不需要*。 *将导致Cannot find module的错误 将此添加到您的tsconfig.json文件

"baseUrl": "./",
"paths": {
      "@test": [ "src/app/test/" ],
      "@somthing": [ "src/app/something/" ],
      "@name": [ "src/app/name/" ]
    },

答案 5 :(得分:1)

保持简单

为了使这一点变得简单,您需要了解几件事,才能将该解决方案应用于将来的任何项目。

前言:Angular并未设置“通常的” @/~/ path mappings,可能是因为它选择在此问题上不那么自满。

它确实为所有导入设置了baseUrl./(这意味着tsconfig.json所在的文件夹)。

这意味着任何非相对导入(不以./../开头的导入)都将自动以baseUrl作为前缀。

只要您使用以该基本URL开头的路径进行导入,就应该已经有解决方案!只要您的重构工具能够识别基本URL并能够正确应用导入路径重构,重构就不会有问题。

因此,默认情况下,使用未经修改的TS配置,您可以使用这种导入方式,而不必担心相对路径变得难以管理:

// sample import taking into consideration that there is
// a baseUrl set up for all imports which get prefixed to
// all imports automatically:

import { ComingSoonComponentModule } from 'src/app/components/coming-soon/coming-soon.module';

另一种解决方案

但是,如果您真的想使用类似@/的前缀,则可以像使用简单的path mapping一样轻松地做到这一点,就像这样:

// tsconfig.json

{
  // ...
  "compilerOptions": {
    "baseUrl": "./",
    // notice that the mapping below is relative to the baseUrl: `src/app/*` is in fact `{baseUrl}src/app/*`, ie. `./src/app/*`.
    "paths": { "@/*": ["src/app/*"] },
    // ...
  },
  // ...
}

然后,您可以作为以下任意一种导入:

import { ComingSoonComponentModule } from 'src/app/components/coming-soon/coming-soon.module';
import { ComingSoonComponentModule } from '@/components/coming-soon/coming-soon.module';

要记住的事情:

  1. paths tsconfig选项相对于baseUrl选项(因此请记住并为paths键使用相对路径)。
  2. *-星号是指定的模块路径(按照您导入的代码中的规范),其他所有内容都是根据tsconfig中的规范添加到最后的前缀或后缀路径。

答案 6 :(得分:-1)

对于此问题,我有一个更简单的解决方案。在您的“ tsconfig.json”中,只需将baseURL设置为空字符串即可:

"baseUrl": ""

现在,您可以像这样从根目录引用从一个文件到另一个文件的路径:

import { ProductService } from 'src/app/services/product.service'; 

这些是绝对路径,但是角度使用它们的方式似乎是相对的。但是他们工作!我不喜欢上面提到的“路径”快捷方式,因为我想知道所有东西都在哪里,这就是发明绝对路径的方式和原因。

请记住,这可以解决导入时引用模块和组件时或构建Angular项目时的路径问题,但不能解决与模板,样式路径或使用完全不同的图像之类的资产相关的路径问题构建和编译项目时,Angular中的路径系统。

如果这有助于解释这种愚蠢的路径系统,则项目根目录中的“ angular.json”工作空间文件将控制“ sourceRoot”文件夹的名称,该文件夹默认设置为“ src”。这就是Angular构建块使用的“源根”文件夹的开始。请记住,Angular“工作区根目录”是“ src”上方的项目文件夹,并且是项目和编译器的真实根目录。因此,当您编写“ src / app / ...”时,根目录实际上位于“ src”之上。 angular.json显然是从当前位置派生其起始文件夹,因此“ src / app /”实际上是一个基于angular.json位置的相对本地文件夹。我相信,这就是为什么“ / src / app”不适用于baseURL的原因,因为它相对于angular.json。

默认情况下,Angular的“ src”文件夹是在构建/编译项目时所有构建路径都解析的文件夹。我怀疑webpack在解析时也会在angular.json中也使用相同的“ sourceRoot”“ src”值。

经过很多努力,我发现将tsconfig中的baseURL设置为“”而不是“”。或“ ./”,现在只要从“ src”文件夹开始就可以使用这些完整路径。这些类型的绝对路径对我来说更有意义,因为您现在可以从视觉上了解所有内容从上到下的位置,而不是上下移动文件树。太疯狂了!

我不知道为什么Angular的孩子会使用那些愚蠢的相对路径系统。这些“ ./”路径在编译器路径解析系统和它们使用的HTML / URL路径解析系统中完全没有用,并且使导航更加困难。我认为,如果他们花时间学习为什么以及何时开发人员使用相对路径,他们可能已经意识到在广泛的环境中假设每个文件都引用其本地文件夹中的每个其他文件不是很有用。