2016-09-14 32 views
12

Tôi có ứng dụng Angular 2 RC7 nơi tôi sử dụng SystemJS để tải các tệp JavaScript.Góc 2: Cách báo cho SystemJS sử dụng gói?

Đây là cấu hình hiện tại của tôi cho 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); 

Bây giờ tôi đã tạo ra một bó gọi app.bundle.min.js có chứa tất cả các logic ứng dụng của tôi, và một dependencies.bundle.min.js có chứa phụ thuộc sử dụng.

Làm cách nào để yêu cầu SystemJS sử dụng các tệp này thay vì nhập tệp riêng lẻ?

Tôi đã thử thay thế này:

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

với:

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

trong index.html của tôi, nhưng điều đó không làm việc. Miễn là tôi giữ khối tập lệnh System.import... bên trong index.html, ứng dụng sẽ tải nhưng sử dụng các tệp riêng lẻ thay vì các gói.

Tôi cũng đã cố gắng thay đổi này:

map: { 

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

nhưng điều đó không làm việc, hoặc.

Đây là cách các bó được tạo bằng 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(){}); 

tôi nghi ngờ tôi phải bằng cách nào đó thay đổi ánh xạ bên trong cấu hình SystemJS của tôi chỉ về phía bó? Làm thế nào để tôi làm điều này?

+0

Khó có thể nói mà không biết chính xác có bao gói được tạo – artem

+0

Tôi đã thêm nhiệm vụ ngụm cho câu hỏi của tôi. –

Trả lời

22

Theo mappackages trong SystemJS cấu hình của bạn,

System.import('app') 

chuyển thành yêu cầu đối với các tập tin app/main.js. Tuy nhiên, nếu bạn nhìn vào gói ứng dụng được tạo ra, bạn sẽ thấy rằng mô-đun này là thực sự đăng ký như

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

vì bó được tạo ra từ .js tập tin trong thư mục dist.

Sự không khớp này là lý do khiến mô-đun của bạn không được tải từ gói tập lệnh.

Một giải pháp khả thi là để luôn luôn giữ .ts.js tập tin trong thư mục riêng biệt - .ts trong app, .js trong dist. Bằng cách đó, systemjs sẽ cần phải biết chỉ có khoảng dist: phần duy nhất của systemjs.config.js rằng cần phải thay đổi là app lập bản đồ:

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

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

Để kiểm tra xem nó hoạt động, tôi bắt đầu từ angular quickstart example và thêm gulpfile.js với các tác vụ này:

  1. biên dịch kiểu số thành dist bằng cách sử dụng gulp-typescript plugin.

    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. bản sao systemjs tập tin cấu hình vào dist thư mục, vì thế nó sẽ được đi kèm cùng với mã ứng dụng và sẽ có mặt trong sản xuất (nó là cần thiết bởi vì bạn đang sử dụng bundle và không buildStatic)

    gulp.task('bundle-config', function() { 
        return gulp.src('app/configs/systemjs.config.js') 
        .pipe(gulp.dest('dist/configs')); 
    }); 
    
  3. tạo bó với builder 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(){}); 
    

Lưu ý rằng nó sử dụng cú pháp [dist/**/*] để tạo gói ứng dụng mà không có bất kỳ phụ thuộc nào - gói trong gulpfile.js của bạn khác và tạo gói lớn hơn bao gồm một số phụ thuộc - Tôi không biết nó có chủ ý hay không.

Sau đó, tôi đã tạo index-production.html với những thay đổi từ index.html:

  1. loại bỏ <script> thẻ cho systemjs.config.js - chúng tôi nhập khẩu từ các bó

  2. thêm <script> thẻ cho bó trong <head>

    <script src="production/dependencies.bundle.min.js"></script> 
    <script src="production/app.bundle.min.js"></script> 
    
  3. thêm nội tuyến <script> rằng nhập khẩu cấu hình và ứng dụng mô-đun:

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

nhập khẩu 'ứng dụng' Module này là cần thiết vì bó được tạo ra với bundle không nhập khẩu bất cứ điều gì và không chạy bất kỳ mã - chúng chỉ làm cho tất cả các module có sẵn để nhập sau, không giống như các gói 'sfx' được tạo với buildStatic.

Ngoài ra, khối kịch bản này cần phải được trong các yếu tố sau <body><my-app>, nếu không app sẽ bắt đầu quá sớm khi các yếu tố <my-app> chưa được tạo (cách khác, import('app') có thể được gọi vào 'tài liệu sẵn sàng' sự kiện).

Bạn có thể tìm thấy ví dụ hoàn chỉnh trên github: https://github.com/fictitious/test-systemjs-angular-gulp

+0

Trả lời tuyệt vời. Cảm ơn nhiều! Giải pháp của bạn làm việc như một sự quyến rũ. –

+0

@artem là nó có thể với giải pháp này để gỡ lỗi các tập tin ts trong trình duyệt? – Yvan

+0

@Yvan có, bạn cần phải cài đặt và định cấu hình gulp-sourcemaps. Tôi đã cập nhật ví dụ về repo. – artem

Các vấn đề liên quan