2016-09-14 4 views
12

У меня есть приложение Angular 2 RC7, где я использую SystemJS для загрузки файлов JavaScript.Angular 2: Как рассказать SystemJS использовать комплект?

Это моя текущая конфигурация для SystemJS:

(function (global) { 

System.config({ 

    defaultExtension: 'js', 
    defaultJSExtensions: true, 

    paths: { 
     'npm:': 'node_modules/' 
    }, 

    // Let the system loader know where to look for things 
    map: { 

     // Our app is within the app folder 
     app: 'app', 

     // Angular bundles 
     '@angular/core': 'npm:@angular/core/bundles/core.umd.js', 
     '@angular/common': 'npm:@angular/common/bundles/common.umd.js', 
     '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', 
     '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', 
     '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', 
     '@angular/http': 'npm:@angular/http/bundles/http.umd.js', 
     '@angular/router': 'npm:@angular/router/bundles/router.umd.js', 
     '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', 

     // Other libraries 
     'rxjs': 'npm:rxjs', 
     'ng2-translate': 'node_modules/ng2-translate' 

    }, 

    // Tell the system loader how to load when no filename and/or no extension 
    packages: { 
     app: { main: './main.js', defaultExtension: 'js' }, 
     rxjs: { defaultExtension: 'js' }, 
     'ng2-translate': { defaultExtension: 'js' } 
    } 

}); 

})(this); 

Теперь я создал пакет под названием app.bundle.min.js, который содержит все мои приложения логики, и dependencies.bundle.min.js, который содержит зависимости, используемые.

Как сообщить SystemJS использовать эти файлы вместо импорта файлов по отдельности?

Я попытался заменить это:

<script> 
    System.import('app').catch(function(err){ 
    console.error(err); 
    }); 
</script> 

с:

<script src="production/dependencies.bundle.min.js"></script> 
<script src="production/app.bundle.min.js"></script> 

в моей index.html, но это не работает. Пока я сохраняю блок сценариев System.import... внутри index.html, приложение загружается, но использует отдельные файлы вместо пакетов.

Я также попытался это изменить:

map: { 

    // Our app is within the app folder 
    app: 'production/app.bundle.min.js', 

, но это не сработало.

Это, как пучки генерируются с использованием Gulp:

gulp.task('inline-templates', function() { 

return gulp.src('app/**/*.ts') 
.pipe(inlineNg2Template({ 
    UseRelativePaths: true, 
    indent: 0, 
    removeLineBreaks: true 
})) 
.pipe(tsc({ 
    "target": "es5", 
    "module": "commonjs", 
    "moduleResolution": "node", 
    "sourceMap": true, 
    "emitDecoratorMetadata": true, 
    "experimentalDecorators": true, 
    "removeComments": true, 
    "noImplicitAny": false, 
    "suppressImplicitAnyIndexErrors": true 
})) 
.pipe(gulp.dest('dist')); 

}); 

gulp.task('bundle-app', ['inline-templates'], function() { 

var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js'); 

return builder 
    .bundle('dist/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'production/app.bundle.min.js', { 
     minify: true, 
     mangle: true 
    }) 
    .then(function() { 
     console.log('Build complete'); 
    }) 
    .catch(function(err) { 
     console.log('Build error'); 
     console.log(err); 
    }); 

}); 

gulp.task('bundle-dependencies', ['inline-templates'], function() { 

var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js'); 

return builder 
    .bundle('dist/**/*.js - [dist/**/*.js]', 'production/dependencies.bundle.min.js', { 
     minify: true, 
     mangle: true 
    }) 
    .then(function() { 
     console.log('Build complete'); 
    }) 
    .catch(function(err) { 
     console.log('Build error'); 
     console.log(err); 
    }); 

}); 

gulp.task('production', ['bundle-app', 'bundle-dependencies'], function(){}); 

Я подозреваю, что я должен каким-то образом изменить отображение в моей конфигурации SystemJS, чтобы указывать на пучки? Как мне это сделать?

+0

Трудно сказать, не зная точно, как пучки генерируются – artem

+0

Я добавил задачу Глоток на мой вопрос. –

ответ

22

Согласно map и packages в вашем SystemJS конфигурации,

System.import('app') 

переводит в запрос для файла app/main.js. Тем не менее, если смотреть в генерируемое приложении пачку, вы видите, что этот модуль действительно зарегистрирован как

System.registerDynamic("dist/main.js" ... 

, поскольку пучок был создан из .js файлов в папке dist.

Это несоответствие является причиной того, что ваши модули не загружаются из набора сценариев.

Одним из возможных решений является всегда держать .ts и .js файлы в отдельных папках - .ts в app, .js в dist. Таким образом, systemjs нужно будет только знать о dist: только часть systemjs.config.js, что необходимо изменить это app отображения:

// Let the system loader know where to look for things 
map: { 

    // Our app is compiled to js files in the dist folder 
    app: 'dist', 

Чтобы проверить, что это работает, я начал с angular quickstart example и добавил gulpfile.js с эти задачи:

  1. компиляции машинопись в dist используя gulp-typescript плагин.

    var gulp = require('gulp'); 
    var typescript = require('typescript'); 
    var tsc = require('gulp-typescript'); 
    
    var systemjsBuilder = require('systemjs-builder'); 
    
    gulp.task('tsc', function() { 
    
        return gulp.src(['app/**/*.ts', 'typings/index.d.ts']) 
        .pipe(tsc({ 
         "target": "es5", 
         "module": "commonjs", 
         "moduleResolution": "node", 
         "sourceMap": true, 
         "emitDecoratorMetadata": true, 
         "experimentalDecorators": true, 
         "removeComments": true, 
         "noImplicitAny": false, 
         "suppressImplicitAnyIndexErrors": true 
        })) 
        .js.pipe(gulp.dest('dist')); 
    }); 
    
  2. копия systemjs конфигурационный файл в dist папку, так что будет поставляться в комплекте вместе с кодом приложения и будут доступны в производстве (это необходимо, потому что вы используете bundle и не buildStatic)

    gulp.task('bundle-config', function() { 
        return gulp.src('app/configs/systemjs.config.js') 
        .pipe(gulp.dest('dist/configs')); 
    }); 
    
  3. генерировать пучки с systemjs строитель:

    gulp.task('bundle-app', ['bundle-config', 'tsc'], function() { 
    
        var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js'); 
        return builder 
         .bundle('[dist/**/*]', 'production/app.bundle.min.js', { 
          minify: true, 
          mangle: true 
         }) 
         .then(function() { 
          console.log('Build complete'); 
         }) 
         .catch(function(err) { 
          console.log('Build error'); 
          console.log(err); 
         }); 
    
    }); 
    
    gulp.task('bundle-dependencies', ['bundle-config', 'tsc'], function() { 
    
        var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js'); 
        return builder 
         .bundle('dist/**/* - [dist/**/*.js]', 'production/dependencies.bundle.min.js', { 
          minify: true, 
          mangle: true 
         }) 
         .then(function() { 
          console.log('Build complete'); 
         }) 
         .catch(function(err) { 
          console.log('Build error'); 
          console.log(err); 
         }); 
    
        }); 
    
    gulp.task('production', ['bundle-app', 'bundle-dependencies'], function(){}); 
    

Обратите внимание, что он использует [dist/**/*] синтаксис для генерации пакета приложений без каких-либо зависимостей - тот, что находится в вашем gulpfile.js, отличается и генерирует гораздо больший пакет, который включает в себя некоторые зависимости - я не знаю, намеренно это или нет.

Затем я создал index-production.html с этими изменениями от index.html:

  1. удалить <script> тег для systemjs.config.js - мы импортировать его из пакета

  2. добавить <script> теги для пучков в <head>

    <script src="production/dependencies.bundle.min.js"></script> 
    <script src="production/app.bundle.min.js"></script> 
    
  3. добавить в себя, который импортирует конфигурации и приложения модуля:

    <script> 
        System.import('dist/configs/systemjs.config.js').then(function() { 
        System.import('app').catch(function(err){ console.error(err); }); 
        }); 
    </script> 
    

импортируя модуль «приложения» необходимо потому, что пучки, генерируемые с bundle ничего не импортировать и не запускать любой код - они только делает все модули доступны для импорта позже, в отличие от пакетов 'sfx', сгенерированных с buildStatic.

Кроме того, этот блок сценария должен быть в элементе <body> после <my-app>, в противном случае app начнет слишком рано, когда <my-app> элемента еще не создан (в качестве альтернативы, import('app') можно назвать на «документ» готовое событие).

Вы можете найти полный пример на GitHub: https://github.com/fictitious/test-systemjs-angular-gulp

+0

Удивительный ответ. Большое спасибо! Ваше решение работало как прелесть. –

+0

@artem возможно ли это решение для отладки ts-файлов в браузере? – Yvan

+0

@Yvan Да, вам нужно установить и настроить gulp-sourcemaps. Я обновил пример репо. – artem

Смежные вопросы