Sự khác biệt giữa SystemJS và Webpack là gì?


222

Tôi đang tạo ứng dụng Angular đầu tiên của mình và tôi sẽ tìm hiểu vai trò của các trình tải mô-đun là gì. Tại sao chúng ta cần chúng? Tôi đã cố gắng tìm kiếm và tìm kiếm trên Google và tôi không thể hiểu tại sao chúng ta cần cài đặt một trong số họ để chạy ứng dụng của mình?

Nó không đủ để chỉ sử dụng importđể tải công cụ từ các mô-đun nút?

Tôi đã làm theo hướng dẫn này (sử dụng SystemJS) và nó khiến tôi sử dụng systemjs.config.jstệp:

/**
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function(global) {
  // map tells the System loader where to look for things
  var map = {
    'app':                        'transpiled', // 'dist',
    '@angular':                   'node_modules/@angular',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    'rxjs':                       'node_modules/rxjs'
  };
  // 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' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  };
  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'forms',
    'http',
    'platform-browser',
    'platform-browser-dynamic',
    'router',
    'router-deprecated',
    'upgrade',
  ];
  // Individual files (~300 requests):
  function packIndex(pkgName) {
    packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
  }
  // Bundled (~40 requests):
  function packUmd(pkgName) {
    packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
  }
  // Most environments should use UMD; some (Karma) need the individual index files
  var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
  // Add package entries for angular packages
  ngPackageNames.forEach(setPackageConfig);
  var config = {
    map: map,
    packages: packages
  };
  System.config(config);
})(this);

Tại sao chúng ta cần tập tin cấu hình này?
Tại sao chúng ta cần SystemJS (hoặc WebPack hoặc những người khác)?
Cuối cùng, theo bạn thì cái gì tốt hơn?


4
Ở đây bạn có thể đọc bài viết thực sự tốt để so sánh SystemJs (Jspm) với Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack .
Sweta

xem câu trả lời này stackoverflow.com/a/40670147/2545680 cho SystemJS
Max Koretskyi

Câu trả lời:


135

Nếu bạn truy cập trang SystemJS Github, bạn sẽ thấy mô tả của công cụ:

Trình tải mô-đun động phổ quát - tải các mô-đun ES6, AMD, CommonJS và các tập lệnh toàn cầu trong trình duyệt và NodeJS.

Vì bạn sử dụng các mô-đun trong TypeScript hoặc ES6, bạn cần một trình tải mô-đun. Trong trường hợp SystemJS, systemjs.config.jscho phép chúng tôi định cấu hình cách khớp tên mô-đun với các tệp tương ứng của chúng.

Tệp cấu hình này (và SystemJS) là cần thiết nếu bạn sử dụng nó một cách rõ ràng để nhập mô-đun chính của ứng dụng của bạn:

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

Khi sử dụng TypeScript và định cấu hình trình biên dịch cho commonjsmô-đun, trình biên dịch sẽ tạo mã không còn dựa trên SystemJS. Trong ví dụ này, tệp cấu hình trình biên dịch kiểu sẽ xuất hiện như sau:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs", // <------
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}

Webpack là một gói mô-đun linh hoạt. Điều này có nghĩa là nó đi xa hơn và không chỉ xử lý các mô-đun mà còn cung cấp cách đóng gói ứng dụng của bạn (tệp concat, tệp uglify, ...). Nó cũng cung cấp một máy chủ dev với tải lại để phát triển.

SystemJS và Webpack khác nhau nhưng với SystemJS, bạn vẫn phải làm việc ( ví dụ với trình xây dựng Gulp hoặc SystemJS ) để đóng gói ứng dụng Angular2 của bạn để sản xuất.


2
Khi bạn nói "với SystemJS, bạn vẫn còn việc phải làm (với trình tạo Gulp hoặc SystemJS chẳng hạn) để đóng gói ứng dụng Angular2 của bạn để sản xuất" là những gì tôi hiện đang làm với npm start?
smartmouse

5
Trong thực tế, để sản xuất, không hiệu quả khi tải nhiều tệp cho các mô-đun (Các tệp riêng lẻ (~ 300 yêu cầu) hoặc Gói (~ 40 yêu cầu)). Bạn cần tập hợp mọi thứ thành một hoặc hai (mã của bạn và mã thư viện của bên thứ ba), biên dịch ngoại tuyến các mẫu của bạn (ngc) và tận dụng cây lắc để giảm thiểu trọng lượng của các gói. Bài viết này có thể khiến bạn quan tâm: blog.mgechev.com/2016/06/26/ . Bạn cũng cần làm xấu các tệp CSS.
Thierry Templier

1
Với khởi động npm, bạn "đơn giản" khởi động một máy chủ sẽ phục vụ ứng dụng của bạn dựa trên cấu hình SystemJS của bạn cho các mô-đun ...
Thierry Templier

11
Google đã chính thức chuyển sang webpack. Vì vậy, tôi đoán sẽ tốt hơn nếu gắn bó với phần lớn cộng đồng sẽ sử dụng. Tôi sẽ sớm chuyển dự án systemJS của mình sang webpack. Không hoàn toàn chắc chắn làm thế nào để làm điều đó mặc dù.
dùng2180794

1
@JonasKello đó là trường hợp cho cli góc. Xem liên kết này: github.com/angular/angular-cli trong phần "Cập nhật gói web"?
Thierry Templier

190

SystemJS hoạt động phía khách hàng. Nó tải các mô-đun (tệp) động theo yêu cầu khi cần thiết. Bạn không phải tải toàn bộ ứng dụng lên phía trước. Bạn có thể tải một tệp, ví dụ, bên trong trình xử lý nhấp vào nút.

Mã SystemJS:

// example import at top of file
import myModule from 'my-module'
myModule.doSomething()

// example dynamic import (could be placed anywhere in your code)
// module not loaded until code is hit
System.import('my-module').then((myModule) {
  // myModule is available here
  myModule.doSomething()
});

Ngoài việc cấu hình nó để hoạt động, đó là tất cả những gì có ở SystemJS! Bây giờ bạn là một chuyên gia SystemJS!

Webpack là hoàn toàn khác nhau và mất mãi mãi để làm chủ. Nó không làm điều tương tự như SystemJS, nhưng khi sử dụng Webpack, SystemJS trở nên dư thừa.

Webpack chuẩn bị một tệp duy nhất gọi là bundle.js - Tệp này chứa tất cả HTML, CSS, JS, v.v. Vì tất cả các tệp được gói trong một tệp duy nhất, giờ đây không cần trình tải lười biếng như SystemJS (nơi các tệp riêng lẻ được tải dưới dạng cần thiết).

Ưu điểm của SystemJS là tải lười biếng này. Ứng dụng sẽ tải nhanh hơn vì bạn không tải mọi thứ trong một lần nhấn.

Ưu điểm của Webpack là, mặc dù ứng dụng có thể mất vài giây để tải ban đầu, nhưng sau khi được tải và lưu vào bộ đệm, nó rất nhanh.

Tôi thích SystemJS nhưng Webpack dường như là xu hướng hơn.

Khởi động nhanh Angular2 sử dụng SystemJS.

CLI góc sử dụng Webpack.

Webpack 2 (sẽ cung cấp rung cây) đang trong giai đoạn thử nghiệm nên có lẽ đây là thời điểm tồi tệ để chuyển sang Webpack.

Lưu ý SystemJS đang triển khai tiêu chuẩn tải mô-đun ES6 . Webpack chỉ là một mô-đun npm.

Người chạy tác vụ (đọc tùy chọn cho những người muốn hiểu hệ sinh thái nơi SystemJS có thể tồn tại)

Với SystemJS, trách nhiệm duy nhất của nó là lười tải các tệp, do đó vẫn cần một cái gì đó để thu nhỏ các tệp đó, sao chép các tệp đó (ví dụ từ SASS sang CSS), v.v. Những công việc này phải được thực hiện được gọi là các tác vụ .

Webpack, khi được cấu hình, sẽ thực hiện chính xác điều này cho bạn (và kết hợp đầu ra với nhau). Nếu bạn muốn làm một cái gì đó tương tự với SystemJS, bạn thường sử dụng một trình chạy tác vụ JavaScript. Trình chạy tác vụ phổ biến nhất là một mô-đun npm khác gọi là gulp .

Vì vậy, ví dụ, SystemJS có thể lười tải một tệp JavaScript được rút gọn đã được gulp thu nhỏ. Gulp, khi thiết lập chính xác, có thể thu nhỏ các tệp khi đang di chuyển và tải lại trực tiếp. Tải lại trực tiếp là phát hiện tự động thay đổi mã và làm mới trình duyệt tự động để cập nhật. Tuyệt vời trong quá trình phát triển. Với CSS, phát trực tiếp là có thể (tức là bạn thấy trang cập nhật các kiểu mới mà không cần tải lại trang).

Có nhiều nhiệm vụ khác mà Webpack và gulp có thể thực hiện sẽ quá nhiều để thực hiện ở đây. Tôi đã cung cấp một ví dụ :)


7
Tôi cũng vậy, tôi thấy SystemJS và JSPM dễ làm việc hơn webpack. Ngoài ra tôi thấy các gói sản xuất nhỏ hơn (so với một dự án ví dụ webpack khác). Đây là bài viết của tôi về chủ đề: stackoverflow.com/questions
40256204

7
Bạn có thể sử dụng Webpack & Lazy load bằng cách sử dụng angular2-router-loader. Xem thêm Medium.com/@daviddentoom/ trộm
Alex Klaus

36
Bạn đã sai về Webpack! Nó cho phép bạn kết hợp bó với tải lười biếng. Hơn nữa, nó trong suốt bó các mô-đun hoãn lại thành khối.
dizel3d

3
@AlexKlaus cảm ơn vì ví dụ! Tôi đang tìm kiếm một cái gì đó như thế :)
tftd

3
"Webpack hoàn toàn khác biệt và cần mãi mãi để làm chủ. Nó không làm điều tương tự như SystemJS, nhưng khi sử dụng Webpack, SystemJS trở nên dư thừa." Tôi phải không đồng ý. SystemJS vẫn cho phép phát triển dev mà không cần phải xây dựng cho mỗi thay đổi. Tôi có thể thay đổi tệp TS, lưu (sẽ tự động gọi tsc.exe và xây dựng tệp đó), sau đó tải lại trang của tôi và không gặp vấn đề gì. Với Webpack, tôi phải xây dựng lại có thể mất nhiều thời gian hơn vì nó sẽ biên dịch lại và xây dựng mọi thứ . Tôi không thể tìm ra cách nào để tránh điều đó khi sử dụng Webpack.
Polantaris

0

Cho đến nay tôi đã sử dụng systemjs. Nó đang tải từng tệp một và tải đầu tiên mất 3-4 giây mà không thu nhỏ tệp. Sau khi chuyển sang webpack tôi đã có một cải tiến hiệu suất tuyệt vời. Bây giờ chỉ cần tải một tệp bó (cũng là polyfill và lib của nhà cung cấp mà hầu như không bao giờ thay đổi và hầu như luôn được lưu trong bộ nhớ cache) và đó là nó. Bây giờ chỉ mất một giây để tải ứng dụng phía máy khách. Không có logic phía khách hàng bổ sung. Càng ít số lượng các tệp riêng lẻ được tải càng cao hiệu suất. Khi sử dụng systemjs, bạn nên suy nghĩ về việc nhập mô-đun một cách linh hoạt để tiết kiệm hiệu suất. Với webpack, bạn tập trung chủ yếu vào logic của mình vì hiệu suất sẽ vẫn tốt khi gói được thu nhỏ và lưu vào bộ nhớ cache trong trình duyệt của bạn.


3
Bạn chỉ trả lời một trong những câu hỏi của OP, tốt hơn là nên bình luận.
Ben
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.