Angular 2 + Typescript + systemjs uygulamasını gerçekte nasıl dağıtırım?


103

Angular.io'da typcript ve systemjs kullanan bir hızlı başlangıç ​​öğreticisi var. Artık o mini uygulamayı çalıştırdığıma göre, konuşlandırılabilir bir şey yaratmaya nasıl başlayabilirim? Bununla ilgili herhangi bir bilgi bulamadım.

System.config dosyasında herhangi bir ek araca, herhangi bir ek ayara ihtiyacım var mı?

(Webpack'i kullanabileceğimi ve tek bir bundle.js oluşturabileceğimi biliyorum, ancak eğitimde kullanıldığı gibi systemjs kullanmak istiyorum)

Birisi bu kurulumla derleme sürecini paylaşabilir mi (Angular 2, TypeScript, systemjs)


İşte JSPM kullanarak dağıtım için bir ng2 uygulaması oluşturmaya yönelik tarifim: stackoverflow.com/a/34616199/3532945
brando

2
basit cevap ng build -prod stackoverflow.com/a/38421680/5079380
Amr ElAdawy

Yanıtlar:


66

Bu seviyede anlaşılması gereken en önemli şey, aşağıdaki yapılandırmayı kullanarak, derlenmiş JS dosyalarını doğrudan birleştiremezsiniz.

TypeScript derleyici yapılandırmasında:

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "declaration": false,
    "stripInternal": true,
    "module": "system",
    "moduleResolution": "node",
    "noEmitOnError": false,
    "rootDir": ".",
    "inlineSourceMap": true,
    "inlineSources": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules"
  ]
}

HTML'de

System.config({
  packages: {
    app: {
      defaultExtension: 'js',
      format: 'register'
    }
  }
});

Nitekim, bu JS dosyaları anonim modüller içerecektir. Anonim bir modül, System.registermodül adını ilk parametre olarak kullanan ancak içermeyen bir JS dosyasıdır . Systemjs modül yöneticisi olarak yapılandırıldığında, typcript derleyicisinin varsayılan olarak ürettiği şey budur.

Bu nedenle, tüm modüllerinizin tek bir JS dosyasında olması için outFile, TypeScript derleyici yapılandırmanızdaki özelliğinden yararlanmanız gerekir .

Bunu yapmak için içindeyken aşağıdakileri kullanabilirsiniz:

const gulp = require('gulp');
const ts = require('gulp-typescript');

var tsProject = ts.createProject('tsconfig.json', {
  typescript: require('typescript'),
  outFile: 'app.js'
});

gulp.task('tscompile', function () {
  var tsResult = gulp.src('./app/**/*.ts')
                     .pipe(ts(tsProject));

  return tsResult.js.pipe(gulp.dest('./dist'));
});

Bu, başka bir işlemle birleştirilebilir:

  • derlenmiş TypeScript dosyalarını çirkinleştirmek için
  • bir app.jsdosya oluşturmak için
  • vendor.jsüçüncü taraf kitaplıklar için bir dosya oluşturmak için
  • boot.jsUygulamayı önyükleyen modülü içe aktarmak için bir dosya oluşturmak için . Bu dosya sayfanın sonuna eklenmelidir (tüm sayfa yüklendiğinde).
  • index.htmlbu iki dosyayı hesaba katacak şekilde güncellemek için

Yudum görevlerinde aşağıdaki bağımlılıklar kullanılır:

  • gulp-concat
  • gulp-html-replace
  • gulp-typcript
  • yutkunma

Aşağıdaki, uyarlanabilmesi için bir örnektir.

  • app.min.jsDosya oluştur

    gulp.task('app-bundle', function () {
      var tsProject = ts.createProject('tsconfig.json', {
        typescript: require('typescript'),
        outFile: 'app.js'
      });
    
      var tsResult = gulp.src('app/**/*.ts')
                       .pipe(ts(tsProject));
    
      return tsResult.js.pipe(concat('app.min.js'))
                    .pipe(uglify())
                    .pipe(gulp.dest('./dist'));
    });
  • vendors.min.jsDosya oluştur

    gulp.task('vendor-bundle', function() {
      gulp.src([
        'node_modules/es6-shim/es6-shim.min.js',
        'node_modules/systemjs/dist/system-polyfills.js',
        'node_modules/angular2/bundles/angular2-polyfills.js',
        'node_modules/systemjs/dist/system.src.js',
        'node_modules/rxjs/bundles/Rx.js',
        'node_modules/angular2/bundles/angular2.dev.js',
        'node_modules/angular2/bundles/http.dev.js'
      ])
      .pipe(concat('vendors.min.js'))
      .pipe(uglify())
      .pipe(gulp.dest('./dist'));
    });
  • boot.min.jsDosya oluştur

    gulp.task('boot-bundle', function() {
      gulp.src('config.prod.js')
        .pipe(concat('boot.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('./dist'));
     });

    config.prod.jsBasitçe aşağıdaki içeriklere:

     System.import('boot')
        .then(null, console.error.bind(console));
  • index.htmlDosyayı güncelleyin

    gulp.task('html', function() {
      gulp.src('index.html')
        .pipe(htmlreplace({
          'vendor': 'vendors.min.js',
          'app': 'app.min.js',
          'boot': 'boot.min.js'
        }))
        .pipe(gulp.dest('dist'));
    });

    index.htmlAşağıdaki gibi görünüyor:

    <html>
      <head>
        <!-- Some CSS -->
    
        <!-- build:vendor -->
        <script src="node_modules/es6-shim/es6-shim.min.js"></script>
        <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
        <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
        <script src="node_modules/systemjs/dist/system.src.js"></script>
        <script src="node_modules/rxjs/bundles/Rx.js"></script>
        <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
        <script src="node_modules/angular2/bundles/http.dev.js"></script>
        <!-- endbuild -->
    
        <!-- build:app -->
        <script src="config.js"></script>
        <!-- endbuild -->
      </head>
    
      <body>
        <my-app>Loading...</my-app>
    
        <!-- build:boot -->
        <!-- endbuild -->
      </body>
    </html>

System.import('boot');Tüm uygulama bileşenlerinizin app.min.jsdosyadan kaydedilmesini beklemek için gövdenin sonunda yapılması gerektiğine dikkat edin .

Burada CSS ve HTML küçültme işleminin nasıl yapıldığını anlatmıyorum.


1
bir örnekle bir github deposu oluşturabilir misiniz lütfen?
jdelobel

Talimatlarına uydum ve yudumla ilgili her şey yolunda görünüyor. Ancak, uygulamayı tarayıcıda çalıştırdığımda şu konsol günlüğü hatasını alıyorum: "system.src.js: 1625 Yakalanmamış TypeError: Aynı modül dosyasında birden çok anonim System.register çağrısı." Bunun ne anlama geldiğine ve nasıl düzeltileceğine dair bir fikriniz var mı?
AngularM

@AngularM: outFile parametreniz var mı?
Thierry Templier


Gönderdiğim github projesine bir göz atabilir misin? Yukarıdaki yorumuma bakın. Kodunuzla bazı farklılıklar görüyor musunuz?
Thierry Templier

28

Angular2-cli inşa komutunu kullanabilirsiniz

ng build -prod

https://github.com/angular/angular-cli/wiki/build#bundling

-Prod bayrağıyla oluşturulan yapılar, tüm bağımlılıkları tek bir dosyada toplarng build -prod veya paketler ve ağaç sallama tekniklerinden yararlanır.ng serve -prod

Güncelleme

Bu cevap, angular2 rc4 içindeyken sunulmuştur

Angular-cli beta21 ve angular2 ^ 2.1.0 üzerinde tekrar denedim ve beklendiği gibi çalışıyor

Bu cevap, uygulamayı kullanabileceğiniz angular-cli ile başlatmayı gerektirir

ng new myApp

Veya mevcut bir tanesinde

ng init

Güncelleme 08/06/2018

Açısal 6 için sözdizimi farklıdır.

ng build --prod --build-optimizer

Belgeleri kontrol edin


8
Bu, uygulamanızın angular-cli'nin düşünceli yapısında yapılandırılmasını gerektirir.
Michael Pell

2
@Amr ElAdawy FYI angular-cli web paketine taşındı. Bu soru SystemJS ile ilgilidir. ng yapı benim için işe yaramadı.
Shahriar Hasan Sayeed

@ShahriarHasanSayeed Cevabı verdiğim zamanı mı yoksa denediğiniz zamanı mı kastediyorsunuz?
Amr ElAdawy

@AmrElAdawy, bunun gerçekten çalıştığı modüllerin sürümlerini ekleyebilir misiniz? Angular2, Temmuz ayından bu yana oldukça değişti.
ppovoski

2
Tour of Heroes eğitimini cli sürümüne dönüştürmek önemsizdir. Cli kullanarak yeni bir proje oluşturun ve ardından eğitim dosyalarını kopyalayın.
Rosdi Kasim

12

Gulp ve SystemJS-Builder ile SystemJS kullanarak Typescript'te bir Angular 2 (2.0.0-rc.1) projesi oluşturabilirsiniz. .

Aşağıda, 2.0.0-rc.1 ( tam kaynak , canlı örnek ) çalıştıran Tour of Heroes'un nasıl oluşturulacağına, paketleneceğine ve küçültüleceğine ilişkin basitleştirilmiş bir sürüm bulunmaktadır .

gulpfile.js

var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var concat = require('gulp-concat');
var typescript = require('gulp-typescript');
var systemjsBuilder = require('systemjs-builder');

// Compile TypeScript app to JS
gulp.task('compile:ts', function () {
  return gulp
    .src([
        "src/**/*.ts",
        "typings/*.d.ts"
    ])
    .pipe(sourcemaps.init())
    .pipe(typescript({
        "module": "system",
        "moduleResolution": "node",
        "outDir": "app",
        "target": "ES5"
    }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('app'));
});

// Generate systemjs-based bundle (app/app.js)
gulp.task('bundle:app', function() {
  var builder = new systemjsBuilder('public', './system.config.js');
  return builder.buildStatic('app', 'app/app.js');
});

// Copy and bundle dependencies into one file (vendor/vendors.js)
// system.config.js can also bundled for convenience
gulp.task('bundle:vendor', function () {
    return gulp.src([
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/bootstrap/dist/js/bootstrap.min.js',
        'node_modules/es6-shim/es6-shim.min.js',
        'node_modules/es6-promise/dist/es6-promise.min.js',
        'node_modules/zone.js/dist/zone.js',
        'node_modules/reflect-metadata/Reflect.js',
        'node_modules/systemjs/dist/system-polyfills.js',
        'node_modules/systemjs/dist/system.src.js',
      ])
        .pipe(concat('vendors.js'))
        .pipe(gulp.dest('vendor'));
});

// Copy dependencies loaded through SystemJS into dir from node_modules
gulp.task('copy:vendor', function () {
  gulp.src(['node_modules/rxjs/**/*'])
    .pipe(gulp.dest('public/lib/js/rxjs'));

  gulp.src(['node_modules/angular2-in-memory-web-api/**/*'])
    .pipe(gulp.dest('public/lib/js/angular2-in-memory-web-api'));
  
  return gulp.src(['node_modules/@angular/**/*'])
    .pipe(gulp.dest('public/lib/js/@angular'));
});

gulp.task('vendor', ['bundle:vendor', 'copy:vendor']);
gulp.task('app', ['compile:ts', 'bundle:app']);

// Bundle dependencies and app into one file (app.bundle.js)
gulp.task('bundle', ['vendor', 'app'], function () {
    return gulp.src([
        'app/app.js',
        'vendor/vendors.js'
        ])
    .pipe(concat('app.bundle.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./app'));
});

gulp.task('default', ['bundle']);

system.config.js

var map = {
  'app':                                'app',
  'rxjs':                               'vendor/rxjs',
  'zonejs':                             'vendor/zone.js',
  'reflect-metadata':                   'vendor/reflect-metadata',
  '@angular':                           'vendor/@angular'
};

var packages = {
  'app':                                { main: 'main', defaultExtension: 'js' },
  'rxjs':                               { defaultExtension: 'js' },
  'zonejs':                             { main: 'zone', defaultExtension: 'js' },
  'reflect-metadata':                   { main: 'Reflect', defaultExtension: 'js' }
};

var packageNames = [
  '@angular/common',
  '@angular/compiler',
  '@angular/core',
  '@angular/http',
  '@angular/platform-browser',
  '@angular/platform-browser-dynamic',
  '@angular/router',
  '@angular/router-deprecated',
  '@angular/testing',
  '@angular/upgrade',
];

packageNames.forEach(function(pkgName) {
  packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});

System.config({
  map: map,
  packages: packages
});


2
SystemJs ve Gulp nasıl çalıştırılacağını belirtebilir misiniz?
Jan Drozen

@JanDrozen Gulpfile dosyanızla aynı konumda gulp <taskname>, SystemJS oluşturucuyu çağıran görevin adı " taskname " olduğunda çalıştırabilirsiniz , yukarıdaki örneğimde öyle bundle:app. Bu Gulp görevinde, Sistem yapılandırmanızı ve çıkış dosyanızı belirtmek için 'systemjs-builder' npm modülünü kullanabilirsiniz.
Steely

@ steely: Teşekkürler! Tıkır tıkır çalışıyor. Varsayılan hedefi bekleyin - uglify () yöntemi eksik (veya bir şey eksik). Lütfen bana bu son belirsiz kısmı açıklar mısınız?
Jan Drozen

Angular2'nin yeni sürümüyle bunu nasıl yapacağınıza lütfen rehberlik eder misiniz?
micronyks

@ Steely. Angular2 quickstart-app'ı çalıştırmak için gerekli olan en son angular2 derleme dosyalarının son bağlantısını (github'da) sağlayabilir misiniz?
micronyks

1

İşte Angular 2 için MEA2N standart metnim: https://github.com/simonxca/mean2-boilerplate

Bir tscşeyleri bir araya getirmek için kullanılan basit bir ortak metindir . (Aslında özünde sadece komut olan grunt-ts kullanır tsc.) Wekpack, vb. Gerekmez.

Homurtu kullansanız da kullanmasanız da fikir şudur:

  • uygulamanızı adlı bir klasöre yazın ts/(örnek:public/ts/ )
  • kullanmak tsciçin dizin yapısını yansıtacak şekilde ts/bir içine klasördeki js/klasör ve sadece referans dosyalarının js/Gözlerinde farklı klasörde index.html.

Almak için homurtu-ts çalışmalarına (düz TSC Gulp vb için eşdeğer komut olmamalıdır), kendi içinde bir özelliği vardır tsconfig.jsondenir "outDir": "../js", ve ona gönderimde gruntfile.jsile:

grunt.initConfig({
  ts: {
    source: {tsconfig: 'app/ts/tsconfig.json'}
  },
  ...
});

Ardından çalıştırın grunt ts, bu uygulamanızı public/ts/içeri alır vepublic/js/ .

Orada. Anlaması çok kolay. En iyi yaklaşım değil, başlamak için iyi bir yaklaşım.


1

SystemJ'ler için açısal rc1'i paketlemenin en kolay yolu şunu kullanmaktır gulpve systemjs-builder:

gulp.task('bundle', function () {
    var path = require('path');
    var Builder = require('systemjs-builder');

    var builder = new Builder('/node_modules');

    return builder.bundle([
        '@angular/**/*.js'
        ], 
        'wwwroot/bundle.js', 
        { minify: false, sourceMaps: false })
        .then(function () {
            console.log('Build complete');
        })
        .catch(function (err) {
            console.log('Build error');
            console.log(err);
        });
});

Yorumlarda belirtildiği gibi, systemJs şu anda bileşenleri kullanarak moduleId: module.id

https://github.com/angular/angular/issues/6131

Şu anki öneri (açısal 2 rc1) açık yollar kullanıyor gibi görünüyor. moduleId: '/app/path/'


Bu umut verici görünüyor, ancak @Componentdekoratördeki harici şablonlara göreceli yolları kullandığımda başarısız oluyor . bundle.jsyolları göreceli olsalar bile mutlak olarak çözümlemeye çalışır ve 404 hatasına neden olur (bkz. stackoverflow.com/questions/37497635/… ). Bununla nasıl başa çıktın?
BeetleJuice

moduleIdgöreceli yolu ayarlıyor musunuz?
paul

Anladığımdan emin değilim. Ben moduleId: module.idde@Component
Beter Böcek

Bu, tüm yolu aşağı çekmekle aynı dezavantajlara sahiptir ve ilk etapta templateUrlsahip olma amacını ortadan kaldırır moduleId. Göreli yolları önerildiği gibi kullanmaya çalışıyorum ( angular.io/docs/ts/latest/cookbook/… )
BeetleJuice

yolu açıkça belirleyerek daha fazla şansa sahip olabilirsin örneğinmoduleId: '/app/components/home/'
paul


0

Angular.io web sitesi altında, Gelişmiş / Dağıtım bölümü altında, konuşlandırmanın en basit yolunun 'geliştirme ortamını sunucuya kopyalamak' olması önerilir.

  1. Aşağıdaki bölümü inceleyin: Mümkün olan en basit dağıtım. Nihai proje dosyaları kod bölümünde gösterilir. Web'den (yerel npm_modules klasörü yerine) npm paket dosyalarını yüklemek için kodu zaten ayarladığını unutmayın.

  2. yerel bilgisayarınızda çalıştığından emin olun (npm start). Ardından proje klasörünün altında, '/ src' alt klasörünün altındaki her şeyi kurduğunuz S3 klasörüne kopyalayın. Kopyalamak için sürükle ve bırak özelliğini kullanabilirsiniz, bu işlem sırasında dosyalar için izin ayarını seçme seçeneğine sahip olursunuz, onları 'herkes' tarafından 'okunabilir' hale getirdiğinizden emin olun.

  3. "Özellikler" sekmesi altında, "Statik web sitesi barındırma" panelini arayın, "Web sitesini barındırmak için bu grubu kullan" seçeneğini işaretleyin ve hem Dizin belgesi hem de Hata belgesi için "index.html" öğesini belirtin.

  4. Statik web sitesi Endpoint'e tıklayın, projeniz iyi çalışıyor!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.