SystemJS和Webpack之间有什么区别?

我正在创建我的第一个Angular应用程序,我会弄清楚模块加载器的作用是什么。为什么我们需要它们?我试图在Google上搜索和搜索,我不明白为什么我们需要安装其中一个来运行我们的应用程序?

仅仅用于从节点模块加载东西还不够吗?import

我已经遵循了本教程(使用SystemJS),它使我使用file: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或其他)?
最后,在您看来,什么更好?


答案 1

SystemJS 在客户端工作。它在需要时按需动态加载模块(文件)。您不必预先加载整个应用程序。例如,您可以在按钮单击处理程序中加载文件。

SystemJS code:

// 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准备了一个名为bul.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任务运行器。最流行的任务运行器是另一个名为 gulp 的 npm 模块。

因此,例如,SystemJS可能会延迟加载一个已由 gulp 缩小的缩小的 JavaScript 文件。如果设置正确,Gulp可以动态缩小文件并实时重新加载。实时重新加载是自动检测代码更改和自动刷新浏览器以进行更新。在开发过程中很棒。使用CSS,可以进行实时流式传输(即,您看到页面更新新样式,甚至无需重新加载页面)。

Webpack和gulp还可以执行许多其他任务,这些任务太多了,无法在这里介绍。我提供了一个示例:)


答案 2

如果您转到SystemJS Github页面,您将看到该工具的描述:

通用动态模块加载器 - 在浏览器和NodeJS中加载ES6模块,AMD,CommonJS和全局脚本。

由于您在 TypeScript 或 ES6 中使用模块,因此需要一个模块加载程序。在 SystemJS 的情况下,允许我们配置模块名称与其相应文件匹配的方式。systemjs.config.js

如果显式使用此配置文件(和 SystemJS)来导入应用程序的主模块,则此配置文件(和 SystemJS)是必需的:

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

使用 TypeScript 并将编译器配置为模块时,编译器将创建不再基于 SystemJS 的代码。在此示例中,typescript 编译器配置文件将如下所示:commonjs

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

Webpack 是一个灵活的模块捆绑器。这意味着它走得更远,不仅处理模块,还提供了一种打包应用程序的方法(concat文件,uglify文件等)。它还为开发服务器提供了用于开发的负载重新加载。

SystemJS和Webpack是不同的,但是使用SystemJS,您仍然需要做一些工作(例如使用GulpSystemJS builder)来打包您的Angular2应用程序以进行生产。