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
斯威塔

看到这个答案stackoverflow.com/a/40670147/2545680 for SystemJS
Max Koretskyi

Answers:


135

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

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

因为您在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文件等)的方法。它还为开发服务器提供了加载重载以进行开发。

SystemJS和Webpack有所不同,但是对于SystemJS,您仍然需要进行工作(例如,使用GulpSystemJS构建器)来打包Angular2应用程序以进行生产。


2
当您说“使用SystemJS时,您仍然有工作要做(例如,使用Gulp或SystemJS构建器)以打包Angular2应用程序进行生产”是我现在得到的npm start
smartmouse

5
实际上,对于生产而言,为模块加载大量文件(单个文件(约300个请求)或捆绑(约40个请求))效率不高。您需要将所有内容收集到一个或两个(您的代码和第三方库代码)中,离线编译模板(ngc)并利用摇树来最大程度地减少捆绑包的重量。本文可能会让您感兴趣:blog.mgechev.com/2016/06/26/…。您还需要丑化CSS文件。
Thierry Templier

1
使用npm start,您可以“简单地”启动服务器,该服务器将根据模块的SystemJS配置为您的应用程序提供服务...
Thierry Templier

11
Google已正式移至webpack。因此,我认为最好坚持使用大多数社区会使用的东西。我即将将我的systemJS项目迁移到webpack。虽然不完全确定该怎么做。
user2180794 '16

1
@JonasKello角度cli就是这种情况。请参阅“ Webpack更新”部分中的此链接:github.com/angular/angular-cli
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快速入门使用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可以执行许多其他任务,这些任务在这里无法涵盖。我提供了一个例子:)


7
我也觉得SystemJS和JSPM比使用webpack容易得多。我还发现生产捆绑包较小(与另一个webpack示例项目相比)。这里是我的话题后:stackoverflow.com/questions/40256204/...
彼得Salomonsen

7
您可以将Webpack&Lazy加载与一起使用angular2-router-loader。详情请见medium.com/@daviddentoom/…–
亚历克斯·克劳斯

36
您对Webpack错了!它使您可以将捆绑与延迟加载结合在一起。而且,它透明地将延迟的模块捆绑为块。
dizel3d

3
@AlexKlaus感谢您的示例!我一直在寻找这样的东西:)
tftd

3
“ Webpack完全不同,需要永远掌握。它与SystemJS的功能不同,但是当使用Webpack时,SystemJS变得多余。” 我不同意。SystemJS仍然允许开发人员进行开发,而不必不断为每个更改进行构建。我可以对TS文件进行更改,然后保存(它将自动调用tsc.exe并进行构建),然后重新加载页面,没有任何问题。使用Webpack,我必须重建,这可能会花费更长的时间,因为它将重新编译并构建所有内容。我无法找到任何方法来避免使用Webpack。
Polantaris

0

到目前为止,我正在使用systemjs。它正在一次一个地加载文件,第一次加载需要3-4秒,而没有缩小的文件。切换到webpack后,我获得了很大的性能提升。现在只需加载一个捆绑文件(几乎从未更改且几乎始终已缓存的polyfills和vendor lib)就可以了。现在只需一秒钟即可加载客户端应用程序。没有其他客户端逻辑。加载的单个文件数量越少,性能越高。使用systemjs时,您应该考虑动态导入模块以节省性能。使用webpack时,您将主要精力放在逻辑上,因为一旦缩小包并将其缓存在浏览器中,性能仍然会很好。


3
您只回答了OP的一个问题,最好发表评论。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.