请参见底部的进一步更新 ...
我有一个非常大的应用程序,我试图从Angular 1.6转换为Angular 4.0。它已成为一项艰巨的任务,我陷入了困境。我们在两个不同的应用程序之间使用了一组通用实用程序。试图将其编译成可以通过" npm link"导入的模块。导入我的应用程序时出现以下错误。
我正在使用webpack 3。
compiler.es5.js:1690 Uncaught Error: Unexpected value 'TestModule' imported by the module 'AppModule'. Please add a @NgModule annotation.
at syntaxError (compiler.es5.js:1690)
at compiler.es5.js:15382
at Array.forEach (<anonymous>)
at CompileMetadataResolver.getNgModuleMetadata (compiler.es5.js:15365)
at JitCompiler._loadModules (compiler.es5.js:26795)
at JitCompiler._compileModuleAndComponents (compiler.es5.js:26768)
at JitCompiler.compileModuleAsync (compiler.es5.js:26697)
at PlatformRef_._bootstrapModuleWithZone (core.es5.js:4536)
at PlatformRef_.bootstrapModule (core.es5.js:4522)
at Object.<anonymous> (main.ts:26)
我创建了一个测试用例,最小化了我的问题。它看起来有点复杂,因为我将webpack.config和package.json文件与我的实际案例大致相同,但代码减少到最低限度。
您可以看到代码https://github.com/crowmagnumb/ng-migration-test以及完全重新创建问题的步骤。
我的应用中的 main.ts 文件看起来像这样......
import './polyfills';
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {UpgradeModule} from '@angular/upgrade/static';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {TestModule} from 'ng-module-test';
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
UpgradeModule,
TestModule
]
})
export class AppModule {
// Override Angular bootstrap so it doesn't do anything
ngDoBootstrap() {
}
}
// Bootstrap using the UpgradeModule
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
console.log("Bootstrapping in Hybrid mode with Angular & AngularJS");
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document.body, ['au.website']);
});
......我的模块看起来像......
import {NgModule} from '@angular/core';
import {Utils} from './utils/module';
@NgModule({
imports: [
Utils
]
})
export class TestModule {};
感谢您的帮助。
更新
我将TestModule的导入更改为相对路径,而不是通过链接的npm模块加载,如此...
// import {TestModule} from 'ng-module-test';
import {TestModule} from '../../ng-module-test/src/main';
......我得到了同样的结果。所以它似乎与 npm link 无关,而是与代码的特定分离有关。任何人都可以阐明这一点吗?
我已经检查了上述回购的变化。
进一步更新
现在我完全不理解这一点。如果我将导入更改为阅读...
import {TestModule} from './ng-module-test/main';
...我在 ng-app-test / src 中创建一个名为 ng-module-test 的目录,然后复制的内容ng-module-test / src 文件夹,然后在评论中发现@Hosar。但是,如果我使用 ln -s ../../ng-module-test/src ng-module-test 对代码进行符号链接,以便有效地从底层操作系统的立场完全相同, IT DOESN&#34; T WORK。
答案 0 :(得分:1)
你需要在ng-module-test / package.json中使所有的@angular包成为peerDependency和devDependency而不是依赖
然后将以下内容添加到ng-app-test / src / tsconfig.json:
{
"compilerOptions": {
// ...
// Note: these paths are relative to `baseUrl` path.
"paths": {
"@angular/*": [
"../node_modules/@angular/*"
]
}
}
}
查看完整说明: https://github.com/angular/angular-cli/wiki/stories-linked-library
答案 1 :(得分:1)
我找到了符号链接方向的解决方案。只需要在webpack.config.js的resolve部分中将符号链接设置为false(反直觉)。例如......
resolve: {
extensions: ['.ts', '.tsx', '.js'],
symlinks: false
},
但是这仍然不允许我使用 npm链接,因为它仍然失败。但是现在这样可以让我继续前进。在某些方面,它更好,因为现在手表系统会自动获取我的打字稿文件中的更改。但是,如果我确定需要/需要发布此库,它并没有提供很大的灵活性。但是,如果我稍后想出来,那将只是一个全局搜索并替换以修复它。
所以,最后,看起来我会在我的应用中添加一个符号链接&#39; src dir指向我库的src目录。然后我将通过...导入该库中的内容。
import {Blah} from './ng-module-test/main';
......或(例如)......
import {Blah} from '../../ng-module-test/main';
...取决于我导入的文件有多深入src dir。我将查看webpack配置的模块属性,看看我是否可以将其作为...来解决...
import {Blah} from 'ng-module-test/main';
......无处不在。或者更好,甚至放弃主力。如果我管理它,我会给出解决方案。
<强>更新强>
更好的解决方案。多亏了这个link我能够实现一个更好的解决方案,它不涉及符号链接(除非你想使用一个而不是将相对路径放到我想的库模块中)。
如果我将以下内容添加到 tsconfig.json 文件中:
"paths": {
"NgModuleTest/*": ["../ng-module-test/src/*"]
}
...然后将 webpack.config.js 中的解决方案更改为...
const TsConfigPathsPlugin = require('awesome-typescript-loader').TsConfigPathsPlugin;
resolve: {
extensions: ['.ts', '.tsx', '.js'],
// symlinks: false,
modules: [
`${__dirname}/node_modules`
],
plugins: [
new TsConfigPathsPlugin({
tsconfig: './tsconfig.json',
compiler: 'typescript'
})
]
}
...然后,我可以通过...
引用导入到我的外部库import {Blah} from 'NgModuleTest/main';
...无论我在src树中的哪个位置。另外,我可以添加尽可能多的这些路径,以便我可以以同样简单的方式引用内部模块。尼斯。我没有测试,看看tsconfig.json中的路径是否接受符号链接,正如我所说,这对于syml的symlink属性意味着什么。但我可以使用tsconfig.json指向该目录之外的代码,就像我上面所做的那样。
哦,顺便说一句,我将tsrc.json从src移到了根目录下与webpack.config.js一起,因为我有一些路径问题似乎可以在同一个位置解决它们。它确实如此。我认为这可能是必要的,以便插件具有与tsconfig.json相同的相对路径。
使用此解决方案更新了上面的回购。