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
并使用 map
和 startWith
运算符。
转译
除了 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.
我对 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
并使用 map
和 startWith
运算符。
转译
除了 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.