อะไรคือความแตกต่างระหว่าง SystemJS และ Webpack?


222

ฉันกำลังสร้างแอปพลิเคชัน Angular แรกของฉันและฉันจะคิดออกว่าบทบาทของโมดูลตัก ทำไมเราต้องการพวกเขา ฉันพยายามค้นหาและค้นหาใน Google และฉันไม่เข้าใจว่าทำไมเราต้องติดตั้งหนึ่งในนั้นเพื่อเรียกใช้แอปพลิเคชันของเรา

มันไม่เพียงพอที่จะใช้importเพื่อโหลดเนื้อหาจากโหนดโมดูลใช่ไหม

ฉันได้ทำตามบทช่วยสอนนี้ (ที่ใช้ SystemJS) และทำให้ฉันใช้systemjs.config.jsไฟล์:

/**
 * 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);

ทำไมเราต้องการไฟล์การกำหนดค่านี้
ทำไมเราต้องใช้ SystemJS (หรือ WebPack หรืออื่น ๆ )
ในที่สุดคุณคิดว่าอะไรดีกว่ากัน?


4
ที่นี่คุณสามารถอ่านบทความที่ดีจริงๆเพื่อเปรียบเทียบ SystemJs (Jspm) กับ Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack
Sweta

ดูคำตอบนี้stackoverflow.com/a/40670147/2545680สำหรับ SystemJS
Max Koretskyi

คำตอบ:


135

หากคุณไปที่หน้า SystemJS Github คุณจะเห็นคำอธิบายของเครื่องมือ:

Universal ไดนามิกโมดูลโหลดเดอร์ - โหลดโมดูล ES6, AMD, CommonJS และสคริปต์ส่วนกลางในเบราว์เซอร์และ NodeJS

เนื่องจากคุณใช้โมดูลใน TypeScript หรือ ES6 คุณจำเป็นต้องมีโมดูลโหลดเดอร์ ในกรณีของ SystemJS systemjs.config.jsจะอนุญาตให้เรากำหนดค่าวิธีการจับคู่ชื่อโมดูลกับไฟล์ที่เกี่ยวข้อง

ไฟล์การกำหนดค่านี้ (และ SystemJS) จำเป็นถ้าคุณใช้อย่างชัดเจนเพื่อนำเข้าโมดูลหลักของแอปพลิเคชันของคุณ:

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

เมื่อใช้ TypeScript และกำหนดค่าคอมไพเลอร์ให้กับcommonjsโมดูลคอมไพเลอร์จะสร้างรหัสที่ไม่ได้ยึดตาม SystemJS อีกต่อไป ในตัวอย่างนี้ไฟล์ config types compiler จะปรากฏดังนี้:

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

Webpack เป็นตัวรวมโมดูลที่ยืดหยุ่น ซึ่งหมายความว่ามันจะดำเนินต่อไปและไม่เพียง แต่จัดการกับโมดูล แต่ยังให้วิธีในการทำแพ็คเกจแอปพลิเคชันของคุณ (ไฟล์ concat, uglify files, ... ) นอกจากนี้ยังมีเซิร์ฟเวอร์ dev ที่มีการโหลดซ้ำเพื่อการพัฒนา

SystemJS และ Webpack นั้นแตกต่างกัน แต่ด้วย SystemJS คุณยังคงมีงานต้องทำ (ด้วยตัวสร้างGulpหรือSystemJSเป็นต้น) เพื่อทำแพ็กเกจแอปพลิเคชัน Angular2 ของคุณเพื่อการผลิต


2
เมื่อคุณพูดว่า "กับ SystemJS คุณยังคงมีงานต้องทำ (ด้วยตัวสร้าง Gulp หรือ SystemJS เป็นต้น) เพื่อจัดทำแพ็กเกจแอปพลิเคชัน Angular2 ของคุณสำหรับการผลิต" เป็นสิ่งที่ฉันได้รับด้วยในขณะนี้npm start?
smartmouse

5
อันที่จริงแล้วสำหรับการผลิตมันไม่ได้มีประสิทธิภาพในการโหลดไฟล์จำนวนมากสำหรับโมดูล (แต่ละไฟล์ (~ 300 คำขอ) หรือ Bundled (~ 40 คำขอ)) คุณต้องรวบรวมทุกอย่างเป็นหนึ่งหรือสอง (รหัสของคุณและรหัสห้องสมุดบุคคลที่สาม) รวบรวมแม่แบบของคุณแบบออฟไลน์ (ngc) และใช้ประโยชน์จากการเขย่าต้นไม้เพื่อลดน้ำหนักของการรวมกลุ่ม บทความนี้อาจคุณสนใจ: blog.mgechev.com/2016/06/26/... นอกจากนี้คุณยังจำเป็นต้องอัปเกรดไฟล์ CSS
Thierry Templier

1
ด้วยการเริ่มต้น npm คุณ "เพียงแค่" เริ่มต้นเซิร์ฟเวอร์ที่จะให้บริการแอปพลิเคชันของคุณตามการกำหนดค่า SystemJS ของคุณสำหรับโมดูล ...
Thierry Templier

11
Google ได้ย้ายไปยัง webpack อย่างเป็นทางการ ดังนั้นฉันคิดว่ามันจะดีกว่าถ้าคุณยึดติดกับสิ่งที่ชุมชนส่วนใหญ่ใช้ ฉันกำลังย้ายโครงการ systemJS ของฉันไปที่ webpack เร็ว ๆ นี้ ไม่แน่ใจทั้งหมดว่าจะทำอย่างไร
user2180794

1
@JonasKello เป็นกรณีของ cli เชิงมุม ดูลิงค์นี้: github.com/angular/angular-cliในส่วน "การอัปเดต Webpack" หรือไม่
Thierry Templier

190

SystemJS ทำงานฝั่งไคลเอ็นต์ มันโหลดโมดูล (ไฟล์) ตามความต้องการแบบไดนามิกเมื่อมีความจำเป็น คุณไม่จำเป็นต้องโหลดแอพทั้งหมดล่วงหน้า คุณสามารถโหลดไฟล์ตัวอย่างเช่นภายในตัวจัดการคลิกของปุ่ม

รหัส 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()
});

นอกเหนือจากการกำหนดค่าให้ทำงานนั่นคือทั้งหมดที่มีให้กับ SystemJS! ตอนนี้คุณเป็นมืออาชีพ SystemJS!

Webpack แตกต่างอย่างสิ้นเชิงและใช้เวลาตลอดไปในการเป็นผู้เชี่ยวชาญ มันไม่ได้ทำสิ่งเดียวกันกับ SystemJS แต่เมื่อใช้ Webpack, SystemJS จะซ้ำซ้อน

Webpack เตรียมไฟล์เดี่ยวชื่อ bundle.js - ไฟล์นี้มี HTML, CSS, JS, ฯลฯ ทั้งหมดเนื่องจากไฟล์ทั้งหมดจะถูกรวมในไฟล์เดียวตอนนี้ไม่จำเป็นต้องโหลดขี้เกียจเช่น SystemJS (ที่แต่ละไฟล์ถูกโหลดเป็น จำเป็น)

ข้อดีของ SystemJS คือการโหลดที่ขี้เกียจ แอปควรโหลดเร็วขึ้นเพราะคุณไม่ได้โหลดทุกอย่างในการเข้าชมครั้งเดียว

ข้อดีของ Webpack คือแม้ว่าแอพอาจใช้เวลาสองสามวินาทีในการโหลดครั้งแรก แต่เมื่อโหลดแล้วแคชจะเร็วมาก

ฉันชอบ SystemJS แต่ Webpack น่าจะนิยมกว่า

Angular2 quickstart ใช้ SystemJS

CLI เชิงมุมใช้ Webpack

Webpack 2 (ซึ่งจะเสนอการเขย่าต้นไม้) อยู่ในรุ่นเบต้าดังนั้นอาจถึงเวลาที่ไม่ดีที่จะย้ายไปที่ Webpack

หมายเหตุ SystemJS มีการดำเนินการตามมาตรฐานการโหลดโมดูล ES6 Webpack เป็นเพียงโมดูล npm อื่น

Task runners (การอ่านเพิ่มเติมสำหรับผู้ที่ต้องการทำความเข้าใจกับระบบนิเวศที่ SystemJS อาจมีอยู่)

ด้วย SystemJS รับผิดชอบ แต่เพียงผู้เดียวของมันคือการโหลดขี้เกียจของไฟล์เพื่อให้สิ่งที่ยังคงมีความจำเป็นที่จะลดขนาดไฟล์เหล่านั้น transpile ไฟล์เหล่านั้น (เช่นจาก SASS เพื่อ CSS) ฯลฯ งานเหล่านี้ที่จะต้องทำจะเรียกว่างาน

Webpack เมื่อกำหนดค่าแล้วจะทำสิ่งนี้ให้คุณอย่างถูกต้อง (และรวมเอาเอาต์พุตเข้าด้วยกัน) หากคุณต้องการทำสิ่งที่คล้ายกับ SystemJS คุณมักจะใช้งานจาวาสคริปต์ ส่วนใหญ่วิ่งงานที่เป็นที่นิยมอีกโมดูล NPM เรียกว่าอึก

ตัวอย่างเช่น SystemJS อาจขี้เกียจโหลดไฟล์ JavaScript ขนาดเล็กที่ถูกย่อด้วย gulp อึกเมื่อติดตั้งอย่างถูกต้องสามารถย่อไฟล์ได้ทันทีและโหลดซ้ำได้ การโหลดสดคือการตรวจจับการเปลี่ยนแปลงรหัสโดยอัตโนมัติและการรีเฟรชเบราว์เซอร์อัตโนมัติเพื่ออัปเดต ยอดเยี่ยมในระหว่างการพัฒนา ด้วย CSS ทำให้การสตรีมแบบสดเป็นไปได้ (เช่นคุณเห็นหน้าอัปเดตสไตล์ใหม่โดยไม่ต้องโหลดซ้ำหน้า)

มีงานอื่น ๆ อีกมากมายที่ Webpack และอึกสามารถทำซึ่งจะมีมากเกินไปที่จะครอบคลุมที่นี่ ฉันได้ให้ตัวอย่าง :)


7
ฉันด้วยฉันพบว่า SystemJS และ JSPM นั้นง่ายกว่าการทำงานกับ webpack นอกจากนี้ฉันพบว่าชุดการผลิตมีขนาดเล็กลง (เมื่อเทียบกับโครงการตัวอย่างของ webpack อื่น) นี่คือโพสต์ของฉันเกี่ยวกับหัวข้อ: stackoverflow.com/questions/40256204/…
Peter Salomonsen

7
คุณสามารถใช้ Webpack angular2-router-loaderและขี้เกียจโหลดกับการใช้ ดูmedium.com/@daviddentoom/
อเล็กซ์

36
คุณผิดเกี่ยวกับ Webpack! จะช่วยให้คุณสามารถรวมการรวมกับการโหลดขี้เกียจ ยิ่งกว่านั้นมันรวมโมดูลที่เลื่อนออกไปเป็นชิ้น ๆ อย่างโปร่งใส
dizel3d

3
@AlexKlaus ขอบคุณสำหรับตัวอย่าง! ผมกำลังมองหาสิ่งที่ต้องการที่ :)
tftd

3
"Webpack นั้นแตกต่างอย่างสิ้นเชิงและใช้เวลาตลอดไปในการเป็นผู้เชี่ยวชาญมันไม่ได้ทำสิ่งเดียวกันกับ SystemJS แต่เมื่อใช้ Webpack นั้น SystemJS จะซ้ำซ้อน" ฉันไม่เห็นด้วย SystemJS ยังช่วยให้การพัฒนา dev โดยไม่ต้องสร้างสำหรับการเปลี่ยนแปลงทุกครั้ง ฉันสามารถเปลี่ยนแปลงไฟล์ TS, บันทึก (ซึ่งจะเรียก tsc.exe โดยอัตโนมัติและสร้าง) จากนั้นโหลดหน้าเว็บของฉันซ้ำและไม่มีปัญหาใด ๆ ด้วย Webpack ผมต้องสร้างซึ่งอาจใช้เวลาอย่างมีนัยสำคัญอีกต่อไปเพราะมันจะคอมไพล์และสร้างทุกอย่าง ฉันไม่พบวิธีที่จะหลีกเลี่ยงการใช้ Webpack
Polantaris

0

จนถึงตอนนี้ฉันใช้ systemjs มันเป็นการโหลดไฟล์แบบหนึ่งต่อหนึ่งและการโหลดครั้งแรกใช้เวลา 3-4 วินาทีโดยไม่มีไฟล์ขนาดเล็ก หลังจากเปลี่ยนมาใช้ webpack ฉันได้รับการปรับปรุงประสิทธิภาพที่ยอดเยี่ยม ตอนนี้ใช้เวลาในการโหลดไฟล์บันเดิลหนึ่งไฟล์เท่านั้น (เช่น polyfills และและ libs ผู้ขายซึ่งแทบไม่เคยเปลี่ยนและแคชเกือบทุกครั้ง) และนั่นคือไฟล์ ตอนนี้ใช้เวลาเพียงไม่กี่วินาทีในการโหลดแอปฝั่งไคลเอ็นต์ ไม่มีตรรกะฝั่งไคลเอ็นต์เพิ่มเติม จำนวนไฟล์แต่ละไฟล์ที่น้อยลงจะทำให้ประสิทธิภาพการทำงานดีขึ้น เมื่อใช้ systemjs คุณควรคิดถึงการนำเข้าโมดูลแบบไดนามิกเพื่อบันทึกประสิทธิภาพ ด้วย webpack คุณให้ความสำคัญกับตรรกะของคุณเป็นหลักเนื่องจากประสิทธิภาพจะยังคงดีเมื่อบันเดิลมีขนาดเล็กและแคชในเบราว์เซอร์ของคุณ


3
คุณตอบคำถามของ OP อย่างใดอย่างหนึ่งเท่านั้นจึงเป็นการดีกว่าที่จะแสดงความคิดเห็น
Ben
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.