ChatGPT解决这个技术问题 Extra ChatGPT

SystemJS 和 Webpack 有什么区别?

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

仅使用 import 从节点模块加载内容还不够吗?

我关注了 this tutorial(使用 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 或其他)?最后,您认为哪个更好?

在这里您可以阅读非常好的文章来比较 SystemJs(Jspm) 和 Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack
请参阅 SystemJS 的此答案 stackoverflow.com/a/40670147/2545680

d
danday74

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(将提供 tree shaking)处于测试阶段,所以也许现在是迁移到 Webpack 的糟糕时机。

注意 SystemJS 正在实现 ES6 module loading standard。 Webpack 只是另一个 npm 模块。

任务运行器(对于那些想要了解 SystemJS 可能存在的生态系统的人的可选读物)

对于 SystemJS,它的唯一职责是延迟加载文件,因此仍然需要一些东西来缩小这些文件、转换这些文件(例如从 SASS 到 CSS)等。这些必须完成的工作称为任务。

Webpack 在配置后会为您正确执行此操作(并将输出捆绑在一起)。如果你想用 SystemJS 做类似的事情,你通常会使用 JavaScript 任务运行器。最受欢迎的任务运行器是另一个名为 gulp 的 npm 模块。

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

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


我也是,我发现 SystemJS 和 JSPM 比 webpack 更容易使用。我还发现生产包更小(与另一个 webpack 示例项目相比)。这是我关于该主题的帖子:stackoverflow.com/questions/40256204/…
你可以使用 Webpack &使用 angular2-router-loader 进行延迟加载。查看更多medium.com/@daviddentoom/…
你错了 Webpack!它允许您将捆绑与延迟加载结合起来。此外,它透明地将延迟模块捆绑成块。
@AlexKlaus 感谢您的示例!我正在寻找类似的东西:)
“Webpack 完全不同,需要很长时间才能掌握。它与 SystemJS 做的事情不同,但是当使用 Webpack 时,SystemJS 变得多余。”我不同意。 SystemJS 仍然允许开发人员开发,而无需不断地为每次更改进行构建。我可以更改一个 TS 文件,保存(它会自动调用 tsc.exe 并构建它),然后重新加载我的页面并且没有任何问题。使用 Webpack,我必须重新构建,这可能需要更长的时间,因为它将重新编译和构建所有内容。我无法找到任何方法来避免使用 Webpack。
d
danday74

如果你去 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 builder)来打包您的 Angular2 应用程序以用于生产。


当您说“使用 SystemJS,您仍有工作要做(例如使用 Gulp 或 SystemJS 构建器)来打包您的 Angular2 应用程序以进行生产”是我目前使用 npm start 得到的结果吗?
事实上,对于生产来说,为模块加载大量文件(单个文件(~300 个请求)或捆绑(~40 个请求))效率不高。您需要将所有内容收集到一两个(您的代码和第三方库代码)中,离线编译您的模板 (ngc) 并利用树抖动来最小化包的重量。您可能会对这篇文章感兴趣:blog.mgechev.com/2016/06/26/…。您还需要对 CSS 文件进行 uglify。
使用 npm start,您“只需”启动一个服务器,该服务器将根据您的 SystemJS 模块配置为您的应用程序提供服务......
Google 已正式迁移到 webpack。所以我想最好还是坚持大多数社区会使用的东西。我很快将我的 systemJS 项目迁移到 webpack。不完全确定如何做到这一点。
@JonasKello 角度 cli 就是这种情况。在“Webpack 更新”部分看到这个链接:github.com/angular/angular-cli
H
Hrach Gyulzadyan

到目前为止,我使用的是 systemjs。它正在一个一个地加载文件,第一次加载需要 3-4 秒而没有缩小文件。切换到 webpack 后,我得到了很大的性能提升。现在只需要加载一个捆绑文件(还有 polyfill 和供应商库,它们几乎从不改变并且几乎总是被缓存),就是这样。现在只需一秒钟即可加载客户端应用程序。没有额外的客户端逻辑。加载的单个文件数量越少,性能越高。使用 systemjs 时,您应该考虑动态导入模块以节省性能。使用 webpack,你主要关注你的逻辑,因为一旦包被压缩并缓存在你的浏览器中,性能仍然会很好。


您只回答了 OP 的一个问题,最好发表评论。