我正在创建我的第一个 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 在客户端工作。它在需要时根据需要动态加载模块(文件)。您不必预先加载整个应用程序。例如,您可以在按钮单击处理程序中加载文件。
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 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,您仍然需要做一些工作(例如使用 Gulp 或 SystemJS builder)来打包您的 Angular2 应用程序以用于生产。
npm start
得到的结果吗?
到目前为止,我使用的是 systemjs。它正在一个一个地加载文件,第一次加载需要 3-4 秒而没有缩小文件。切换到 webpack 后,我得到了很大的性能提升。现在只需要加载一个捆绑文件(还有 polyfill 和供应商库,它们几乎从不改变并且几乎总是被缓存),就是这样。现在只需一秒钟即可加载客户端应用程序。没有额外的客户端逻辑。加载的单个文件数量越少,性能越高。使用 systemjs 时,您应该考虑动态导入模块以节省性能。使用 webpack,你主要关注你的逻辑,因为一旦包被压缩并缓存在你的浏览器中,性能仍然会很好。
angular2-router-loader
进行延迟加载。查看更多medium.com/@daviddentoom/…