Angular 2 + Typescript + systemjs 앱을 실제로 어떻게 배포합니까?


103

typescript 및 systemjs를 사용하는 angular.io에 빠른 시작 자습서가 있습니다. 이제 미니 앱을 실행 했으니 배포 가능한 것을 만들려면 어떻게해야할까요? 나는 그것에 대한 정보를 전혀 찾을 수 없었습니다.

System.config에 추가 도구, 추가 설정이 필요합니까?

(나는 webpack을 사용하고 하나의 bundle.js를 만들 수 있다는 것을 알고 있지만 튜토리얼에서 사용되는 systemjs를 사용하고 싶습니다)

누군가가이 설정 (Angular 2, TypeScript, systemjs)과 빌드 프로세스를 공유 할 수 있습니까?


다음은 JSPM을 사용하여 배포 용 ng2 앱을 빌드하는 방법입니다. stackoverflow.com/a/34616199/3532945
brando

2
간단한 답변 ng build -prod stackoverflow.com/a/38421680/5079380
Amr ElAdawy

답변:


66

이 수준에서 이해해야 할 핵심 사항은 다음 구성을 사용하면 컴파일 된 JS 파일을 직접 연결할 수 없다는 것입니다.

TypeScript 컴파일러 구성에서 :

{
  "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에서

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

실제로 이러한 JS 파일에는 익명 모듈이 포함됩니다. 익명 모듈은 System.register모듈 이름을 첫 번째 매개 변수로 사용 하지만 사용 하지 않는 JS 파일입니다 . 이것은 typescript 컴파일러가 systemjs가 모듈 관리자로 구성 될 때 기본적으로 생성하는 것입니다.

따라서 모든 모듈을 단일 JS 파일로 만들 outFile려면 TypeScript 컴파일러 구성 내 에서 속성 을 활용해야 합니다.

이를 위해 gulp 내부에서 다음을 사용할 수 있습니다.

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

이것은 다른 처리와 결합 될 수 있습니다.

  • 컴파일 된 TypeScript 파일을 uglify하려면
  • app.js파일 을 만들려면
  • vendor.js타사 라이브러리 용 파일 을 만들려면
  • boot.js응용 프로그램을 부트 스트랩하는 모듈을 가져올 파일 을 만듭니다 . 이 파일은 페이지 끝에 포함되어야합니다 (모든 페이지가로드 될 때).
  • index.html이 두 파일을 고려 하여 업데이트하려면

gulp 작업에는 다음 종속성이 사용됩니다.

  • 꿀꺽 꿀꺽
  • gulp-html-replace
  • 꿀꺽 꿀꺽 타이프 스크립트
  • 꿀꺽 꿀꺽 마시다

다음은 적용 할 수있는 샘플입니다.

  • app.min.js파일 생성

    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.js파일 생성

    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.js파일 생성

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

    config.prod.js단순히 다음을 포함합니다

     System.import('boot')
        .then(null, console.error.bind(console));
  • index.html파일 업데이트

    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.html다음과 같다 :

    <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');모든 앱 구성 요소가에서 등록 할 때까지 기다릴 몸의 끝에서해야 app.min.js파일.

여기서는 CSS 및 HTML 축소를 처리하는 방법을 설명하지 않습니다.


1
예제로 github 저장소를 만들 수 있습니까?
jdelobel

나는 당신의 지시를 따랐고 꿀꺽 꿀꺽 마시기에 관해서는 모두 괜찮아 보입니다. 그러나 브라우저에서 앱을 실행하면 "system.src.js : 1625 Uncaught TypeError : 동일한 모듈 파일에서 여러 익명 System.register 호출"이라는 콘솔 로그 오류가 발생합니다. 이것이 의미하는 바와 수정 방법에 대한 아이디어가 있습니까?
AngularM

@AngularM : outFile 매개 변수가 있습니까? 이것은 당신의 오류의 열쇠입니다 ;-)
Thierry Templier

gulp

제가 제출 한 github 프로젝트를 볼 수 있습니까? 위의 내 의견을 참조하십시오. 코드에 약간의 차이가 있습니까?
Thierry Templier 2016 년

28

angular2-cli 빌드 명령을 사용할 수 있습니다.

ng build -prod

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

로 만든 빌드 -prod를 통해 플래그 ng build -prod또는 ng serve -prod에 모든 종속성을 번들 하나의 파일 , 그리고 사용하게 나무 흔드는 기술을.

최신 정보

이 답변은 angular2가 rc4에있을 때 제출되었습니다.

angular-cli beta21 및 angular2 ^ 2.1.0에서 다시 시도했으며 예상대로 작동합니다.

이 답변은 사용할 수있는 angular-cli로 앱을 초기화해야합니다.

ng new myApp

또는 기존에

ng init

업데이트 2018/08/06

각도 6의 경우 구문이 다릅니다.

ng build --prod --build-optimizer

문서 확인


8
이를 위해서는 앱이 angular-cli의 독자적인 구조로 구성되어야합니다.
Michael Pell

2
@Amr ElAdawy FYI angular-cli가 webpack으로 이동했습니다. 이 질문은 SystemJS와 관련이 있습니다. ng 빌드는 나를 위해 작동하지 않습니다.
Shahriar Hasan Sayeed 2011

@ShahriarHasanSayeed 내가 답변을 제출 한 시간 또는 시도한 시간을 언급하고 있습니까?
Amr ElAdawy

@AmrElAdawy, 이것이 실제로 작동하는 모듈의 버전을 추가 할 수 있습니까? Angular2는 7 월 이후로 상당히 변경되었습니다.
ppovoski

2
Tour of Heroes 튜토리얼을 cli 버전으로 변환하는 것은 간단합니다. cli를 사용하여 새 프로젝트를 생성 한 다음 튜토리얼 파일을 복사하십시오.
Rosdi Kasim

12

GulpSystemJS-Builder 와 함께 SystemJS를 사용하여 Typescript에서 Angular 2 (2.0.0-rc.1) 프로젝트를 빌드 할 수 있습니다 .

아래는 2.0.0-rc.1을 실행하는 Tour of Heroes를 빌드, 번들링 및 축소하는 방법의 단순화 된 버전입니다 ( 전체 소스 , 라이브 예제 ).

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 및 Gulp를 실행하는 방법을 지정해 주시겠습니까?
Jan

@JanDrozen gulpfile과 같은 위치에서 실행할 수 있습니다. gulp <taskname>여기서 "taskname"은 SystemJS 빌더를 호출하는 작업의 이름입니다 bundle:app. 위의 예에서는 . Gulp 작업에서 'systemjs-builder'npm 모듈을 사용하여 시스템 구성 및 출력 파일을 지정할 수 있습니다.
Steely

@ 스틸리 : 감사합니다! 매력처럼 작동합니다. 기본 대상을 기대하십시오-uglify () 메서드가 누락되었습니다 (또는 뭔가 누락되었습니다). 이 마지막 불분명 한 부분을 설명해 주시겠습니까?
Jan Drozen

@Steely 최신 버전의 angular2로 수행하는 방법을 안내해 주시겠습니까?
micronyks

@Steely. angular2 빠른 시작 앱을 실행하는 데 필요한 최신 angular2 빌드 파일의 최종 링크 (github에서)를 제공 할 수 있습니까?
micronyks

1

Angular 2 용 MEA2N 상용구는 다음과 같습니다. https://github.com/simonxca/mean2-boilerplate

tsc사물을 하나로 묶는 데 사용하는 간단한 상용구입니다 . (실제로 핵심은 명령 인 grunt-ts를 사용합니다 tsc.) Wekpack 등이 필요하지 않습니다.

grunt 사용 여부에 관계없이 아이디어는 다음과 같습니다.

  • 라는 폴더에 응용 프로그램을 쓰기 ts/(예 : public/ts/)
  • 사용 tsc당신의 디렉토리 구조 미러링 ts/에 폴더를 js/의 폴더와 단지 참조 파일을 js/사용자의 폴더 index.html.

grunt-ts 가 작동하도록 하려면 (일반 tsc, Gulp 등에 대해 동등한 명령이 있어야 함) tsconfig.jsoncalled에 속성이 있고 다음을 사용하여 "outDir": "../js"참조합니다 gruntfile.js.

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

그런 다음을 실행 grunt ts하면 앱 public/ts/public/js/.

그곳에. 매우 이해하기 쉽습니다. 최선의 방법은 아니지만 시작하기에 좋은 방법입니다.


1

내가 systemJs을 위해 각 RC1을 번들로 발견하는 가장 쉬운 방법은 사용하는 것입니다 gulpsystemjs-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);
        });
});

의견에서 지적했듯이 systemJs는 현재 다음을 사용하여 구성 요소를 번들링 할 때 문제가 있습니다. moduleId: module.id

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

현재 권장 사항 (angular 2 rc1)은 명시 적 경로를 사용하는 것 같습니다. moduleId: '/app/path/'


이것은 유망 해 보이지만 @Component데코레이터 에서 외부 템플릿에 대한 상대 경로를 사용하면 실패합니다 . bundle.js상대 경로 임에도 절대 경로를 확인하려고 시도하여 404 오류를 발생시킵니다 ( stackoverflow.com/questions/37497635/… 참조 ). 어떻게 처리 했습니까?
BeetleJuice

moduleId상대 경로 를 설정 하고 있습니까?
Paul

이해하지 못합니다. 나는이 moduleId: module.id@Component
비틀

그것은 전체 경로를 아래에 두는 것과 동일한 단점 templateUrl을 가지고 moduleId있으며 처음 에 갖는 목적을 무너 뜨립니다 . 권장되는 상대 경로를 사용하려고합니다 ( angular.io/docs/ts/latest/cookbook/… )

경로를 직접 설정하면 더 많은 행운을 얻을 수 있습니다. 예moduleId: '/app/components/home/'
paul


0

Angular.io 웹 사이트의 Advanced / Deployment 섹션에서 배포하는 가장 간단한 방법은 '개발 환경을 서버에 복사'하는 것입니다.

  1. 아래 섹션으로 이동 : 가능한 가장 간단한 배포. 최종 프로젝트 파일은 코드 섹션 내에 표시됩니다. 이미 로컬 npm_modules 폴더 대신 웹에서 npm 패키지 파일을로드하도록 코드를 설정했습니다.

  2. 로컬 컴퓨터에서 실행 중인지 확인하십시오 (npm start). 그런 다음 프로젝트 폴더에서 '/ src'하위 폴더 아래의 모든 항목을 설정 한 S3 버킷에 복사합니다. 끌어서 놓기를 사용하여 복사 할 수 있습니다. 해당 프로세스 중에 파일에 대한 권한 설정을 선택하는 옵션이 표시되고 파일을 '모든 사람'이 '읽을 수 있도록'확인해야합니다.

  3. 버킷 '속성'탭에서 '정적 웹 사이트 호스팅'패널을 찾아 '웹 사이트 호스팅에이 버킷 사용'옵션을 선택하고 색인 문서와 오류 문서 모두에 'index.html'을 지정합니다.

  4. 정적 웹 사이트 Endpoint를 클릭하면 프로젝트가 잘 실행됩니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.