Каковы различия между 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 или другие)?
Наконец, по вашему мнению, что лучше?

Smartmouse
источник
4
Здесь вы можете прочитать действительно хорошую статью для сравнения SystemJ (Jspm) с Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack .
Sweta
см. этот ответ stackoverflow.com/a/40670147/2545680 для SystemJS
Макс Корецкий

Ответы:

135

Если вы перейдете на страницу SystemJS Github, вы увидите описание инструмента:

Универсальный динамический загрузчик модулей - загружает модули 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. В этом примере файл конфигурации компилятора машинописного текста будет выглядеть так:

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

Webpack - это гибкий модуль-упаковщик. Это означает, что он идет дальше и не только обрабатывает модули, но и предоставляет способ упаковки вашего приложения (файлы concat, файлы uglify, ...). Он также предоставляет dev-серверу перезагрузку для разработки.

SystemJS и Webpack различаются, но с SystemJS вам все еще нужно работать (например, с Gulp или SystemJS Builder ), чтобы упаковать ваше приложение Angular2 для производства.

Тьерри Темплиер
источник
2
Когда вы говорите «с SystemJS, у вас все еще есть работа (например, с Gulp или SystemJS builder) для упаковки вашего приложения Angular2 для производства» - это то, с чем я сейчас работаю npm start?
Smartmouse
5
Фактически, для производства неэффективно загружать много файлов для модулей (отдельные файлы (~ 300 запросов) или пакетные (~ 40 запросов)). Вам нужно собрать все в один или два (ваш код и код сторонней библиотеки), скомпилировать ваши шаблоны в автономном режиме (ngc) и использовать встряхивание дерева, чтобы минимизировать вес пакетов. Эта статья может вас заинтересовать: blog.mgechev.com/2016/06/26/… . Вам также необходимо увеличить CSS-файлы.
Тьерри Темплиер
1
С помощью npm start вы «просто» запускаете сервер, который будет обслуживать ваше приложение на основе вашей конфигурации SystemJS для модулей ...
Thierry Templier
11
Google официально перешел на webpack. Поэтому я думаю, что лучше придерживаться того, что будет использовать большинство сообщества. Я скоро перенесу свой проект systemJS в webpack. Не совсем уверен, как это сделать, хотя.
user2180794 16.09.16
1
@JonasKello это дело для угловых кли. Смотрите эту ссылку: github.com/angular/angular-cli в разделе «Обновление Webpack»?
Тьерри Темплиер
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 использует SystemJS.

Angular CLI использует Webpack.

Webpack 2 (который будет предлагать встряхивание дерева) находится в бета-версии, поэтому, возможно, сейчас самое время перейти на Webpack.

Примечание. SystemJS реализует стандарт загрузки модулей ES6 . Webpack - это просто еще один модуль npm.

Исполнители задач (дополнительное чтение для тех, кто хочет понять экосистему, в которой может существовать SystemJS)

С SystemJS его единственная ответственность заключается в отложенной загрузке файлов, поэтому что-то все еще необходимо для минимизации этих файлов, их переноса (например, из SASS в CSS) и т. Д. Эти задания, которые должны быть выполнены, называются задачами .

Webpack, когда настроен, правильно делает это для вас (и связывает вывод вместе). Если вы хотите сделать что-то подобное с SystemJS, вы обычно используете JavaScript Runner. Самым популярным средством запуска задач является еще один модуль npm, который называется gulp .

Так, например, SystemJS может лениво загрузить минимизированный файл JavaScript, который был минимизирован gulp. При правильной настройке Gulp может минимизировать файлы на лету и в режиме реального времени перезагрузить. Перезагрузка в режиме реального времени - это автоматическое обнаружение изменения кода и автоматическое обновление браузера для обновления. Отлично во время разработки. С помощью CSS возможна прямая трансляция (то есть вы видите, что страница обновляет новые стили без перезагрузки страницы).

Есть много других задач, которые могут выполнять Webpack и gulp, которых здесь было бы слишком много. Я привел пример :)

danday74
источник
7
Я тоже считаю, что с SystemJS и JSPM работать намного проще, чем с webpack. Также я обнаружил, что производственные пакеты меньше (по сравнению с другим примером проекта с веб-пакетом). Вот мой пост на эту тему: stackoverflow.com/questions/40256204/…
Peter Salomonsen
7
Вы можете использовать Webpack & Lazy loading с помощью angular2-router-loader. Посмотреть больше medium.com/@daviddentoom/…
Алекс Клаус
36
Вы ошибаетесь насчет Webpack! Это позволяет сочетать комплектацию с ленивой загрузкой. Более того, он прозрачно объединяет отложенные модули в порции.
dizel3d
3
@AlexKlaus спасибо за пример! Я искал что-то подобное :)
TFTD
3
«Webpack совершенно другой и требует вечного освоения. Он не делает то же самое, что SystemJS, но при использовании Webpack SystemJS становится избыточным». Я должен не согласиться. SystemJS по-прежнему позволяет разрабатывать разработки без необходимости постоянного построения для каждого изменения. Я могу внести изменения в файл TS, сохранить (который автоматически вызовет tsc.exe и соберет его), затем перезагрузить страницу и не иметь никаких проблем. С Webpack мне нужно пересобрать, что может занять значительно больше времени, потому что он перекомпилирует и соберет все . Я не смог найти способ избежать этого с помощью Webpack.
Полантарис
0

До сих пор я использовал systemjs. Он загружал файлы один за другим, и первая загрузка занимала 3-4 секунды без минимизированных файлов. После перехода на веб-пакет я получил значительное улучшение производительности. Теперь требуется только загрузить один пакетный файл (также полифилы и библиотеки вендоров, которые почти никогда не менялись и почти всегда кэшировались) и все. Теперь загрузка клиентского приложения занимает всего секунду. Никакой дополнительной логики на стороне клиента. Чем меньше количество загружаемых отдельных файлов, тем выше производительность. При использовании systemjs вы должны подумать о динамическом импорте модулей, чтобы сохранить производительность. С веб-пакетом вы сосредотачиваетесь, главным образом, на своей логике, потому что производительность все равно будет хорошей, когда пакет свернут и кэширован в вашем браузере.

Грач Гюльзадян
источник
3
Вы ответили только на один из вопросов ОП, было бы лучше сделать комментарий.
Бен