在 Angular2+Webpack 中使用 templateUrl 的相对路径

Using relative path for templateUrl in Angular2+Webpack

import {Component} from 'angular2/core';

@Component({
  selector: 'app',
  styleUrls: ['./app.component.less'],
  templateUrl: './app.component.html'
})
export class AppComponent {
  name:string = 'Demo'
}

当使用 templateUrl 和 styleUrls 的相对路径时,我得到:错误 404,找不到文件:

zone.js: 101 GET http://localhost/app.component.html 404(未找到)

代码:https://github.com/Dreampie/angular2-demo

我觉得这样设计不太好,因为不同情况下构建目录可能不一样,能改成相对当前路径吗?

raw-loader可以解决这个问题,但是html-loaderless-loader不适用于templatestyles,它只适用于string ,那为什么不支持他们呢?

import {Component} from 'angular2/core';

@Component({
  selector: 'app',
  styles: [require('./app.component.less')],
  template: require('./app.component.html')
})
export class AppComponent {
  name:string = 'Demo'
}

得到其他错误:

browser_adapter.js:77 EXCEPTION: Error during instantiation of Token Promise<ComponentRef>!.BrowserDomAdapter.logError
browser_adapter.js:77 ORIGINAL EXCEPTION: Expected 'styles' to be an array of strings.

./(单点)符号仅适用于 ts 路径,不适用于 html 或 css 路径。

这些路径是相对于 index.html 的,因此根据您的文件结构,这应该可行

@Component({
  selector: 'app',
  styleUrls: ['app.component.less'],
  templateUrl: 'app.component.html'
})

让我补充一些信息。

为什么 Angular 无法从组件文件的位置计算出 HTML 和 CSS URL?

不幸的是,那个位置并不容易知道。 Angular 应用程序可以通过多种方式加载:从单个文件、从 SystemJS 包或从 CommonJS 包,等等。由于加载策略多种多样,因此很难在运行时判断这些文件的实际位置。

唯一可以确定的位置 Angular 是 index.html 主页的 URL。因此默认情况下它会解析相对于 index.html 的 URL 的模板和样式路径。这就是为什么我们之前使用 app/ 基本路径前缀编写 CSS 文件 URLs 的原因。

Official Angular Docu

你需要试试

@Component({
  selector: 'app',
  template: require('./app.component.html'),
  styles: [
    require('./app.component.less').toString()
      or
    String(require('./app.component.less'))
      or
    add css-to-string in your webpack conf ({test: /\.css$/, loaders: ['css-to-string', 'style', 'css']})
})

将 moduleId 属性 设置为 module.id 以进行模块相关加载,以便 url 相对于组件。

@Component({
  moduleId: module.id,
  selector: 'app',
  styleUrls: ['app.component.less'],
  templateUrl: 'app.component.html'
})

例如,如果您使用的是 SystemJS,请在此处查看我的回答:

您可以使用 model.id 并将其从您的构建路径(使用 js)转换为使用 ts、css 和 html 的构建路径。这样你就可以在 Angular 中为你的模板和样式使用相对路径 2 没问题

@Component({
   moduleId: module.id.replace("/dist/", "/"),
...
});

我在我的案例中发现了同样的错误。

的原因

Expected 'styles' to be an array of strings

在我的例子中是 css-loader,它用于加载 CSS 文件并通过管道传输到 angular2-template-loader

我从调试中了解到 css-loader 有一些 "smart" 检测到 CSS 文件中的更改,如果没有任何更改 CSS 文件就不会导出为webpack 模块的字符串。

因为它只是一个 hello word 应用程序,所以我的解决方案非常简单:将 css-loader 替换为 raw-loader。这是我的装载机版本:

loaders: [
    {
        include: [srcPath],
        test: /\.js$/,
        loader: 'babel',
        query: {
            presets: ['es2015']
        }
    },
    {
        include: [srcPath],
        test: /\.js$/,
        loader: 'angular2-template-loader',
        query: {
            keepUrl: true
        }
    },
    {
        include: [srcPath],
        test: /\.(html|css)$/,
        loader: 'raw',
        query: {
            minimize: true
        }
    }
]

WebPack2 不再需要这个 moduleId