SystemJS导入在捆绑的Angular2应用程序上静默失败

时间:2016-09-21 09:22:09

标签: javascript angular gulp systemjs

我在使用SystemJS时遇到了麻烦。

我有一个用Typescript编写的典型Angular2应用程序。 我正在尝试将所有应用程序.js捆绑到一个文件中以优化加载时间。

捆绑包是由gulp使用systemjs-builder创建的,如下所示:

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();
        });
});

通过脚本标记加载包。它可以正常工作,因为在浏览器控制台中调用System.defined会显示我的模块: 的 System.defined

System.defined(picture)

这是我的systemjs.config.js。如果我理解了正确的事情,请导入" app"应解析为wwwroot / app / main.ts,然后通过"捆绑"解析到捆绑文件参数。

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);

然而,一旦我尝试从index.html导入我的入口点,没有任何反应(意味着我没有进入我的回调或我的catch块)。这是我索引的摘录:

<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>

我尝试过各种各样的事情,比如使用bundleStatic,导入app / main.js,更改捆绑选项。 感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

我认为你很先进,你有很好的角度理解。

我遇到与@angular/upgrade组件类似的问题。在经历了严重的头痛之后,我发现angular2中的一些错误信息丢失了(即使在当前稳定的包中)。

可能的错误来源可能在@angular/compiler内。 RuntimeCompiler.compileComponents()正在丢失来自CompileMetadataResolver.getNgModuleMetadata()的邮件。简单但不理想的解决方案是在try-catch块中包含对getNgModuleMetadata的调用。

使用捆绑编译器和angular 2.0.0时的解决方案:

compiler.umd.js:第16799行

改变这个:

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) {
   ...

为:

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) {
 ...

显然,这不是理想的解决方案,但我能够发现我的一个模块具有循环依赖(导致undefined而不是NgModule.import内的有效服务。)