Javascript 当未指定 js 扩展名时,Angular2 Typescript 应用程序在组件上抛出 404

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34381182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:14:18  来源:igfitidea点击:

Angular2 Typescript app throws 404 on components when js extension not specified

javascripttypescriptangularpolyfills

提问by xlecoustillier

I just started to play around with Angular2, and ran into a weird component file extension problem:

我刚开始玩 Angular2,遇到了一个奇怪的组件文件扩展问题:

Let's use the 5 minutes quickstart demo from angular.io(I'll reproduce the code here for reference).

让我们使用angular.io 中5 分钟快速入门演示(我将在此处重现代码以供参考)。

File structure

文件结构

angular2-quickstart
|- app
|  |- app.component.ts
|  |- boot.ts
|
|- index.html
|- package.json
|- tsconfig.json

package.json

包.json

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
  },
  "license": "ISC",
  "dependencies": {
    "angular2": "2.0.0-beta.0",
    "systemjs": "0.19.6",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.33.3",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.0",
    "zone.js": "0.5.10"
  },
  "devDependencies": {
    "concurrently": "^1.0.0",
    "lite-server": "^1.3.1",
    "typescript": "^1.7.3"
  }
}

tsconfig.json

配置文件

{
  "compilerOptions": {
    "target": "ES5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules"
  ]
}

app/app.component.ts

应用程序/app.component.ts

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }

app/boot.ts

应用程序/boot.ts

import {bootstrap}    from 'angular2/platform/browser'
import {AppComponent} from './app.component'

bootstrap(AppComponent);

index.html

索引.html

<html>

  <head>
    <title>Angular 2 QuickStart</title>

    <!-- 1. Load libraries -->
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

  </head>

  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>

</html>

This works like a charm, but exposes the whole file structure, including node_modulesand the configuration, which seems like a bad idea.

这就像一个魅力,但暴露了整个文件结构,包括node_modules和配置,这似乎是一个坏主意。

So I tried to expose only the appfolder. To achieve that, I did the following:

所以我试图只公开app文件夹。为了实现这一点,我做了以下事情:

  • Copy the referenced javascript files in an app/scriptsfolder
  • Move the index.htmlin app
  • Change the references paths in this file
  • Change the litescript in package.jsonto lite-server --baseDir app
  • 将引用的 javascript 文件复制到文件app/scripts夹中
  • 移动index.htmlapp
  • 更改此文件中的引用路径
  • lite脚本更改package.jsonlite-server --baseDir app

When running this, everything worked, except that angular2-polyfills.jsreturned :

运行此程序时,一切正常,除了angular2-polyfills.js返回:

Error: XHR error (404 Not Found) loading http://localhost:3000/app.component(…)
  run @ angular2-polyfills.js:138
  zoneBoundFn @ angular2-polyfills.js:111
  lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511
  lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523
  lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494
  lib$es6$promise$$internal$$publishRejection @ angular2-polyfills.js:1444
  (anonymous function) @ angular2-polyfills.js:243
  run @ angular2-polyfills.js:138zoneBoundFn @ angular2-polyfills.js:111
  lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305

Of course, if I ask for http://localhost:3000/app.component.jsthe file is returned correctly.

当然,如果我要求http://localhost:3000/app.component.js的文件是正确返回的。

So my question is: why doesn't the .jsextension get appended to app.component, resulting in this error, where that worked when the server baseDir was the root of the project ? Did I miss some configuration option ?

所以我的问题是:为什么没有将.js扩展附加到app.component,导致这个错误,当服务器 baseDir 是项目的根时,它在哪里工作?我错过了一些配置选项吗?

采纳答案by headwinds

You can configure the path to your app folder. In my case, I'm using angular 2 to produce a mobile version of our app and had to configure System like so:

您可以配置应用程序文件夹的路径。就我而言,我使用 angular 2 来生成我们应用程序的移动版本,并且必须像这样配置 System:

System.config({
            paths: {
                'app/*': './js/mobile/dist/*'
            },
            packages: {        
              app: {
                format: 'register',
                defaultExtension: 'js'
              }
            }
          });
          System.import('app/main')
                .then(null, console.error.bind(console));

As you can see, I decided to map "app" to "dist" where I have my compiled js files to keep them separate from the ts files.

如您所见,我决定将“app”映射到“dist”,在那里我编译了 js 文件,以将它们与 ts 文件分开。

回答by Alex Hopkins

This problem may be caused by JetBrains WebStorm when refactoring files to new locations. It seems to append the .ts extension on imports.

此问题可能是由 JetBrains WebStorm 在将文件重构到新位置时引起的。它似乎在导入时附加了 .ts 扩展名。

So, keep your new files in their places but check every file's imports.

因此,请将您的新文件保存在原处,但要检查每个文件的导入。

All of your imports should resemble this

你所有的进口都应该像这样

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

And not this

而不是这个

import {MyComponent} from './Components/MyComponent.ts';

回答by Steven Leggett

In my boot.tsfile I changed this line:

在我的boot.ts文件中,我更改了这一行:

import {AppComponent} from './app.components'

import {AppComponent} from './app.components'

and it works. I reported to Google today as well.

它有效。我今天也向谷歌报告了。

回答by HydTechie

In my case, it is resolved when added module.id

在我的情况下,它在添加时解决 module.id

@Component({
    ***moduleId: module.id,***
    providers : [MyService],
    templateUrl: 'sandbox.component.html',
})

回答by ali-myousefi

after trying many other solutions suggested by others, I found out it can case by dots in filenamesand these two solutions worked for me. first:

在尝试了其他人建议的许多其他解决方案后,我发现文件名中可以区分大小写,这两个解决方案对我有用。第一的:

defaultJSExtensions: true,

but defaultJSExtensions is a property that will be deprecated in futureand second:

defaultJSExtensions 是一个在未来和第二个将被弃用的属性

packages: {
            '.': {
                defaultExtension: 'js'
            }
        }

回答by Tyson Sukeforth

You're missing app/main.ts. It's only a few lines, so it's fairly easy to miss in the quickstart.

你缺少 app/main.ts。它只有几行,因此在快速入门中很容易错过。

回答by Neel Krishna

I had the same error with chrome, after pulling my hair out for a while I tried turning off adblock and it worked after that. If you have adblock, it's probably the culprit

我在使用 chrome 时遇到了同样的错误,在将头发拉出一段时间后,我尝试关闭 adblock,然后它就起作用了。如果你有广告拦截,它可能是罪魁祸首