SystemJS(angular2.0):加载单独的文件还是最小化一个大的 JS?

SystemJS (angular2.0): Loading separate files vs minimize one big JS?

我对 SystemJS 有点困惑,它似乎自动单独加载文件,而不是将它们编译并最小化到一个大的 js 文件中。

我认为最初的想法是请求不同的文件,尽管较小的做法是不好的做法?并且生成了一个首选的大型 js 文件(最小化)。

这就是我现在安装 SystemJS 以加载单独文件的方式(见下文),现在推荐这样做吗?

   System.config({
            packages: {
                app: {
                    format: 'register',
                    defaultExtension: 'js'
                }
            }
        });
        System.import('app/main')
                .then(null, console.error.bind(console));

System.js(即ES6模块标准)改变开发流程

开发中

单独的文件 + 即时转译用于进行测试,重新加载 and/or 单个文件的热重新加载无需 transpile/build 每次更改后的整个应用程序包。

生产中

使用 Webpack 和 JSPM 等工具将单个文件转译并组合成一个或多个包。

JSPM 和 Webpack(即从版本 2 开始)都默认支持 ES6 模块,并且可以利用 tree shaking(即通过 rollup.js)来消除捆绑输出中未使用的代码。

旁白:最终,当 most/all 服务器支持 HTTP2 并且所有浏览器都原生支持 ES6 模块标准时,捆绑将成为一种反模式。捆绑的好处(即减少 HTTP 请求)将不再相关,缺点(即缓存特性差、开发复杂性增加)将成为不使用它的充分理由。

摇树

Tree Shaking 不是通过减少文件导入来优化包,而是跟踪应用程序的所有导入路径以确定哪些代码将包含在输出中。

例如,如果您的应用程序使用 Rxjs 可观察对象异步获取数据,您可以导入整个包。

import 'rxjs';

这很适合入门,但效率不高。打包过程的 tree shaking 步骤无法确定哪些代码未被使用,因此整个 Rxjs 包将包含在输出中。

要优化输出包大小,最好只导入应用程序代码中使用的 Rxjs 功能。

import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators/map';
import { startWith } from 'rxjs/operators/startWith';

当 tree shaking 步骤运行时,它将仅包括来自 Rxjs 包的代码,需要创建一个 Observable 并使用 mapstartWith 运算符。

转译

除了 tree shaking 和 bundling 之外,您还需要一种将 ES6/Typescript 源代码转换为 ES5 的策略。传统上,使用 Grunt 或 Gulp 等自动化工具手动指定转译、连接、minify/uglify 开发和生产代码所需的步骤。

JSPM 可以通过创建一个自执行包来处理所有这些

jspm bundle-sfx app/main dist/main --uglify

Webpack 可以完成同样的事情

webpack -p app/main.js dist/main.js

除了 ES6/Typescript 转译之外,这两个工具还可以利用 loaders/plugins 来支持其他文件类型,例如 css 和 scss.