[英]SystemJS import fails silently on bundled Angular2 app
I am having trouble with SystemJS. 我在使用SystemJS时遇到麻烦。
I have a typical Angular2 application written in Typescript. 我有一个用Typescript编写的典型Angular2应用程序。 I am trying to bundle all my application .js into a single file to optimize load time. 我试图将所有应用程序.js捆绑到一个文件中,以优化加载时间。
The bundle is created by gulp using systemjs-builder like this : 捆绑包是由gulp使用systemjs-builder创建的,如下所示:
gulpfile.js gulpfile.js
paths.compiledTs = "./wwwroot/app";
gulp.task('bundle:app', function (done) {
var builder = new Builder("/", './systemjs.config.js');
var builderConfig = {
normalize: true,
minify: true,
mangle: true,
runtime: false
};
builder.bundle(paths.compiledTs + '/main.js', paths.compiledTs + '/middleware-app.js', builderConfig)
.then(function () {
done();
})
.catch(function (err) {
console.log(err);
done();
});
});
The bundle is loaded though script tag. 通过脚本标记加载捆绑软件。 It works correcly as a call to System.defined in the browser console shows my modules : System.defined 它在浏览器控制台中对System.defined的调用正确地显示了我的模块: System.defined
System.defined(picture) System.defined(图片)
Here is my systemjs.config.js. 这是我的systemjs.config.js。 If I understand things correctly, an import to "app" should resolve to wwwroot/app/main.ts, then to the bundle file through the "bundles" parameter. 如果我理解正确,则导入“ app”应解析为wwwroot / app / main.ts,然后通过“ bundles”参数解析为捆绑文件。
systemjs.config.js systemjs.config.js
/**
* System configuration
*/
(function (global) {
// map tells the System loader where to look for things
var map = {
'app': 'wwwroot/app',
'@angular': 'wwwroot/lib/@angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main:'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'lodash': { defaultExtension: 'js' },
'moment': { defaultExtension: 'js' },
'pikaday': { defaultExtension: 'js' },
'ng2-translate': { defaultExtension: 'js' },
};
var ngPackageNames = [
'common',
'compiler',
'core',
'forms',
'http',
'platform-browser',
'platform-browser-dynamic',
'router'
];
// Individual files (~300 requests):
function packNgIndex(pkgName) {
packages['@angular/' + pkgName] = { main: 'index.js', defaultExtension: 'js' };
}
// Bundled (~40 requests):
function packNgUmd(pkgName) {
packages['@angular/' + pkgName] = { main: 'bundles/' + pkgName + '.umd.min.js', defaultExtension: 'js' };
}
// Most environments should use UMD; some (Karma) need the individual index files
var setNgPackageConfig = System.packageWithIndex ? packNgIndex : packNgUmd;
// Add package entries for angular packages
ngPackageNames.forEach(setNgPackageConfig);
var config = {
defaultJSExtensions: true,
baseURL: global.baseUrl,
paths: {
"lodash": "wwwroot/lib/lodash.min.js",
"moment": "wwwroot/lib/moment.min.js",
"pikaday": "wwwroot/lib/pikaday.js"
},
map: map,
packages: packages,
meta: {
pikaday: {
deps: ['moment']
},
'angular2/*': {
build: false
},
'rxjs/*': {
build: false
},
'ng2-translate/*': {
build: false
}
},
bundles: {
"wwwroot/lib/bundles/rxjs.min.js": [
"rxjs/*",
"rxjs/operator/*",
"rxjs/observable/*",
"rxjs/add/operator/*",
"rxjs/add/observable/*",
"rxjs/util/*"
],
"wwwroot/lib/bundles/ng2-translate.min.js": [
"ng2-translate/*"
],
"wwwroot/app/middleware-app.js": [
"app/*",
"app/common/busy-indicator/*",
"app/common/config/*",
"app/common/date-picker/*",
"app/common/dialog/*",
"app/common/guards/*",
"app/common/interface/*",
"app/common/login/*",
"app/common/models/*",
"app/common/pagination/*",
"app/common/services/*",
"app/common/storage/*",
"app/i18n/*",
"app/layout/*",
"app/pages/authentication/*",
"app/pages/logs/*",
"app/pages/monitoring/*",
"app/pages/not-found/*",
"app/pages/referentials/*",
"app/pages/reports/*"
]
}
};
System.config(config);
})(this);
However once I attempt to import my entry point from index.html, nothing happens (meaning I don't enter my then callback or my catch block). 但是,一旦我尝试从index.html导入我的入口点,就什么也没有发生(这意味着我不输入我的then回调或catch块)。 Here is an extract of my index : 这是我的索引的一部分:
<script src="@Href("~/wwwroot/app/middleware-app.js")"></script>
<script type="text/javascript">
System.import('app')
.then(app => {
console.log("never entered");
var endpoint = '@endpointUrl';
var version = '@Html.Version()';
var production = @Html.IsProductionEnabled();
app.run(endpoint, version, production);
})
.catch(function (err) {
console.log("never entered as well");
console.error(err);
});
</script>
I have tried various things like using bundleStatic instead, importing app/main.js, changing the bundling options. 我尝试了各种方法,例如改用bundleStatic,导入app / main.js,更改捆绑选项。 Thank you for any help you can provide. 感谢您提供任何帮助。
I assume that you are quite advanced and you have good angular2 understanding. 我认为您很高级,并且对Angular2有很好的理解。
I had similar issue with @angular/upgrade
component. 我对@angular/upgrade
组件有类似的问题。 After serious headache, I have found out that some of the error messages are lost inside angular2 (even in currently stable package). 经过严重的头痛之后,我发现在angular2内部(甚至在当前稳定的软件包中)丢失了一些错误消息。
The possible source of error can be inside @angular/compiler
. 错误的可能来源可以在@angular/compiler
内部。 The RuntimeCompiler.compileComponents()
is losing messages from CompileMetadataResolver.getNgModuleMetadata()
. RuntimeCompiler.compileComponents()
正在丢失来自CompileMetadataResolver.getNgModuleMetadata()
消息。 Simple, yet not ideal solution is to wrap call to getNgModuleMetadata
in try-catch block. 简单但不是理想的解决方案是getNgModuleMetadata
调用getNgModuleMetadata
在try-catch块中。
Solution when you are using bundled compiler and angular 2.0.0: 使用捆绑的编译器和angular 2.0.0时的解决方案:
compiler.umd.js:line 16799 editor.umd.js:第16799行
Change this: 更改此:
RuntimeCompiler.prototype._compileComponents = function (mainModule, isSync) {
var _this = this;
var templates = new Set();
var loadingPromises = [];
var ngModule = this._metadataResolver.getNgModuleMetadata(mainModule);
ngModule.transitiveModule.modules.forEach(function (localModuleMeta) {
...
to: 至:
RuntimeCompiler.prototype._compileComponents = function (mainModule, isSync) {
var _this = this;
var templates = new Set();
var loadingPromises = [];
try {
var ngModule = this._metadataResolver.getNgModuleMetadata(mainModule);
} catch(e) {
console.log(e);
throw e;
}
ngModule.transitiveModule.modules.forEach(function (localModuleMeta) {
...
Obviously, this is not ideal solution, but I was able to find out that one of my modules had circular dependency (which was causing undefined
instead of valid service inside NgModule.import
). 显然,这不是理想的解决方案,但是我能够发现我的一个模块具有循环依赖关系(这导致undefined
而不是NgModule.import
内部的有效服务)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.