无法导入自定义组件 - Angular2 和 TypeScript
Cannot import a custom component - Angular2 and TypeScript
我正在尝试在 app.ts 中导入自定义组件,但出现错误“TS2307:找不到模块 'MyComponent'”我已经看过了,找不到任何对我有帮助的东西。
有些人写道:使用 "moduleResolution":"classic",但如果我这样做,那么我会得到其他所有内容的 TS2307 错误(所有 angular2/ ...) 除了 MyComponent。
其他人写道 "run tsc --declaration MyComponent.ts" - 它确实生成了一个 MyComponent.d.ts 文件(同时在控制台中抛出错误,例如 "Cannot compile unless the --module flag is provided" - 它在 tsconfig 中作为选项提供 - 或 "Cannot find module 'angular2/common'" 对于我在 MyComponent.ts 中导入的任何内容 - 但它确实会生成一个 .d.ts 文件),但是在尝试编译 app.ts 时它仍然会给出相同的 TS2307 错误。我发现没什么用。
这是我的项目结构:
| /app
| /resources
| /dev
| /ts
| app.ts
| MyComponent.ts
| /dist
| /js
| app.js // transcompiled app.ts
| MyComponent.js // transcompiled MyComponent.ts
| /modules // files copied from the /node_modules/**/ folders (because node_modules is outside versioning and also outside public root (public root is the /app folder)
| es6-shim.js
| angular2-polyfills.js
| system.src.js
| Rx.js
| http.dev.js
| angular2.dev.js
| index.html
|
| /node_modules
| /angular2 // 2.0.0-beta.1
| /es6-promise // 3.0.2
| /es6-shim // 0.33.3
| /rxjs // 5.0.0-beta.0
| /reflect-metadata // 0.1.2
| /systemjs // 0.19.6
| /zone.js // 0.5.10
|
这是我的tsconfig.json:
{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"outDir": "app/resources/dist/js"
},
"files": [
"app/resources/dev/ts/app.ts"
]
}
我的app.ts:
import { bootstrap } from "angular2/platform/browser";
import { Component, View } from "angular2/core";
import { HTTP_PROVIDERS, Http, Response } from "angular2/http";
//My Custom Components:
import { MyComponent } from 'MyComponent';
/**
* APP
*/
@Component({
selector: 'my-app'
})
@View({
directives: [MyComponent],
template: `
<my-component></my-component>
plus other html
`
})
class MyApp {
public whatever;
constructor(public http: Http) {
// initialize this.whatever
}
makeRequest(): void {
this.http.request('/_http/response.json')
.subscribe((res:Response) => {
this.whatever = res.json();
});
}
}
bootstrap(MyApp, [ HTTP_PROVIDERS ]);
这是我的 MyComponent.ts:
import { Component } from 'angular2/core';
import { NgFor, NgIf } from 'angular2/common';
@Component({
selector: 'my-component',
template: `
<div>MY IMPORTED COMPONENT</div>
`
})
export class MyComponent {
constructor() {}
doSomething(): void {
console.log('Doing something');
}
}
我的app.ts和MyComponent.ts都在同一个文件夹里。无论如何,我也试过这样的路径:从“/app/resources/dev/ts/MyComponent”导入{MyComponent}。
另外,我已经尝试将它添加到 tsconfig 中的文件数组中(有些人写道我应该这样做)......仍然......没有任何效果!我也检查了 js 输出,因为有些人写即使它抛出错误,它可能仍然被编译......运气不好!
====================
编辑:
好的,正如 inoabrian 在第一条评论中建议的那样...我以为我尝试了所有方法,但似乎我还没有为导入部分尝试过“./MyComponent”。
import { MyComponent } from './MyComponent';
现在转译器开始工作了。谢谢 inoabrian,但现在我有另一个问题。当我在浏览器中尝试 运行 时,我检查了我的控制台并且 systemjs 和 angular2-pollyfills 尖叫:
http://my-app/resources/dist/js/MyComponent 404 (Not Found)
分别是:
XHR error (404 Not Found) loading http://my-app/resources/dist/js/MyComponent(…)
不要被路径所迷惑(与我的项目文件夹结构相比),当我访问 http://my-app
时,我的本地服务器指向 /app
这是我的 index.html 系统配置和所有包含的 js 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... Meta tags & CSS assets -->
<script src="resources/dist/modules/es6-shim.js"></script>
<script src="resources/dist/modules/angular2-polyfills.js"></script>
<script src="resources/dist/modules/system.src.js"></script>
<script src="resources/dist/modules/Rx.js"></script>
<script src="resources/dist/modules/http.dev.js"></script>
<script src="resources/dist/modules/angular2.dev.js"></script>
</head>
<body>
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('resources/dist/js/app.js')
.then(null, console.error.bind(console));
</script>
<my-app></my-app>
</body>
</html>
我觉得我应该对转译文件 "MyComponent.js" 再做一件事,但不知道是什么(我已经尝试将它添加到 System.import,希望它会接受一个数组......但它似乎没有)。接下来我该做什么?
P.S. 尽管如此,这还是令人失望,我希望将 MyComponent 导入 app.ts 将是一切,并且我会找到 MyComponent class + 来自 MyComponent.ts 的所有内容 + 我的转译 app.ts 文件全部在一个 app.js 文件中,没有另一个 js 文件:(
有点奇怪的是,您在与 app.js
相同的文件夹中没有 MyComponent.js
。在我的例子中,当我在 tsconfig.json
文件中添加 outDir
时,我所有的 TypeScript 文件都被编译成这个文件夹中的 JavaScript。
这是我在 tsconfig.json
文件中的配置:
{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir": "app/resources/dist/js"
},
"exclude": [
"node_modules"
]
}
我运行编译阶段用命令:tsc -w
.
希望对你有帮助,
蒂埃里
我相信您在系统配置中缺少正确的参数。
像这样添加:
System.config({
defaultJSExtensions: true
})
我知道它早就应该了,但也许其他人可能会从答案中受益。
我确实意识到最终的问题是什么(除了我已经在原始问题中编辑过的内容)。这里是:
我确实提到我有一个自定义文件夹结构并且不愿意更改它。如果我有,它会通过简单地遵循 angular 2 快速入门来工作。但这不会让我意识到我的具体情况下的问题,我也不会理解 System.js 是如何工作的。
问题出在我的 System.config() - 在包部分。
这是错误的代码:
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('my/path/to/app_main_file');
我的错误是认为键 "app" 只是一个通用键,来自单词 "application"。事实证明,在 packages 对象中,每个键实际上代表一个路径(该包 - 它是文件 - 在您的应用程序中驻留的位置)。所以,假设我的转译文件所在的文件夹是 "my/app/public" 并且 "app_main_file" 是我的应用程序的主要 js 文件,那么我实际上应该有这样的东西:
System.config({
packages: {
'my/app/public': {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('my/app/public/app_main_file')
.then(null, console.error.bind(console));
或者,你可以把配置部分写得更好,像这样:
System.config({
packages: {
'my-app': {
format: 'register',
defaultExtension: 'js'
}
},
map: {
'my-app': 'my/app/public'
}
});
我认为 "map" 的功能和使用方法不言自明。
P.S。我知道在我的回答中我没有遵循与原始问题完全相同的文件夹结构,但我认为这样解释更有意义。如果重要,只需将上面的 "my/app/public" 替换为我最初在问题中的内容:"resources/dist/js/",这是一回事。
我正在尝试在 app.ts 中导入自定义组件,但出现错误“TS2307:找不到模块 'MyComponent'”我已经看过了,找不到任何对我有帮助的东西。
有些人写道:使用 "moduleResolution":"classic",但如果我这样做,那么我会得到其他所有内容的 TS2307 错误(所有 angular2/ ...) 除了 MyComponent。
其他人写道 "run tsc --declaration MyComponent.ts" - 它确实生成了一个 MyComponent.d.ts 文件(同时在控制台中抛出错误,例如 "Cannot compile unless the --module flag is provided" - 它在 tsconfig 中作为选项提供 - 或 "Cannot find module 'angular2/common'" 对于我在 MyComponent.ts 中导入的任何内容 - 但它确实会生成一个 .d.ts 文件),但是在尝试编译 app.ts 时它仍然会给出相同的 TS2307 错误。我发现没什么用。
这是我的项目结构:
| /app
| /resources
| /dev
| /ts
| app.ts
| MyComponent.ts
| /dist
| /js
| app.js // transcompiled app.ts
| MyComponent.js // transcompiled MyComponent.ts
| /modules // files copied from the /node_modules/**/ folders (because node_modules is outside versioning and also outside public root (public root is the /app folder)
| es6-shim.js
| angular2-polyfills.js
| system.src.js
| Rx.js
| http.dev.js
| angular2.dev.js
| index.html
|
| /node_modules
| /angular2 // 2.0.0-beta.1
| /es6-promise // 3.0.2
| /es6-shim // 0.33.3
| /rxjs // 5.0.0-beta.0
| /reflect-metadata // 0.1.2
| /systemjs // 0.19.6
| /zone.js // 0.5.10
|
这是我的tsconfig.json:
{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"outDir": "app/resources/dist/js"
},
"files": [
"app/resources/dev/ts/app.ts"
]
}
我的app.ts:
import { bootstrap } from "angular2/platform/browser";
import { Component, View } from "angular2/core";
import { HTTP_PROVIDERS, Http, Response } from "angular2/http";
//My Custom Components:
import { MyComponent } from 'MyComponent';
/**
* APP
*/
@Component({
selector: 'my-app'
})
@View({
directives: [MyComponent],
template: `
<my-component></my-component>
plus other html
`
})
class MyApp {
public whatever;
constructor(public http: Http) {
// initialize this.whatever
}
makeRequest(): void {
this.http.request('/_http/response.json')
.subscribe((res:Response) => {
this.whatever = res.json();
});
}
}
bootstrap(MyApp, [ HTTP_PROVIDERS ]);
这是我的 MyComponent.ts:
import { Component } from 'angular2/core';
import { NgFor, NgIf } from 'angular2/common';
@Component({
selector: 'my-component',
template: `
<div>MY IMPORTED COMPONENT</div>
`
})
export class MyComponent {
constructor() {}
doSomething(): void {
console.log('Doing something');
}
}
我的app.ts和MyComponent.ts都在同一个文件夹里。无论如何,我也试过这样的路径:从“/app/resources/dev/ts/MyComponent”导入{MyComponent}。 另外,我已经尝试将它添加到 tsconfig 中的文件数组中(有些人写道我应该这样做)......仍然......没有任何效果!我也检查了 js 输出,因为有些人写即使它抛出错误,它可能仍然被编译......运气不好!
====================
编辑:
好的,正如 inoabrian 在第一条评论中建议的那样...我以为我尝试了所有方法,但似乎我还没有为导入部分尝试过“./MyComponent”。
import { MyComponent } from './MyComponent';
现在转译器开始工作了。谢谢 inoabrian,但现在我有另一个问题。当我在浏览器中尝试 运行 时,我检查了我的控制台并且 systemjs 和 angular2-pollyfills 尖叫:
http://my-app/resources/dist/js/MyComponent 404 (Not Found)
分别是:
XHR error (404 Not Found) loading http://my-app/resources/dist/js/MyComponent(…)
不要被路径所迷惑(与我的项目文件夹结构相比),当我访问 http://my-app
时,我的本地服务器指向 /app这是我的 index.html 系统配置和所有包含的 js 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... Meta tags & CSS assets -->
<script src="resources/dist/modules/es6-shim.js"></script>
<script src="resources/dist/modules/angular2-polyfills.js"></script>
<script src="resources/dist/modules/system.src.js"></script>
<script src="resources/dist/modules/Rx.js"></script>
<script src="resources/dist/modules/http.dev.js"></script>
<script src="resources/dist/modules/angular2.dev.js"></script>
</head>
<body>
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('resources/dist/js/app.js')
.then(null, console.error.bind(console));
</script>
<my-app></my-app>
</body>
</html>
我觉得我应该对转译文件 "MyComponent.js" 再做一件事,但不知道是什么(我已经尝试将它添加到 System.import,希望它会接受一个数组......但它似乎没有)。接下来我该做什么?
P.S. 尽管如此,这还是令人失望,我希望将 MyComponent 导入 app.ts 将是一切,并且我会找到 MyComponent class + 来自 MyComponent.ts 的所有内容 + 我的转译 app.ts 文件全部在一个 app.js 文件中,没有另一个 js 文件:(
有点奇怪的是,您在与 app.js
相同的文件夹中没有 MyComponent.js
。在我的例子中,当我在 tsconfig.json
文件中添加 outDir
时,我所有的 TypeScript 文件都被编译成这个文件夹中的 JavaScript。
这是我在 tsconfig.json
文件中的配置:
{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir": "app/resources/dist/js"
},
"exclude": [
"node_modules"
]
}
我运行编译阶段用命令:tsc -w
.
希望对你有帮助, 蒂埃里
我相信您在系统配置中缺少正确的参数。 像这样添加:
System.config({
defaultJSExtensions: true
})
我知道它早就应该了,但也许其他人可能会从答案中受益。 我确实意识到最终的问题是什么(除了我已经在原始问题中编辑过的内容)。这里是: 我确实提到我有一个自定义文件夹结构并且不愿意更改它。如果我有,它会通过简单地遵循 angular 2 快速入门来工作。但这不会让我意识到我的具体情况下的问题,我也不会理解 System.js 是如何工作的。
问题出在我的 System.config() - 在包部分。 这是错误的代码:
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('my/path/to/app_main_file');
我的错误是认为键 "app" 只是一个通用键,来自单词 "application"。事实证明,在 packages 对象中,每个键实际上代表一个路径(该包 - 它是文件 - 在您的应用程序中驻留的位置)。所以,假设我的转译文件所在的文件夹是 "my/app/public" 并且 "app_main_file" 是我的应用程序的主要 js 文件,那么我实际上应该有这样的东西:
System.config({
packages: {
'my/app/public': {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('my/app/public/app_main_file')
.then(null, console.error.bind(console));
或者,你可以把配置部分写得更好,像这样:
System.config({
packages: {
'my-app': {
format: 'register',
defaultExtension: 'js'
}
},
map: {
'my-app': 'my/app/public'
}
});
我认为 "map" 的功能和使用方法不言自明。
P.S。我知道在我的回答中我没有遵循与原始问题完全相同的文件夹结构,但我认为这样解释更有意义。如果重要,只需将上面的 "my/app/public" 替换为我最初在问题中的内容:"resources/dist/js/",这是一回事。