【问题标题】:Angular2 / Electron application components cannot find template HTML fileAngular2 / Electron 应用程序组件找不到模板 HTML 文件
【发布时间】:2017-03-06 15:08:12
【问题描述】:

我已经设置了一个 angular2 / Electron 应用程序,类似于此视频中的说明:https://www.youtube.com/watch?v=pLPCuFFeKOU

我在 app/menu 文件夹中有一个名为 MenuComponent 的组件。当我将模板放入它自己的 HTML 文件并加载我的电子应用程序时,它失败并出现错误:

    xhr_impl.js:40 GET file:///menu.component.html
 net::ERR_FILE_NOT_FOUNDXHRImpl.get @ xhr_impl.js:40DirectiveNormalizer.normalizeTemplate @ directive_normalizer.js:51DirectiveNormalizer.normalizeDirective @ directive_normalizer.js:24(anonymous function) @ runtime_compiler.js:60RuntimeCompiler._loadAndCompileComponent @ runtime_compiler.js:60(anonymous function) @ runtime_compiler.js:83RuntimeCompiler._compileComponent @ runtime_compiler.js:76(anonymous function) @ runtime_compiler.js:66ZoneDelegate.invoke @ zone-node.js:232onInvoke @ ng_zone_impl.js:45ZoneDelegate.invoke @ zone-node.js:231Zone.run @ zone-node.js:114(anonymous function) @ zone-node.js:502ZoneDelegate.invokeTask @ zone-node.js:265onInvokeTask @ ng_zone_impl.js:36ZoneDelegate.invokeTask @ zone-node.js:264Zone.runTask @ zone-node.js:154drainMicroTaskQueue @ zone-node.js:401
browser_adapter.js:86 EXCEPTION: Failed to load /menu.component.html
browser_adapter.js:77 EXCEPTION: Failed to load /menu.component.htmlBrowserDomAdapter.logError @ browser_adapter.js:77BrowserDomAdapter.logGroup @ browser_adapter.js:87ExceptionHandler.call @ exception_handler.js:57(anonymous function) @ application_ref.js:296ZoneDelegate.invoke @ zone-node.js:232onInvoke @ ng_zone_impl.js:45ZoneDelegate.invoke @ zone-node.js:231Zone.run @ zone-node.js:114(anonymous function) @ zone-node.js:502ZoneDelegate.invokeTask @ zone-node.js:265onInvokeTask @ ng_zone_impl.js:36ZoneDelegate.invokeTask @ zone-node.js:264Zone.runTask @ zone-node.js:154drainMicroTaskQueue @ zone-node.js:401
browser_adapter.js:86 EXCEPTION: Error: Uncaught (in promise): Failed to load /menu.component.html
browser_adapter.js:77 EXCEPTION: Error: Uncaught (in promise): Failed to load /menu.component.htmlBrowserDomAdapter.logError @ browser_adapter.js:77BrowserDomAdapter.logGroup @ browser_adapter.js:87ExceptionHandler.call @ exception_handler.js:57(anonymous function) @ application_ref.js:265schedulerFn @ async.js:123SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:112onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:66ZoneDelegate.handleError @ zone-node.js:236Zone.runGuarded @ zone-node.js:131_loop_1 @ zone-node.js:412drainMicroTaskQueue @ zone-node.js:421
browser_adapter.js:77 STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.js:77ExceptionHandler.call @ exception_handler.js:59(anonymous function) @ application_ref.js:265schedulerFn @ async.js:123SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:112onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:66ZoneDelegate.handleError @ zone-node.js:236Zone.runGuarded @ zone-node.js:131_loop_1 @ zone-node.js:412drainMicroTaskQueue @ zone-node.js:421
browser_adapter.js:77 Error: Uncaught (in promise): Failed to load /menu.component.html
    at resolvePromise (zone-node.js:468)
    at PromiseCompleter.reject (zone-node.js:445)
    at application_ref.js:295
    at ZoneDelegate.invoke (zone-node.js:232)
    at Object.onInvoke (ng_zone_impl.js:45)
    at ZoneDelegate.invoke (zone-node.js:231)
    at Zone.run (zone-node.js:114)
    at zone-node.js:502
    at ZoneDelegate.invokeTask (zone-node.js:265)
    at Object.onInvokeTask (ng_zone_impl.js:36)BrowserDomAdapter.logError @ browser_adapter.js:77ExceptionHandler.call @ exception_handler.js:60(anonymous function) @ application_ref.js:265schedulerFn @ async.js:123SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:112onError @ ng_zone.js:120onHandleError @ ng_zone_impl.js:66ZoneDelegate.handleError @ zone-node.js:236Zone.runGuarded @ zone-node.js:131_loop_1 @ zone-node.js:412drainMicroTaskQueue @ zone-node.js:421
zone-node.js:388 Unhandled Promise rejection: Failed to load /menu.component.html ; Zone: angular ; Task: Promise.then ; Value: Failed to load /menu.component.html undefinedconsoleError @ zone-node.js:388_loop_1 @ zone-node.js:417drainMicroTaskQueue @ zone-node.js:421
zone-node.js:390 Error: Uncaught (in promise): Failed to load /menu.component.html(…)consoleError @ zone-node.js:390_loop_1 @ zone-node.js:417drainMicroTaskQueue @ zone-node.js:421```

我尝试将我的模板 html 内联,一切正常。

我的项目树如下所示:

当我尝试将模板放在它自己的 HTML 文件中时 - menu.component.html 这是 menu.component.ts 中的@Component 元数据:

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'ct-menu',
  templateUrl: 'menu.component.html'
})

export class MenuComponent {

}

该项目正在使用 webpack - 并编译到 root/build 文件夹中。 webpack.config.js 文件有以下内容:

var path = require('path');
var webpack = require('webpack');
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;

module.exports = {
  devtool: 'source-map',
  debug: true,

  entry: {
    'angular2': [
      'rxjs',
      'reflect-metadata',
      'zone.js',
      '@angular/core',
      '@angular/router',
      '@angular/http'
    ],
    'app': './app/app'
  },

  output: {
    path: __dirname + '/build/',
    publicPath: 'build/',
    filename: '[name].js',
    sourceMapFilename: '[name].js.map',
    chunkFilename: '[id].chunk.js'
  },

  resolve: {
    extensions: ['','.ts','.js','.json', '.css', '.html']
  },

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loader: 'ts',
        exclude: [ /node_modules/ ]
      }
    ]
  },

  plugins: [
    new CommonsChunkPlugin({ name: 'angular2', filename: 'angular2.js', minChunks: Infinity }),
    new CommonsChunkPlugin({ name: 'common',   filename: 'common.js' })
    ],
  target: 'electron-renderer'
};

我对电子和 angular2 都是新手!任何支持都将受到高度赞赏 - 我不喜欢使用内联模板。


在尝试了下面答案 1 的建议后,结果如下:

    import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'ct-menu',
  templateUrl: 'menu/menu.component.html'
})

export class MenuComponent {

}

这是构建目录:

【问题讨论】:

  • <base href="/"> 呢?
  • 这实际上破坏了一切。
  • 'That' 将默认的相对基本路径设置为 html 中使用的所有路径,因此它肯定会破坏一切。因此,请确保它的目标是正确的路径。但我认为你应该显示你的 build 输出目录,这就是它运行的地方。
  • 嗯,所以 electron 会从 file:// 加载您的页面。试试这个<base href="./">
  • RenegadeAndy 我已经回答了你的问题,希望对你有所帮助':o。如果我是你,我会开始赏金;-)

标签: javascript node.js angular electron


【解决方案1】:

好吧,我做了一些研究,发现问题来自您在 webpack 配置中使用的加载程序。使用webpack 时,您不必使用moduleId(仅SystemJS 需要),因为webpack 有它自己的angular2 模板加载器angular2-template-loader。此外,raw-loader 用于 htmlcss 文件。

首先,从component 声明中删除moduleId

...
@Component({
  selector: 'ct-menu',
  templateUrl: 'menu.component.html'
})

export class MenuComponent {
...

其次你必须安装angular2-template-loaderraw-loader

npm install --save-dev angular2-template-loader raw-loader

警告:确保所有angular2-template-loaderraw-loader 依赖都正确满足,否则webpack.config 将无法使用它。

注意 1angular2-template-loader 需要 reflect-metadata@0.1.3,因此您必须更改您的 package.json 依赖项并再次运行 npm install

最后,更改webpack.config 以对打字稿和静态文件使用正确的加载器。那么,您将能够运行webpack,然后运行npm start

module: {
    loaders: [
        {
            test: /\.ts$/,
            loaders: ['ts', 'angular2-template-loader'],
            exclude: [/\.(spec|e2e)\.ts$/]
        },
        {
            test: /\.(html|css)$/,
            loader: 'raw-loader'
        }
    ]
}

【讨论】:

  • 它有效 - 太棒了!我应该在上面的 webpack 配置中包含排除节点模块行吗?
  • @RenegadeAndy 好吧,这取决于你,排除会阻止 angular2 测试文件(app.component.spec.ts 等)在它们具有 .ts 扩展名后被加载,如果你没有测试,你可以删除它,但这根本不是问题。
  • 但是我原来的 webpack.config.js 有行 exclude: [ /node_modules/ ] 在从加载器的排除?我不知道这会有什么不同?
  • 我认为当不使用chuck插件时,webpack可以加载条目中指定的所有内容,包括来自note_modules的不必要文件,但我认为这种情况只会捆绑common、angular2和应用程序。但是最好排除 node_modules 如果您使用的是 libs 之类的节点,这可能会导致问题,请注意 /node_modules/ 是一个正则表达式,它会排除所有 node_modules 匹配的声音较大的人可以找到。
  • @RenegadeAndy 似乎没有必要包括,如果 node_module 成为问题,您会很快注意到。稍后我会检查您的下一个问题哈哈:{D
【解决方案2】:

你必须写相对于索引文件的路径:

templateUrl: 'menu/menu.component.html'

【讨论】:

  • 当您使用moduleId: module.id 时,没有必要允许相对于组件angular.io/docs/ts/latest/cookbook/… 的路径。
  • 感谢您的评论 :)
  • 这对我不起作用 - 请查看更新后的问题,我会在其中展示这会发生什么。
  • 当你使用moduleId:module.id,然后templateUrl:'menu/menu.component.html'
猜你喜欢
  • 2013-03-04
  • 2017-03-09
  • 2018-09-12
  • 2019-12-30
  • 2017-12-02
  • 2022-12-20
  • 1970-01-01
  • 2018-08-23
  • 2016-03-09
相关资源
最近更新 更多