2016-09-14 13:10:04 -04:00
|
|
|
|
include ../_util-fns
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
This cookbook describes how to radically improve performance by compiling _ahead-of-time_ (AOT)
|
2016-09-14 13:10:04 -04:00
|
|
|
|
during a build process.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
这个烹饪指南描述如何通过在构建过程中进行预编译(Ahead of Time - AOT)来从根本上提升性能。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
a#toc
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
# Contents
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
# 目录
|
2017-03-30 22:41:23 +01:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
* [Overview](#overview)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
|
|
|
|
[概览](#overview)
|
|
|
|
|
|
2017-03-31 15:25:27 -07:00
|
|
|
|
* [Ahead-of-time (AOT) vs just-in-time (JIT)](#aot-jit)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
[预编译(AOT) vs 即时编译(JIT)](#aot-jit)
|
|
|
|
|
|
2017-03-31 15:25:27 -07:00
|
|
|
|
* [Why do AOT compilation?](#why-aot)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
[为什么需要AOT编译?](#why-aot)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
* [Compile with AOT](#compile)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
|
|
|
|
[用AOT进行编译](#compile)
|
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
* [Bootstrap](#bootstrap)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-02-26 21:44:00 +08:00
|
|
|
|
[引导](#bootstrap)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-03-31 15:25:27 -07:00
|
|
|
|
* [Tree shaking](#tree-shaking)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
|
|
|
|
[摇树优化(Tree Shaking)](#tree-shaking)
|
2017-03-31 15:25:27 -07:00
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [Rollup](#rollup)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [Rollup Plugins](#rollup-plugins)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
[Rollup插件](#rollup-plugins)
|
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [Run Rollup](#run-rollup)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
[运行Rollup](#run-rollup)
|
2017-03-31 15:25:27 -07:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
* [Load the bundle](#load)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
[加载捆(bundle)文件](#load)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
* [Serve the app](#serve)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
[启动开发服务器](#serve)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-03-31 15:25:27 -07:00
|
|
|
|
* [AOT QuickStart source code](#source-code)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
[AOT 快速起步源码](#source-code)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-03-31 15:25:27 -07:00
|
|
|
|
* [Workflow and convenience script](#workflow)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
[工作流与辅助脚本](#workflow)
|
2017-03-31 15:25:27 -07:00
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [Develop JIT along with AOT](#run-jit)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
[先用JIT开发,再用AOT发布](#run-jit)
|
2017-03-31 15:25:27 -07:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
* [Tour of Heroes](#toh)
|
2017-02-26 21:44:00 +08:00
|
|
|
|
|
|
|
|
|
[英雄指南](#toh)
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [JIT in development, AOT in production](#jit-dev-aot-prod)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
[开发环境JIT,生产环境AOT](#jit-dev-aot-prod)
|
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [Tree shaking](#shaking)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
[摇树优化](#shaking)
|
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [Running the application](#running-app)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
[运行本应用](#running-app)
|
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
* [Inspect the Bundle](#inspect-bundle)
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
[审查捆(bundle)文件](#inspect-bundle)
|
2017-03-23 18:20:59 -04:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
a#overview
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Overview
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
## 概览
|
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
An Angular application consists largely of components and their HTML templates.
|
2017-03-01 20:26:56 +00:00
|
|
|
|
Before the browser can render the application,
|
2016-10-12 04:44:49 -04:00
|
|
|
|
the components and templates must be converted to executable JavaScript by the _Angular compiler_.
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
|
|
|
|
Angular应用主要包含组件和它们的HTML模板。
|
|
|
|
|
在浏览器可以渲染应用之前,组件和模板必须要被**Angular编译器**转换为可以执行的JavaScript。
|
2016-10-12 04:44:49 -04:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
|
|
|
|
<a href="https://www.youtube.com/watch?v=kW9cJsvcsGo" target="_blank">Watch compiler author Tobias Bosch explain the Angular Compiler</a> at AngularConnect 2016.
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
|
|
|
|
观看编译器作者Tobias Bosch在AngularConnect 2016大会里,对<a href="http://v.youku.com/v_show/id_XMTc1NTE4NTkwOA==.html?from=y1.7-1.4" target="_blank">Angular编译器</a>的演讲。
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
You can compile the app in the browser, at runtime, as the application loads, using the **_just-in-time_ (JIT) compiler**.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
This is the standard development approach shown throughout the documentation.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
It's great but it has shortcomings.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
你可以在浏览器中使用*即时编译器*(Just-in-Time - JIT)在运行期间编译该应用,也就是在应用加载时。
|
2016-09-16 18:13:42 +08:00
|
|
|
|
这是本文档中展示过的标准开发方式。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
它很不错,但是有自己的缺点。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
JIT compilation incurs a runtime performance penalty.
|
2017-03-01 20:26:56 +00:00
|
|
|
|
Views take longer to render because of the in-browser compilation step.
|
|
|
|
|
The application is bigger because it includes the Angular compiler
|
2016-09-14 13:10:04 -04:00
|
|
|
|
and a lot of library code that the application won't actually need.
|
|
|
|
|
Bigger apps take longer to transmit and are slower to load.
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
JIT编译导致运行期间的性能损耗。
|
2016-12-03 19:15:44 +08:00
|
|
|
|
由于需要在浏览器中执行这个编译过程,视图需要花更长时间才能渲染出来。
|
2016-09-16 18:13:42 +08:00
|
|
|
|
由于应用包含了Angular编译器以及大量实际上并不需要的库代码,所以文件体积也会更大。
|
|
|
|
|
更大的应用需要更长的时间进行传输,加载也更慢。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
Compilation can uncover many component-template binding errors.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
JIT compilation discovers them at runtime, which is late in the process.
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
编译可以发现一些组件模板绑定错误。JIT编译在运行时才揭露它们,那样有点太晚了。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The **_ahead-of-time_ (AOT) compiler** can catch template errors early and improve performance
|
|
|
|
|
by compiling at build time.
|
2016-09-16 18:13:42 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
而**预编译**(AOT)会在构建时编译,这样可以在早期截获模板错误,提高应用性能。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
a#aot-jit
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
## _Ahead-of-time_ (AOT) vs _just-in-time_ (JIT)
|
2017-02-26 15:04:21 +08:00
|
|
|
|
## 预编译(AOT) vs 即时编译(JIT)
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-01 20:26:56 +00:00
|
|
|
|
There is actually only one Angular compiler. The difference between AOT and JIT is a matter of timing and tooling.
|
|
|
|
|
With AOT, the compiler runs once at build time using one set of libraries;
|
2017-03-23 18:20:59 -04:00
|
|
|
|
with JIT it runs every time for every user at runtime using a different set of libraries.
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
事实上只有一个Angular编译器,AOT和JIT之间的差别仅仅在于编译的时机和所用的工具。
|
|
|
|
|
使用AOT,编译器仅仅使用一组库在构建期间运行一次;使用JIT,编译器在每个用户的每次运行期间都要用不同的库运行一次。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-04-15 16:59:00 +08:00
|
|
|
|
a#why-aot
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
## Why do AOT compilation?
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 16:59:00 +08:00
|
|
|
|
## 为什么需要AOT编译?
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
*Faster rendering*
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
**渲染得更快**
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
With AOT, the browser downloads a pre-compiled version of the application.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
The browser loads executable code so it can render the application immediately, without waiting to compile the app first.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
使用AOT,浏览器下载预编译版本的应用程序。
|
2016-09-16 18:13:42 +08:00
|
|
|
|
浏览器直接加载运行代码,所以它可以立即渲染该应用,而不用等应用完成首次编译。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
*Fewer asynchronous requests*
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
**需要的异步请求更少**
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The compiler _inlines_ external HTML templates and CSS style sheets within the application JavaScript,
|
2016-09-14 13:10:04 -04:00
|
|
|
|
eliminating separate ajax requests for those source files.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 16:59:00 +08:00
|
|
|
|
编译器把外部HTML模板和CSS样式表内联到了该应用的JavaScript中。
|
2016-09-16 18:13:42 +08:00
|
|
|
|
消除了用来下载那些源文件的Ajax请求。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
*Smaller Angular framework download size*
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
**需要下载的Angular框架体积更小**
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
There's no need to download the Angular compiler if the app is already compiled.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
如果应用已经编译过了,自然不需要再下载Angular编译器了。
|
|
|
|
|
该编译器差不多占了Angular自身体积的一半儿,所以,省略它可以显著减小应用的体积。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
*Detect template errors earlier*
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
**提早检测模板错误**
|
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
The AOT compiler detects and reports template binding errors during the build step
|
2016-10-12 04:44:49 -04:00
|
|
|
|
before users can see them.
|
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
AOT编译器在构建过程中检测和报告模板绑定错误,避免用户遇到这些错误。
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
|
|
|
|
*Better security*
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
**更安全**
|
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
AOT compiles HTML templates and components into JavaScript files long before they are served to the client.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
With no templates to read and no risky client-side HTML or JavaScript evaluation,
|
|
|
|
|
there are fewer opportunities for injection attacks.
|
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
AOT编译远在HTML模版和组件被服务到客户端之前,将它们编译到JavaScript文件。
|
2016-10-18 16:54:21 +01:00
|
|
|
|
没有模版可以阅读,没有高风险客户端HTML或JavaScript可利用,所以注入攻击的机会较少。
|
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
a#compile
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
2016-12-13 21:17:51 -08:00
|
|
|
|
## Compile with AOT
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
## 用AOT进行编译
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Preparing for offline compilation takes a few simple steps.
|
2016-11-26 21:43:16 +00:00
|
|
|
|
Take the <a href='../guide/setup.html'>Setup</a> as a starting point.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
A few minor changes to the lone `app.component` lead to these two class and HTML files:
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-04-15 15:34:47 +08:00
|
|
|
|
AOT编译需要一些简单的准备步骤。我们先从<a href='../guide/setup.html'>搭建本地开发环境</a>开始。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
只要单独对`app.component`文件的类文件和HTML文件做少量修改就可以了。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
+makeTabs(
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`cb-aot-compiler/ts/src/app/app.component.html,
|
|
|
|
|
cb-aot-compiler/ts/src/app/app.component.ts`,
|
2016-09-14 13:10:04 -04:00
|
|
|
|
null,
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`src/app/app.component.html,
|
|
|
|
|
src/app/app.component.ts`
|
2016-10-12 04:44:49 -04:00
|
|
|
|
)(format='.')
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
:marked
|
2017-04-15 17:09:42 +08:00
|
|
|
|
Install a few new npm dependencies with the following command:
|
|
|
|
|
|
|
|
|
|
用下列命令安装少量新的npm依赖:
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-09-14 21:39:53 +02:00
|
|
|
|
npm install @angular/compiler-cli @angular/platform-server --save
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
|
|
|
|
You will run the `ngc` compiler provided in the `@angular/compiler-cli` npm package
|
2017-03-01 20:26:56 +00:00
|
|
|
|
instead of the TypeScript compiler (`tsc`).
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
你要用`@angular/compiler-cli`包中提供的`ngc`编译器来代替TypeScript编译器(`tsc`)。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
`ngc` is a drop-in replacement for `tsc` and is configured much the same way.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
`ngc`是一个`tsc`的高仿替代品,它们的配置方式几乎完全一样。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
`ngc` requires its own `tsconfig.json` with AOT-oriented settings.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Copy the original `src/tsconfig.json` to a file called `tsconfig-aot.json` on the project root,
|
|
|
|
|
then modify it as follows.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
`ngc`需要自己的带有AOT专用设置的`tsconfig.json`。
|
2016-09-16 18:13:42 +08:00
|
|
|
|
把原始的`tsconfig.json`拷贝到一个名叫`tsconfig-aot.json`的文件中,然后像这样修改它:
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-aot-compiler/ts/tsconfig-aot.json', null, 'tsconfig-aot.json')(format='.')
|
|
|
|
|
|
|
|
|
|
:marked
|
2017-03-01 20:26:56 +00:00
|
|
|
|
The `compilerOptions` section is unchanged except for one property.
|
|
|
|
|
**Set the `module` to `es2015`**.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
This is important as explained later in the [Tree Shaking](#tree-shaking) section.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
`compilerOptions`部分只修改了一个属性:**把`module`设置为`es2015`。
|
|
|
|
|
这一点非常重要,我们会在后面的[摇树优化](#tree-shaking)部分解释为什么。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
What's really new is the `ngc` section at the bottom called `angularCompilerOptions`.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Its `genDir` property tells the compiler
|
2016-09-14 13:10:04 -04:00
|
|
|
|
to store the compiled output files in a new `aot` folder.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
`ngc`区真正新增的内容是底部的`angularCompilerOptions`。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
它的`genDir`属性告诉编译器把编译结果保存在新的`aot`目录下。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
The `"skipMetadataEmit" : true` property prevents the compiler from generating metadata files with the compiled application.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
Metadata files are not necessary when targeting TypeScript files, so there is no reason to include them.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
`"skipMetadataEmit" : true`属性阻止编译器为编译后的应用生成元数据文件。
|
|
|
|
|
当输出成TypeScript文件时,元数据并不是必须的,因此不需要包含它们。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-30 02:52:20 -05:00
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
***Component-relative template URLS***
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
***相对于组件的模板URL***
|
2016-11-30 02:52:20 -05:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The AOT compiler requires that `@Component` URLS for external templates and CSS files be _component-relative_.
|
2016-11-30 02:52:20 -05:00
|
|
|
|
That means that the value of `@Component.templateUrl` is a URL value _relative_ to the component class file.
|
|
|
|
|
For example, an `'app.component.html'` URL means that the template file is a sibling of its companion `app.component.ts` file.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
AOT编译器要求`@Component`中的外部模板和CSS文件的URL是*相对于组件的*。
|
|
|
|
|
这意味着`@Component.templateUrl`的值是一个*相对于*组件类文件的URL值。
|
|
|
|
|
例如,`'app.component.html'` URL表示模板文件与它相应的`app.component.ts`文件放在一起。
|
2016-11-30 02:52:20 -05:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
While JIT app URLs are more flexible, stick with _component-relative_ URLs for compatibility with AOT compilation.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
而JIT应用的URL更灵活,固定写成*相对于组件的*URL的形式对AOT编译的兼容性也更好。
|
2016-11-30 02:52:20 -05:00
|
|
|
|
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
***Compiling the application***
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 16:59:00 +08:00
|
|
|
|
*** 编译该应用 ***
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
Initiate AOT compilation from the command line using the previously installed `ngc` compiler by executing:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
在命令行中执行下列命令,借助刚安装好的`ngc`编译器来启动AOT编译:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-09-14 13:10:04 -04:00
|
|
|
|
node_modules/.bin/ngc -p tsconfig-aot.json
|
2016-10-12 04:44:49 -04:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
|
|
|
|
Windows users should surround the `ngc` command in double quotes:
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
|
|
|
|
Windows用户应该双引号`ngc`命令:
|
2016-10-12 04:44:49 -04:00
|
|
|
|
code-example(format='.').
|
|
|
|
|
"node_modules/.bin/ngc" -p tsconfig-aot.json
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
|
|
|
|
`ngc` expects the `-p` switch to point to a `tsconfig.json` file or a folder containing a `tsconfig.json` file.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
`ngc`希望`-p`选项指向一个`tsconfig.json`文件,或者一个包含`tsconfig.json`文件的目录。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
After `ngc` completes, look for a collection of _NgFactory_ files in the `aot` folder.
|
|
|
|
|
The `aot` folder is the directory specified as `genDir` in `tsconfig-aot.json`.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
在`ngc`完成时,会在`aot`目录下看到一组*NgFactory*文件(该目录是在`tsconfig-aot.json`的`genDir`属性中指定的)。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
These factory files are essential to the compiled application.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
Each component factory creates an instance of the component at runtime by combining the original class file
|
|
|
|
|
and a JavaScript representation of the component's template.
|
|
|
|
|
Note that the original component class is still referenced internally by the generated factory.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
这些工厂文件对于编译后的应用是必要的。
|
|
|
|
|
每个组件工厂都可以在运行时创建一个组件的实例,其中带有一个原始的类文件和一个用JavaScript表示的组件模板。
|
|
|
|
|
注意,原始的组件类依然是由所生成的这个工厂进行内部引用的。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The curious can open `aot/app.component.ngfactory.ts` to see the original Angular template syntax
|
|
|
|
|
compiled to TypeScript, its intermediate form.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
如果你好奇,可以打开`aot/app.component.ngfactory.ts`来看看原始Angular模板语法被编译成TypeScript时的中间结果。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
JIT compilation generates these same _NgFactories_ in memory where they are largely invisible.
|
|
|
|
|
AOT compilation reveals them as separate, physical files.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
JIT编译器在内存中同样会生成这一堆*NgFactory*,但它们大部分是不可见的。
|
|
|
|
|
AOT编译器则会生成在单独的物理文件中。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
.alert.is-important
|
|
|
|
|
:marked
|
2017-03-01 20:26:56 +00:00
|
|
|
|
Do not edit the _NgFactories_! Re-compilation replaces these files and all edits will be lost.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-22 15:27:49 +08:00
|
|
|
|
不要编辑这些*NgFactory*!重新编译时会替换这些文件,你做的所有修改都会丢失。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
a#bootstrap
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Bootstrap
|
2017-04-15 17:09:42 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
## 引导
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The AOT approach changes application bootstrapping.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
AOT也改变了应用的引导方式。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
Instead of bootstrapping `AppModule`, you bootstrap the application with the generated module factory, `AppModuleNgFactory`.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
引导的方式从引导`AppModule`改成了引导生成的模块工厂:`AppModuleNgFactory`。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-01 20:26:56 +00:00
|
|
|
|
Make a copy of `main.ts` and name it `main-jit.ts`.
|
2017-01-14 14:44:47 -08:00
|
|
|
|
This is the JIT version; set it aside as you may need it [later](#run-jit "Running with JIT").
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
复制一份`main.ts`并把它改名为`main-jit.ts`。
|
|
|
|
|
这就是JIT版本,先把它放在一边,我们[稍后](#run-jit "Running with JIT")会用到它。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
Open `main.ts` and convert it to AOT compilation.
|
|
|
|
|
Switch from the `platformBrowserDynamic.bootstrap` used in JIT compilation to
|
|
|
|
|
`platformBrowser().bootstrapModuleFactory` and pass in the AOT-generated `AppModuleNgFactory`.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
打开`main.ts`,并把它改成AOT编译。
|
|
|
|
|
从`platformBrowserDynamic.bootstrap`改成使用`platformBrowser().bootstrapModuleFactory`并把`AppModuleNgFactory`的AOT编译结果传给它。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
Here is AOT bootstrap in `main.ts` next to the original JIT version:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
这里是AOT版本`main.ts`中的引导过程,下一个是你所熟悉的JIT版本。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
+makeTabs(
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`cb-aot-compiler/ts/src/main.ts,
|
|
|
|
|
cb-aot-compiler/ts/src/main-jit.ts`,
|
2016-09-14 13:10:04 -04:00
|
|
|
|
null,
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`src/main.ts,
|
|
|
|
|
src/main-jit.ts`
|
2016-09-14 13:10:04 -04:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Be sure to [recompile](#compiling-aot) with `ngc`!
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 16:59:00 +08:00
|
|
|
|
确保用`ngc`进行[重新编译](#compiling-aot)!
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
a#tree-shaking
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
## Tree shaking
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
## 摇树优化(Tree shaking)
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
AOT compilation sets the stage for further optimization through a process called _tree shaking_.
|
|
|
|
|
A tree shaker walks the dependency graph, top to bottom, and _shakes out_ unused code like
|
|
|
|
|
dead leaves in a tree.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
AOT编译为接下来通过一个叫做*摇树优化*的过程做好了准备。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
摇树优化器从上到下遍历依赖图谱,并且*摇掉*用不到的代码,这些代码就像是圣诞树中那些死掉的松针一样。
|
|
|
|
|
|
|
|
|
|
Tree shaking can greatly reduce the downloaded size of the application
|
2016-09-14 13:10:04 -04:00
|
|
|
|
by removing unused portions of both source and library code.
|
|
|
|
|
In fact, most of the reduction in small apps comes from removing unreferenced Angular features.
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
通过移除源码和库代码中用不到的部分,摇树优化可以大幅缩减应用的下载体积。
|
|
|
|
|
事实上,在小型应用中大部分的缩减都是因为筛掉了那些没用到的Angular特性。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
For example, this demo application doesn't use anything from the `@angular/forms` library.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
There is no reason to download forms-related Angular code and tree shaking ensures that you don't.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
例如,这个演示程序中没有用到`@angular/forms`库中的任何东西,那么也就没有理由去下载这些与表单有关的Angular代码了。摇树优化可以帮你确保这一点。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Tree shaking and AOT compilation are separate steps.
|
|
|
|
|
Tree shaking can only target JavaScript code.
|
2017-03-01 20:26:56 +00:00
|
|
|
|
AOT compilation converts more of the application to JavaScript,
|
2017-03-23 18:20:59 -04:00
|
|
|
|
which in turn makes more of the application "tree shakable".
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
摇树优化和AOT编译是单独的步骤。
|
2017-06-13 17:08:41 +08:00
|
|
|
|
摇树优化仅仅针对JavaScript代码。
|
2017-02-26 15:04:21 +08:00
|
|
|
|
AOT编译会把应用中的大部分都转换成JavaScript,这种转换会让应用更容易被“摇树优化”。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
a#rollup
|
|
|
|
|
:marked
|
2016-09-14 13:10:04 -04:00
|
|
|
|
### Rollup
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
This cookbook illustrates a tree shaking utility called _Rollup_.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
这个烹饪宝典中用来示范的摇树优化工具是*Rollup*。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
Rollup statically analyzes the application by following the trail of `import` and `export` statements.
|
|
|
|
|
It produces a final code _bundle_ that excludes code that is exported, but never imported.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
Rollup会通过跟踪`import`和`export`语句来对本应用进行静态分析。
|
|
|
|
|
它所生成的最终代码*捆*中会排除那些被导出过但又从未被导入的代码。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Rollup can only tree shake `ES2015` modules which have `import` and `export` statements.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
Rollup只能对`ES2015`模块摇树,因为那里有`import`和`export`语句。
|
2017-04-15 17:09:42 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-03-01 20:26:56 +00:00
|
|
|
|
Recall that `tsconfig-aot.json` is configured to produce `ES2015` modules.
|
|
|
|
|
It's not important that the code itself be written with `ES2015` syntax such as `class` and `const`.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
What matters is that the code uses ES `import` and `export` statements rather than `require` statements.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
回忆一下,`tsconfig-aot.json`中曾配置为生成`ES2015`的模块。
|
|
|
|
|
代码本身是否用到了`ES2015`语法(例如`class`和`const`)并不重要,重要的是这些代码使用的应该是`import`和`export`语句,而不是`require`语句。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
In the terminal window, install the Rollup dependencies with this command:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
通过下列命令安装Rollup依赖:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-09-14 13:10:04 -04:00
|
|
|
|
npm install rollup rollup-plugin-node-resolve rollup-plugin-commonjs rollup-plugin-uglify --save-dev
|
|
|
|
|
:marked
|
2016-10-12 04:44:49 -04:00
|
|
|
|
Next, create a configuration file (`rollup-config.js`)
|
2017-03-01 20:26:56 +00:00
|
|
|
|
in the project root directory to tell Rollup how to process the application.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
The cookbook configuration file looks like this.
|
2016-09-16 18:13:42 +08:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
接下来,在项目根目录新建一个配置文件(`rollup-config.js`),来告诉Rollup如何处理应用。
|
|
|
|
|
本烹饪书配置文件是这样的:
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
+makeExample('cb-aot-compiler/ts/rollup-config.js', null, 'rollup-config.js')(format='.')
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
This config file tells Rollup that the app entry point is `src/app/main.js` .
|
2016-09-14 13:10:04 -04:00
|
|
|
|
The `dest` attribute tells Rollup to create a bundle called `build.js` in the `dist` folder.
|
2017-01-14 14:44:47 -08:00
|
|
|
|
It overrides the default `onwarn` method in order to skip annoying messages about the AOT compiler's use of the `this` keyword.
|
|
|
|
|
|
2017-04-15 16:59:00 +08:00
|
|
|
|
这个配置文件告诉Rollup,该应用的入口点是`app/main.js`。
|
|
|
|
|
`dest`属性告诉Rollup要在`dist`目录下创建一个名叫`build.js`的捆文件。
|
|
|
|
|
它覆盖了默认的`onwarn`方法,以便忽略由于AOT编译器使用`this`关键字导致的噪音消息。
|
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The next section covers the plugins in more depth.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-04-15 16:59:00 +08:00
|
|
|
|
下一节我们将深入讲解插件。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
a#rollup-plugins
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
|
|
|
|
### Rollup Plugins
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
### Rollup插件
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
Optional plugins filter and transform the Rollup inputs and output.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
这些可选插件过滤并转换Rollup的输入和输出。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
*RxJS*
|
2017-04-15 15:34:47 +08:00
|
|
|
|
|
|
|
|
|
Rollup expects application source code to use `ES2015` modules.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
Not all external dependencies are published as `ES2015` modules.
|
|
|
|
|
In fact, most are not. Many of them are published as _CommonJS_ modules.
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
Rollup期望应用的源码使用`ES2015`模块。
|
|
|
|
|
但并不是所有外部依赖都发布成了`ES2015`模块。
|
|
|
|
|
事实上,大多数都不是。它们大多数都发布成了*CommonJS*模块。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The _RxJs_ Observable library is an essential Angular dependency published as an ES5 JavaScript _CommonJS_ module.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-10-17 15:15:00 +01:00
|
|
|
|
可观察对象库*RxJS*是Angular所依赖的基础之一,它就是发布成了ES5 JavaScript的*CommonJS*模块。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Luckily, there is a Rollup plugin that modifies _RxJs_
|
2016-09-14 13:10:04 -04:00
|
|
|
|
to use the ES `import` and `export` statements that Rollup requires.
|
2017-03-31 01:13:42 +02:00
|
|
|
|
Rollup then preserves the parts of `RxJS` referenced by the application
|
|
|
|
|
in the final bundle. Using it is straigthforward. Add the following to
|
|
|
|
|
the `plugins` array in `rollup-config.js`:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
幸运的是,有一个Rollup插件,它会修改*RxJS*,以使用Rollup所需的ES`import`和`export`语句。
|
|
|
|
|
然后Rollup就可以把该应用中用到的那部分`RxJS`代码留在“捆”文件中了。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
它的用法很简单。把下列代码添加到`rollup-config.js`的`plugins`数组中:
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
+makeExample('cb-aot-compiler/ts/rollup-config.js','commonjs','rollup-config.js (CommonJs to ES2015 Plugin)')(format='.')
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
:marked
|
2017-03-01 20:26:56 +00:00
|
|
|
|
*Minification*
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
|
|
|
|
*最小化*
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Rollup tree shaking reduces code size considerably. Minification makes it smaller still.
|
2017-03-31 01:13:42 +02:00
|
|
|
|
This cookbook relies on the _uglify_ Rollup plugin to minify and mangle the code.
|
|
|
|
|
Add the following to the `plugins` array:
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
Rollup做摇树优化时会大幅减小代码体积。最小化过程则会让它更小。
|
|
|
|
|
本烹饪宝典依赖于Rollup插件*uglify*来最小化并混淆代码。
|
2017-04-15 17:09:42 +08:00
|
|
|
|
把下列代码添加到`plugins`数组中:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-aot-compiler/ts/rollup-config.js','uglify','rollup-config.js (CommonJs to ES2015 Plugin)')(format='.')
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
|
|
|
|
In a production setting, you would also enable gzip on the web server to compress
|
|
|
|
|
the code into an even smaller package going over the wire.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
在生产环境中,我们还应该打开Web服务器的gzip特性来把代码压缩得更小。
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
a#run-rollup
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
|
|
|
|
### Run Rollup
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
### 运行Rollup
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
Execute the Rollup process with this command:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
通过下列命令执行Rollup过程:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-10-12 04:44:49 -04:00
|
|
|
|
node_modules/.bin/rollup -c rollup-config.js
|
2016-09-14 13:10:04 -04:00
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
2017-01-14 14:44:47 -08:00
|
|
|
|
Windows users should surround the `rollup` command in double quotes:
|
2017-02-26 15:04:21 +08:00
|
|
|
|
|
|
|
|
|
Windows用户要把`rollup`命令放进双引号中:
|
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2017-01-14 14:44:47 -08:00
|
|
|
|
"node_modules/.bin/rollup" -c rollup-config.js
|
|
|
|
|
:marked
|
2016-09-14 13:10:04 -04:00
|
|
|
|
a#load
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
## Load the bundle
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
## 加载捆文件
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
Loading the generated application bundle does not require a module loader like SystemJS.
|
2016-09-14 13:10:04 -04:00
|
|
|
|
Remove the scripts that concern SystemJS.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Instead, load the bundle file using a single `<script>` tag **_after_** the `</body>` tag:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
加载所生成的应用捆文件,并不需要使用像SystemJS这样的模块加载器。
|
|
|
|
|
移除与SystemJS有关的那些脚本吧。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
改用`<script>`标签来加载这些捆文件:
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
+makeExample('cb-aot-compiler/ts/src/index.html','bundle','index.html (load bundle)')(format='.')
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
a#serve
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Serve the app
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
## 启动应用服务器
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
|
|
|
|
You'll need a web server to host the application.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Use the same `lite-server` employed elsewhere in the documentation:
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
你需要一个Web服务器来作为应用的宿主。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
像与文档中其它部分一样,用`lite-server`吧:
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-09-14 13:10:04 -04:00
|
|
|
|
npm run lite
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
:marked
|
|
|
|
|
The server starts, launches a browser, and the app should appear.
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-09-16 18:13:42 +08:00
|
|
|
|
启动了服务器、打开浏览器,应用就出现了。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-09-14 13:10:04 -04:00
|
|
|
|
a#source-code
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
## AOT QuickStart source code
|
2016-09-14 13:10:04 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
## AOT快速起步源代码
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
Here's the pertinent source code:
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
|
|
|
|
下面是相关源代码:
|
2016-09-14 13:10:04 -04:00
|
|
|
|
+makeTabs(
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`cb-aot-compiler/ts/src/app/app.component.html,
|
|
|
|
|
cb-aot-compiler/ts/src/app/app.component.ts,
|
|
|
|
|
cb-aot-compiler/ts/src/main.ts,
|
|
|
|
|
cb-aot-compiler/ts/src/index.html,
|
2016-09-14 13:10:04 -04:00
|
|
|
|
cb-aot-compiler/ts/tsconfig-aot.json,
|
2016-10-12 04:44:49 -04:00
|
|
|
|
cb-aot-compiler/ts/rollup-config.js`,
|
2016-09-14 13:10:04 -04:00
|
|
|
|
null,
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`src/app/app.component.html,
|
|
|
|
|
src/app/app.component.ts,
|
|
|
|
|
src/main.ts,
|
|
|
|
|
src/index.html,
|
2016-09-14 13:10:04 -04:00
|
|
|
|
tsconfig-aot.json,
|
2016-10-12 04:44:49 -04:00
|
|
|
|
rollup-config.js`
|
2016-09-14 13:10:04 -04:00
|
|
|
|
)
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
a#workflow
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Workflow and convenience script
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
## 工作流与便利脚本
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
2017-03-01 20:26:56 +00:00
|
|
|
|
You'll rebuild the AOT version of the application every time you make a change.
|
2017-01-14 14:44:47 -08:00
|
|
|
|
Those _npm_ commands are long and difficult to remember.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
每当修改时,我们都将重新构建应用的AOT版本。
|
|
|
|
|
那些*npm*命令太长,很难记。
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
|
|
|
|
Add the following _npm_ convenience script to the `package.json` so you can compile and rollup in one command.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
把下列*npm*便利脚本添加到`package.json`中,以便用一条命令就可以完成编译和Rollup打包工作。
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
+makeJson('cb-aot-compiler/ts/package.json', { paths: 'scripts.build:aot'}, "package.json (build:aot convenience script)")
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
:marked
|
|
|
|
|
Open a terminal window and try it.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
打开终端窗口,并试一下。
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2017-03-01 20:26:56 +00:00
|
|
|
|
npm run build:aot
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
|
|
|
|
a#run-jit
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
### Develop JIT along with AOT
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
### 先用JIT开发,再AOT发布
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
2017-03-01 20:26:56 +00:00
|
|
|
|
AOT compilation and rollup together take several seconds.
|
2017-01-14 14:44:47 -08:00
|
|
|
|
You may be able to develop iteratively a little faster with SystemJS and JIT.
|
|
|
|
|
The same source code can be built both ways. Here's one way to do that.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
AOT编译和Rollup打包加起来要花好几秒钟。
|
|
|
|
|
用SystemJS和JIT可以让开发期间的迭代更快一点。
|
|
|
|
|
同一套源码可以用这两种方式构建。下面是方法之一:
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
|
|
|
|
* Make a copy of `index.html` and call it `index-jit.html`.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
复制一份`index.html`并命名为`index-jit.html`。
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
* Delete the script at the bottom of `index-jit.html` that loads `bundle.js`
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
删除`index-jit.html`底部用来加载`bundle.js`的脚本
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
* Restore the SystemJS scripts like this:
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
代之以如下的SystemJS脚本:
|
|
|
|
|
|
2017-03-01 20:26:56 +00:00
|
|
|
|
+makeExample('cb-aot-compiler/ts/src/index-jit.html','jit','src/index-jit.html (SystemJS scripts)')(format='.')
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
|
|
|
|
:marked
|
2017-02-02 18:38:17 +00:00
|
|
|
|
Notice the slight change to the `system.import` which now specifies `src/app/main-jit`.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
That's the JIT version of the bootstrap file that we preserved [above](#bootstrap).
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
注意,这里稍微修改了一下`system.import`,现在它指向了`src/app/main-jit`。
|
|
|
|
|
这就是我们[以前](#bootstrap)预留的JIT版本的引导文件。
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Open a _different_ terminal window and enter `npm start`.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
打开*另一个*终端窗口,并输入`npm start`:
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
|
|
|
|
npm start
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
:marked
|
|
|
|
|
That compiles the app with JIT and launches the server.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The server loads `index.html` which is still the AOT version, which you can confirm in the browser console.
|
2017-03-30 22:41:23 +01:00
|
|
|
|
Change the address bar to `index-jit.html` and it loads the JIT version.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
This is also evident in the browser console.
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
2017-04-27 13:19:49 +08:00
|
|
|
|
它会使用JIT方式编译本应用,并启动服务器。
|
|
|
|
|
服务器仍然加载的是AOT版的`index.html`,我们可以在浏览器的控制台中确认这一点。
|
|
|
|
|
在地址栏中改为`index-jit.html`,它就会加载JIT版,这同样可以在浏览器控制台中确认。
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
Develop as usual.
|
|
|
|
|
The server and TypeScript compiler are in "watch mode" so your changes are reflected immediately in the browser.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
2017-05-07 11:36:33 +08:00
|
|
|
|
照常开发。服务器和TypeScript编译器都处于“监听模式”,因此我们的修改都可以立刻反映到浏览器中。
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
2017-03-01 20:26:56 +00:00
|
|
|
|
To see those changes in AOT, switch to the original terminal and re-run `npm run build:aot`.
|
2017-03-30 22:41:23 +01:00
|
|
|
|
When it finishes, go back to the browser and use the back button to
|
2017-03-23 18:20:59 -04:00
|
|
|
|
return to the AOT version in the default `index.html`.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
要对比AOT版的变化,可以切换到原来的终端窗口中,并重新运行`npm run build:aot`。
|
|
|
|
|
结束时,回到浏览器中,并用浏览器的后退按钮回到默认`index.html`中的AOT版本。
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
|
|
|
|
Now you can develop JIT and AOT, side-by-side.
|
2017-04-27 13:19:49 +08:00
|
|
|
|
|
|
|
|
|
现在,我们就可以同时进行JIT和AOT开发了。
|
2017-01-14 14:44:47 -08:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
a#toh
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Tour of Heroes
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
## 英雄指南
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
The sample above is a trivial variation of the QuickStart application.
|
|
|
|
|
In this section you apply what you've learned about AOT compilation and tree shaking
|
|
|
|
|
to an app with more substance, the [_Tour of Heroes_](../tutorial/toh-pt6.html) application.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2016-11-27 10:41:55 +00:00
|
|
|
|
上面的例子是《快速起步》应用的一个简单的变体。
|
2017-02-26 15:04:21 +08:00
|
|
|
|
在本节中,你将在一个更多内容的应用 - [英雄指南](../tutorial/toh-pt6.html)上使用从AOT编译和摇树优化学到的知识。
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
a#jit-dev-aot-prod
|
|
|
|
|
:marked
|
2016-12-13 21:17:51 -08:00
|
|
|
|
### JIT in development, AOT in production
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
### 开发器使用JIT, 产品期使用AOT
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Today AOT compilation and tree shaking take more time than is practical for development. That will change soon.
|
2016-12-13 21:17:51 -08:00
|
|
|
|
For now, it's best to JIT compile in development and switch to AOT compilation before deploying to production.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
目前,AOT编译和摇树优化对开发来说,占用的时间太多了。这将在未来得到改变。
|
|
|
|
|
当前的最佳实践是在开发器使用JIT编译,然后在发布产品前切换到AOT编译。
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
Fortunately, the source code can be compiled either way without change _if_ you account for a few key differences.
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
幸运的是,**如果**你处理了几个关键不同点,源代码可以在没有任何变化时,采取两种方式的任何一种都能编译。
|
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
***index.html***
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
The JIT and AOT apps require their own `index.html` files because they setup and launch so differently.
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
JIT和AOT应用的设置和加载非常不一样,因此它们需要各自的`index.html`文件。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
Here they are for comparison:
|
2016-11-22 15:21:36 +00:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
下面是它们的比较:
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
+makeTabs(
|
|
|
|
|
`toh-6/ts/aot/index.html,
|
2017-02-02 18:38:17 +00:00
|
|
|
|
toh-6/ts/src/index.html`,
|
2016-10-12 04:44:49 -04:00
|
|
|
|
null,
|
2016-12-13 21:17:51 -08:00
|
|
|
|
`aot/index.html (AOT),
|
2017-02-02 18:38:17 +00:00
|
|
|
|
src/index.html (JIT)`
|
2016-10-12 04:44:49 -04:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
:marked
|
2017-03-01 20:26:56 +00:00
|
|
|
|
The JIT version relies on `SystemJS` to load individual modules.
|
2017-01-02 21:15:24 +00:00
|
|
|
|
Its scripts appear in its `index.html`.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
JIT版本依靠`SystemJS`来加载单个模块,并需要`reflect-metadata`垫片。
|
2016-10-18 16:54:21 +01:00
|
|
|
|
所以它们出现在它的`index.html`中。
|
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
The AOT version loads the entire application in a single script, `aot/dist/build.js`.
|
2017-01-02 21:15:24 +00:00
|
|
|
|
It does not need `SystemJS`, so that script is absent from its `index.html`
|
2017-03-01 20:26:56 +00:00
|
|
|
|
|
2016-11-22 15:21:36 +00:00
|
|
|
|
***main.ts***
|
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
JIT and AOT applications boot in much the same way but require different Angular libraries to do so.
|
2016-11-22 20:07:16 +08:00
|
|
|
|
The key differences, covered in the [Bootstrap](#bootstrap) section above,
|
|
|
|
|
are evident in these `main` files which can and should reside in the same folder:
|
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
AOT版本用一个单独的脚本来加载整个应用 - `aot/dist/build.js`。它不需要`SystemJS`和`reflect-metadata`垫片,所以它们不会出现在`index.html`中。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
|
|
|
|
+makeTabs(
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`toh-6/ts/src/main-aot.ts,
|
|
|
|
|
toh-6/ts/src/main.ts`,
|
2016-11-22 20:07:16 +08:00
|
|
|
|
null,
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`main-aot.ts (AOT),
|
|
|
|
|
main.ts (JIT)`
|
2016-11-22 20:07:16 +08:00
|
|
|
|
)
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
2016-11-22 20:07:16 +08:00
|
|
|
|
***TypeScript configuration***
|
2016-11-22 15:21:36 +00:00
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
***TypeScript配置***
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
JIT-compiled applications transpile to `commonjs` modules.
|
2017-03-23 18:20:59 -04:00
|
|
|
|
AOT-compiled applications transpile to _ES2015_/_ES6_ modules to facilitate tree shaking.
|
2016-12-13 21:17:51 -08:00
|
|
|
|
AOT requires its own TypeScript configuration settings as well.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
JIT编译的应用编译为`commonjs`模块。
|
|
|
|
|
AOT编译的应用编译为**ES2015/ES6**模块,用来支持摇树优化。
|
|
|
|
|
而且AOT需要它自己的TypeScript配置设置。
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
You'll need separate TypeScript configuration files such as these:
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
你将需要单独的TypeScript配置文件,像这些:
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
+makeTabs(
|
|
|
|
|
`toh-6/ts/tsconfig-aot.json,
|
2017-03-01 20:26:56 +00:00
|
|
|
|
toh-6/ts/src/tsconfig.1.json`,
|
2016-10-12 04:44:49 -04:00
|
|
|
|
null,
|
2016-12-13 21:17:51 -08:00
|
|
|
|
`tsconfig-aot.json (AOT),
|
2017-02-02 18:38:17 +00:00
|
|
|
|
src/tsconfig.json (JIT)`
|
2016-09-14 13:10:04 -04:00
|
|
|
|
)
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
.callout.is-helpful
|
|
|
|
|
header @Types and node modules
|
|
|
|
|
header @Types和node模块
|
|
|
|
|
:marked
|
|
|
|
|
In the file structure of _this particular sample project_,
|
2017-04-15 15:34:47 +08:00
|
|
|
|
the `node_modules` folder happens to be two levels up from the project root.
|
|
|
|
|
Therefore, `"typeRoots"` must be set to `"../../node_modules/@types/"`.
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
在**这个特定的示例项目**的文件结构中,`node_modules`文件恰好比项目根目录高两级。
|
|
|
|
|
因此,`"typeRoots"`必须设置为`"../../node_modules/@types/"`。
|
2017-04-15 16:59:00 +08:00
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
In a more typical project, `node_modules` would be a sibling of `tsconfig-aot.json`
|
|
|
|
|
and `"typeRoots"` would be set to `"node_modules/@types/"`.
|
|
|
|
|
Edit your `tsconfig-aot.json` to fit your project's file structure.
|
|
|
|
|
|
|
|
|
|
在一个更典型的项目中,`node_modules`位于`tsconfig-aot.json`同级,
|
|
|
|
|
这时`"typeRoots"`应设置为`"node_modules/@types/"`。
|
|
|
|
|
编辑你的`tsconfig-aot.json`,使之适合项目的文件结构。
|
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
a#shaking
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
### Tree shaking
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
### 摇树优化
|
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Rollup does the tree shaking as before.
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
|
|
|
|
Rollup和以前一样,仍然进行摇树优化。
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2017-03-01 20:26:56 +00:00
|
|
|
|
+makeExample('toh-6/ts/rollup-config.js',null,'rollup-config.js')(format='.')
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
a#running-app
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
|
|
|
|
### Running the application
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
### 运行应用
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
.alert.is-important
|
|
|
|
|
:marked
|
2016-12-13 21:17:51 -08:00
|
|
|
|
The general audience instructions for running the AOT build of the Tour of Heroes app are not ready.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
面向大众的运行AOT构建的英雄指南应用的说明还没有准备好。
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
The following instructions presuppose that you have cloned the
|
2017-03-01 20:26:56 +00:00
|
|
|
|
<a href="https://github.com/angular/angular.io" target="_blank">angular.io</a>
|
2016-10-12 04:44:49 -04:00
|
|
|
|
github repository and prepared it for development as explained in the repo's README.md.
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
下面的说明假设你克隆了<a href="https://github.com/angular/angular.io" target="_blank">angular.io</a> Github库,并按照该库的README.md准备了开发环境。
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
The _Tour of Heroes_ source code is in the `public/docs/_examples/toh-6/ts` folder.
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
|
|
|
|
**英雄指南**源代码在`public/docs/_examples/toh-6/ts`目录。
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
2016-12-13 21:17:51 -08:00
|
|
|
|
Run the JIT-compiled app with `npm start` as for all other JIT examples.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
和其他JIT例子一样,使用`npm start`命令,运行JIT编译的应用:
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2016-12-13 21:17:51 -08:00
|
|
|
|
Compiling with AOT presupposes certain supporting files, most of them discussed above.
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
AOT编译假设上面介绍的一些支持文件都以准备好。
|
2016-10-12 04:44:49 -04:00
|
|
|
|
+makeTabs(
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`toh-6/ts/src/index.html,
|
2016-10-12 04:44:49 -04:00
|
|
|
|
toh-6/ts/copy-dist-files.js,
|
|
|
|
|
toh-6/ts/rollup-config.js,
|
|
|
|
|
toh-6/ts/tsconfig-aot.json`,
|
|
|
|
|
null,
|
2017-02-02 18:38:17 +00:00
|
|
|
|
`src/index.html,
|
2016-10-12 04:44:49 -04:00
|
|
|
|
copy-dist-files.js,
|
|
|
|
|
rollup-config.js,
|
|
|
|
|
tsconfig-aot.json`)
|
|
|
|
|
:marked
|
|
|
|
|
Extend the `scripts` section of the `package.json` with these npm scripts:
|
2017-02-26 15:04:21 +08:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
使用下面的npm脚本,扩展`package.json`文件的`scripts`部分:
|
|
|
|
|
|
2017-02-02 18:38:17 +00:00
|
|
|
|
+makeJson('cb-aot-compiler/ts/package.json', { paths: 'scripts.build:aot, scripts.serve:aot'}, "package.json (convenience scripts)")
|
2017-03-01 20:26:56 +00:00
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
2016-12-13 21:17:51 -08:00
|
|
|
|
Copy the AOT distribution files into the `/aot` folder with the node script:
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
使用下面的node脚本,拷贝AOT发布文件到`/aot/`目录:
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-10-12 04:44:49 -04:00
|
|
|
|
node copy-dist-files
|
|
|
|
|
.l-sub-section
|
|
|
|
|
:marked
|
|
|
|
|
You won't do that again until there are updates to `zone.js` or the `core-js` shim for old browsers.
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
|
|
|
|
直到`zone.js`或者支持老版本浏览器的`core-js`垫片有更新,你不需要再这样做。
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
2017-03-23 18:20:59 -04:00
|
|
|
|
Now AOT-compile the app and launch it with the `lite-server`:
|
2016-10-18 16:54:21 +01:00
|
|
|
|
|
2017-02-26 15:04:21 +08:00
|
|
|
|
现在AOT编译应用,并使用`lite`服务器启动它:
|
2017-04-15 17:09:42 +08:00
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2017-02-02 18:38:17 +00:00
|
|
|
|
npm run build:aot && npm run serve:aot
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2017-03-23 18:20:59 -04:00
|
|
|
|
a#inspect-bundle
|
2016-10-12 04:44:49 -04:00
|
|
|
|
:marked
|
|
|
|
|
### Inspect the Bundle
|
2016-11-22 20:07:16 +08:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
### 检查包裹
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2016-11-26 21:43:16 +00:00
|
|
|
|
It's fascinating to see what the generated JavaScript bundle looks like after Rollup.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
The code is minified, so you won't learn much from inspecting the bundle directly.
|
2017-03-01 20:26:56 +00:00
|
|
|
|
But the <a href="https://github.com/danvk/source-map-explorer/blob/master/README.md" target="_blank">source-map-explorer</a>
|
|
|
|
|
tool can be quite revealing.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
看看Rollup之后生成的JavaScript包,非常神奇。
|
|
|
|
|
代码已经被最小化,所以你不会从中直接学到任何知识。
|
|
|
|
|
但是<a href="https://github.com/danvk/source-map-explorer/blob/master/README.md" target="_blank">source-map-explorer</a> 工具非常有用。
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
Install it:
|
2016-10-18 19:24:18 +01:00
|
|
|
|
|
|
|
|
|
安装:
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-10-12 04:44:49 -04:00
|
|
|
|
npm install source-map-explorer --save-dev
|
|
|
|
|
:marked
|
|
|
|
|
Run the following command to generate the map.
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
运行下面的命令来生成源映射。
|
|
|
|
|
|
2017-01-14 14:44:47 -08:00
|
|
|
|
code-example(language="none" class="code-shell").
|
2016-10-12 04:44:49 -04:00
|
|
|
|
node_modules/.bin/source-map-explorer aot/dist/build.js
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
The `source-map-explorer` analyzes the source map generated with the bundle and draws a map of all dependencies,
|
|
|
|
|
showing exactly which application and Angular modules and classes are included in the bundle.
|
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
`source-map-explorer`分析从包生成的源映射,并画出一个依赖地图,显示包中包含哪些应用程序和Angular模块和类。
|
|
|
|
|
|
2016-11-22 20:07:16 +08:00
|
|
|
|
Here's the map for _Tour of Heroes_.
|
2016-10-12 04:44:49 -04:00
|
|
|
|
|
2016-10-18 16:54:21 +01:00
|
|
|
|
下面是英雄指南的地图:
|
|
|
|
|
|
2016-10-12 04:44:49 -04:00
|
|
|
|
a(href="/resources/images/cookbooks/aot-compiler/toh6-bundle.png", target="_blank", title="View larger image")
|
|
|
|
|
figure.image-display
|
2017-03-01 20:26:56 +00:00
|
|
|
|
img(src="/resources/images/cookbooks/aot-compiler/toh6-bundle.png" alt="TOH-6-bundle")
|