docs: Deployment guide for CLI (#19839)
This commit is contained in:
parent
26f82995f6
commit
03f080b7da
@ -1,15 +0,0 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
<h1>Simple Deployment</h1>
|
||||
<nav>
|
||||
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
|
||||
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`
|
||||
})
|
||||
export class AppComponent { }
|
@ -1,29 +0,0 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{ path: 'crisis-center', component: CrisisListComponent },
|
||||
{ path: 'heroes', component: HeroListComponent },
|
||||
|
||||
{ path: '', redirectTo: '/heroes', pathMatch: 'full' }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
RouterModule.forRoot(appRoutes)
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
CrisisListComponent,
|
||||
HeroListComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,9 +0,0 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>CRISIS CENTER</h2>
|
||||
<p>Get your crisis here</p>`
|
||||
})
|
||||
export class CrisisListComponent { }
|
@ -1,10 +0,0 @@
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>HEROES</h2>
|
||||
<p>Get your heroes here</p>
|
||||
`
|
||||
})
|
||||
export class HeroListComponent { }
|
@ -1,38 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Doesn't load from node_modules! -->
|
||||
|
||||
<!-- Set the base href -->
|
||||
<base href="/">
|
||||
<title>Simple Deployment</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- #docregion node-module-scripts -->
|
||||
<!-- Polyfills -->
|
||||
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
|
||||
|
||||
<!-- Update these package versions as needed -->
|
||||
<script src="https://unpkg.com/zone.js@0.8.4?main=browser"></script>
|
||||
<script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
|
||||
<!-- #enddocregion node-module-scripts -->
|
||||
|
||||
<!-- #docregion systemjs-config -->
|
||||
<!-- This SystemJS configuration loads umd packages from the web -->
|
||||
<script src="systemjs.config.server.js"></script>
|
||||
<!-- #enddocregion systemjs-config -->
|
||||
|
||||
<script>
|
||||
System.import('main.js')
|
||||
.catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<my-app></my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,15 +0,0 @@
|
||||
// #docregion
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
// #docregion enableProdMode
|
||||
import { enableProdMode } from '@angular/core';
|
||||
|
||||
// Enable production mode unless running locally
|
||||
if (!/localhost/.test(document.location.host)) {
|
||||
enableProdMode();
|
||||
}
|
||||
// #enddocregion enableProdMode
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
@ -1,46 +0,0 @@
|
||||
// #docregion
|
||||
/**
|
||||
* System configuration for deployment without installing node_modules
|
||||
* Loads umd packages from the web instead
|
||||
* Adjust as necessary for your application needs.
|
||||
*/
|
||||
(function (global) {
|
||||
System.config({
|
||||
// #docregion paths
|
||||
paths: {
|
||||
'npm:': 'https://unpkg.com/' // path serves as alias
|
||||
},
|
||||
// #enddocregion paths
|
||||
// map tells the System loader where to look for things
|
||||
map: {
|
||||
app: 'app', // location of transpiled app files
|
||||
|
||||
// angular minimized umd bundles
|
||||
'@angular/core': 'npm:@angular/core/bundles/core.umd.min.js',
|
||||
'@angular/common': 'npm:@angular/common/bundles/common.umd.min.js',
|
||||
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.min.js',
|
||||
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.min.js',
|
||||
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
|
||||
'@angular/http': 'npm:@angular/http/bundles/http.umd.min.js',
|
||||
'@angular/router': 'npm:@angular/router/bundles/router.umd.min.js',
|
||||
'@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.min.js',
|
||||
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.min.js',
|
||||
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.min.js',
|
||||
'@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.min.js',
|
||||
|
||||
// other libraries
|
||||
'rxjs': 'npm:rxjs@5.0.1',
|
||||
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
|
||||
},
|
||||
// packages tells the System loader how to load when no filename and/or no extension
|
||||
packages: {
|
||||
app: {
|
||||
main: './main.js',
|
||||
defaultExtension: 'js'
|
||||
},
|
||||
rxjs: {
|
||||
defaultExtension: 'js'
|
||||
}
|
||||
}
|
||||
});
|
||||
})(this);
|
@ -1,405 +1,97 @@
|
||||
# Deployment
|
||||
|
||||
This page describes tools and techniques for deploy and optimize your Angular application.
|
||||
|
||||
|
||||
{@a toc}
|
||||
|
||||
{@a overview}
|
||||
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
This guide describes techniques for preparing and deploying an Angular application to a server running remotely.
|
||||
The techniques progress from _easy but suboptimal_ to _more optimal and more involved_.
|
||||
|
||||
* The [simple way](guide/deployment#dev-deploy "Simplest deployment possible") is to copy the development environment to the server.
|
||||
|
||||
* [_Ahead of Time_ compilation (AOT)](guide/deployment#aot "AOT Compilation") is the first of
|
||||
[several optimization strategies](guide/deployment#optimize).
|
||||
You'll also want to read the [detailed instructions in the AOT Cookbook](guide/aot-compiler "AOT Cookbook").
|
||||
|
||||
* [Webpack](guide/deployment#webpack "Webpack Optimization") is a popular general purpose packaging tool with a rich ecosystem, including plugins for AOT.
|
||||
The Angular [webpack guide](guide/webpack "Webpack: an introduction") can get you started and
|
||||
_this_ page provides additional optimization advice, but you'll probably have to learn more about webpack on your own.
|
||||
|
||||
* The [Angular configuration](guide/deployment#angular-configuration "Angular configuration") section calls attention to
|
||||
specific client application changes that could improve performance.
|
||||
|
||||
* The [Server configuration](guide/deployment#server-configuration "Server configuration") section describes
|
||||
server-side changes that may be necessary, _no matter how you deploy the application_.
|
||||
|
||||
|
||||
This page describes techniques for deploying your Angular application to a remote server.
|
||||
|
||||
{@a dev-deploy}
|
||||
|
||||
{@a copy-files}
|
||||
|
||||
## Simplest deployment possible
|
||||
|
||||
The simplest way to deploy the app is to publish it to a web server
|
||||
directly out of the development environment.
|
||||
For the simplest deployment, build for development and copy the output directory to a web server.
|
||||
|
||||
It's already running locally. You'll just copy it, almost _as is_,
|
||||
to a non-local server that others can reach.
|
||||
1. Start with the development build
|
||||
|
||||
1. Copy _everything_ (or [_almost_ everything](guide/deployment#node-modules "Loading npm packages from the web"))
|
||||
from the local project folder to a folder on the server.
|
||||
|
||||
1. If you're serving the app out of a subfolder,
|
||||
edit a version of `index.html` to set the `<base href>` appropriately.
|
||||
For example, if the URL to `index.html` is `www.mysite.com/my/app/`, set the _base href_ to
|
||||
`<base href="/my/app/">`.
|
||||
Otherwise, leave it alone.
|
||||
[More on this below](guide/deployment#base-tag).
|
||||
|
||||
1. Configure the server to redirect requests for missing files to `index.html`.
|
||||
[More on this below](guide/deployment#fallback).
|
||||
|
||||
1. Enable production mode as [described below](guide/deployment#enable-prod-mode) (optional).
|
||||
|
||||
That's the simplest deployment you can do.
|
||||
<code-example language="none" class="code-shell">
|
||||
ng build
|
||||
</code-example>
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
2. Copy _everything_ within the output folder (`dist/` by default) to a folder on the server.
|
||||
|
||||
|
||||
3. If you copy the files into a server _sub-folder_, append the build flag, `--base-href` and set the `<base href>` appropriately.<br><br>
|
||||
|
||||
For example, if the `index.html` is on the server at `/my/app/index.html`, set the _base href_ to
|
||||
`<base href="/my/app/">` like this.
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
ng build --base-href=/my/app/
|
||||
</code-example>
|
||||
|
||||
You'll see that the `<base href>` is set properly in the generated `dist/index.html`.<br><br>
|
||||
If you copy to the server's root directory, omit this step and leave the `<base href>` alone.<br><br>
|
||||
Learn more about the role of `<base href>` [below](guide/deployment#base-tag).
|
||||
|
||||
|
||||
4. Configure the server to redirect requests for missing files to `index.html`.
|
||||
Learn more about server-side redirects [below](guide/deployment#fallback).
|
||||
|
||||
|
||||
This is _not_ a production deployment. It's not optimized and it won't be fast for users.
|
||||
It might be good enough for sharing your progress and ideas internally with managers, teammates, and other stakeholders.
|
||||
Be sure to read about [optimizing for production](guide/deployment#optimize "Optimizing for production") below.
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a node-modules}
|
||||
|
||||
|
||||
### Load npm package files from the web (SystemJS)
|
||||
|
||||
The `node_modules` folder of _npm packages_ contains much more code
|
||||
than is needed to actually run your app in the browser.
|
||||
The `node_modules` for the Quickstart installation is typically 20,500+ files and 180+ MB.
|
||||
The application itself requires a tiny fraction of that to run.
|
||||
|
||||
It takes a long time to upload all of that useless bulk and
|
||||
users will wait unnecessarily while library files download piecemeal.
|
||||
|
||||
Load the few files you need from the web instead.
|
||||
|
||||
(1) Make a copy of `index.html` for deployment and replace all `node_module` scripts
|
||||
with versions that load from the web. It might look like this.
|
||||
|
||||
|
||||
<code-example path="deployment/src/index.html" region="node-module-scripts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
(2) Replace the `systemjs.config.js` script with a script that
|
||||
loads `systemjs.config.server.js`.
|
||||
|
||||
<code-example path="deployment/src/index.html" region="systemjs-config" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
(3) Add `systemjs.config.server.js` (shown in the code sample below) to the `src/` folder.
|
||||
This alternative version configures _SystemJS_ to load _UMD_ versions of Angular
|
||||
(and other third-party packages) from the web.
|
||||
|
||||
Modify `systemjs.config.server.js` as necessary to stay in sync with changes
|
||||
you make to `systemjs.config.js`.
|
||||
|
||||
Notice the `paths` key:
|
||||
|
||||
|
||||
<code-example path="deployment/src/systemjs.config.server.js" region="paths" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
In the standard SystemJS config, the `npm` path points to the `node_modules/`.
|
||||
In this server config, it points to
|
||||
<a href="https://unpkg.com/" title="unpkg.com">https://unpkg.com</a>,
|
||||
a site that hosts _npm packages_,
|
||||
and loads them from the web directly.
|
||||
There are other service providers that do the same thing.
|
||||
|
||||
If you are unwilling or unable to load packages from the open web,
|
||||
the inventory in `systemjs.config.server.js` identifies the files and folders that
|
||||
you would copy to a library folder on the server.
|
||||
Then change the config's `'npm'` path to point to that folder.
|
||||
|
||||
### Practice with an example
|
||||
|
||||
The following trivial router sample app shows these changes.
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="index.html" path="deployment/src/index.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="systemjs.config.server.js" path="deployment/src/systemjs.config.server.js">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="main.ts" path="deployment/src/main.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/app.module.ts" path="deployment/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/app.component.ts" path="deployment/src/app/app.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/crisis-list.component.ts" path="deployment/src/app/crisis-list.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/hero-list.component.ts" path="deployment/src/app/hero-list.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
Practice with this sample before attempting these techniques on your application.
|
||||
|
||||
1. Follow the [setup instructions](guide/setup "Angular QuickStart setup") for creating a new project
|
||||
named <code>simple-deployment</code>.
|
||||
|
||||
1. Add the "Simple deployment" sample files shown above.
|
||||
|
||||
1. Run it with `npm start` as you would any project.
|
||||
|
||||
1. Inspect the network traffic in the browser developer tools.
|
||||
Notice that it loads all packages from the web.
|
||||
You could delete the `node_modules` folder and the app would still run
|
||||
(although you wouldn't be able to recompile or launch `lite-server`
|
||||
until you restored it).
|
||||
|
||||
1. Deploy the sample to the server (minus the `node_modules` folder!).
|
||||
|
||||
When you have that working, try the same process on your application.
|
||||
|
||||
|
||||
{@a optimize}
|
||||
|
||||
|
||||
|
||||
## Optimize for production
|
||||
|
||||
Although deploying directly from the development environment works, it's far from optimal.
|
||||
Although deploying directly from the development environment works,
|
||||
you can generate an optimized build with additional CLI command line flags,
|
||||
starting with `--prod`.
|
||||
|
||||
The client makes many small requests for individual application code and template files,
|
||||
a fact you can quickly confirm by looking at the network tab in a browser's developer tools.
|
||||
Each small file download can spend more time communicating with the server than transferring data.
|
||||
### Build with _--prod_
|
||||
|
||||
Development files are full of comments and whitespace for easy reading and debugging.
|
||||
The browser downloads entire libraries, instead of just the parts the app needs.
|
||||
The volume of code passed from server to client (the "payload")
|
||||
can be significantly larger than is strictly necessary to execute the application.
|
||||
<code-example language="none" class="code-shell">
|
||||
ng build --prod
|
||||
</code-example>
|
||||
|
||||
The many requests and large payloads mean
|
||||
the app takes longer to launch than it would if you optimized it.
|
||||
Several seconds may pass (or worse) before the user can see or do anything useful.
|
||||
The `--prod` _meta-flag_ engages the following optimization features.
|
||||
|
||||
Does it matter? That depends upon business and technical factors you must evaluate for yourself.
|
||||
|
||||
If it _does_ matter, there are tools and techniques to reduce the number of requests and the size of responses.
|
||||
|
||||
* Ahead-of-Time (AOT) Compilation: pre-compiles Angular component templates.
|
||||
* Bundling: concatenates modules into a single file (bundle).
|
||||
* Inlining: pulls template html and css into the components.
|
||||
* [Ahead-of-Time (AOT) Compilation](guide/aot-compiler): pre-compiles Angular component templates.
|
||||
* [Production mode](#enable-prod-mode): deploys the production environment which enables _production mode_.
|
||||
* Bundling: concatenates your many application and library files into a few bundles.
|
||||
* Minification: removes excess whitespace, comments, and optional tokens.
|
||||
* Uglification: rewrites code to use short, cryptic variable and function names.
|
||||
* Dead code elimination: removes unreferenced modules and unused code.
|
||||
* Pruned libraries: drop unused libraries and pare others down to the features you need.
|
||||
* Performance measurement: focus on optimizations that make a measurable difference.
|
||||
* Dead code elimination: removes unreferenced modules and much unused code.
|
||||
|
||||
Each tool does something different.
|
||||
They work best in combination and are mutually reinforcing.
|
||||
The remaining [copy deployment steps](#copy-files) are the same as before.
|
||||
|
||||
You can use any build system you like.
|
||||
Whatever system you choose, be sure to automate it so that
|
||||
building for production is a single step.
|
||||
You may further reduce bundle sizes by adding the `build-optimizer` flag.
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
ng build --prod --build-optimizer
|
||||
</code-example>
|
||||
|
||||
{@a aot}
|
||||
|
||||
|
||||
### Ahead-of-Time (AOT) compilation
|
||||
|
||||
The Angular _Ahead-of-Time_ compiler pre-compiles application components and their templates
|
||||
during the build process.
|
||||
|
||||
Apps compiled with AOT launch faster for several reasons.
|
||||
|
||||
* Application components execute immediately, without client-side compilation.
|
||||
* Templates are embedded as code within their components so there is no client-side request for template files.
|
||||
* You don't download the Angular compiler, which is pretty big on its own.
|
||||
* The compiler discards unused Angular directives that a tree-shaking tool can then exclude.
|
||||
|
||||
Learn more about AOT Compilation in the [AOT Cookbook](guide/aot-compiler "AOT Cookbook")
|
||||
which describes running the AOT compiler from the command line
|
||||
and using [_rollup_](guide/deployment#rollup) for bundling, minification, uglification and tree shaking.
|
||||
|
||||
|
||||
{@a webpack}
|
||||
|
||||
|
||||
### Webpack (and AOT)
|
||||
|
||||
<a href="https://webpack.js.org/" title="Webpack 2">Webpack 2</a> is another
|
||||
great option for inlining templates and style-sheets, for bundling, minifying, and uglifying the application.
|
||||
The "[Webpack: an introduction](guide/webpack "Webpack: an introduction")" guide will get you started
|
||||
using webpack with Angular.
|
||||
|
||||
Consider configuring _Webpack_ with the official
|
||||
<a href="https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack" title="Ahead-of-Time Webpack Plugin">
|
||||
Angular Ahead-of-Time Webpack Plugin</a>.
|
||||
This plugin transpiles the TypeScript application code,
|
||||
bundles lazy loaded `NgModules` separately,
|
||||
and performs AOT compilation — without any changes to the source code.
|
||||
|
||||
|
||||
{@a rollup}
|
||||
|
||||
|
||||
### Dead code elimination with _rollup_
|
||||
|
||||
Any code that you don't call is _dead code_.
|
||||
You can reduce the total size of the application substantially by removing dead code from the application and from third-party libraries.
|
||||
|
||||
_Tree shaking_ is a _dead code elimination_ technique that removes entire exports from JavaScript modules.
|
||||
If a library exports something that the application doesn't import, a tree shaking tool removes it from the code base.
|
||||
|
||||
Tree shaking was popularized by
|
||||
<a href="http://rollupjs.org/" title="Rollup">Rollup</a>, a popular tool with an ecosystem of
|
||||
plugins for bundling, minification, and uglification.
|
||||
Learn more about tree shaking and dead code elimination in
|
||||
<a href="https://medium.com/@Rich_Harris/tree-shaking-versus-dead-code-elimination-d3765df85c80#.15ih9cyvl" title="Tree-shaking and Dead Code Elimination">
|
||||
this post</a> by rollup-creator, Rich Harris.
|
||||
|
||||
|
||||
{@a prune}
|
||||
|
||||
|
||||
### Pruned libraries
|
||||
|
||||
Don't count on automation to remove all dead code.
|
||||
|
||||
Remove libraries that you don't use, especially unnecessary scripts in `index.html`.
|
||||
Consider smaller alternatives to the libraries that you do use.
|
||||
|
||||
Some libraries offer facilities for building a custom, skinny version with just the features you need.
|
||||
Other libraries let you import features _a la carte_.
|
||||
**RxJS** is a good example; import RxJS `Observable` operators individually instead of the entire library.
|
||||
|
||||
|
||||
{@a measure}
|
||||
|
||||
|
||||
### Measure performance first
|
||||
|
||||
You can make better decisions about what to optimize and how when you have a clear and accurate understanding of
|
||||
what's making the application slow.
|
||||
The cause may not be what you think it is.
|
||||
You can waste a lot of time and money optimizing something that has no tangible benefit or even makes the app slower.
|
||||
You should measure the app's actual behavior when running in the environments that are important to you.
|
||||
|
||||
The
|
||||
<a href="https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing" title="Chrome DevTools Network Performance">
|
||||
Chrome DevTools Network Performance page</a> is a good place to start learning about measuring performance.
|
||||
|
||||
The [WebPageTest](https://www.webpagetest.org/) tool is another good choice
|
||||
that can also help verify that your deployment was successful.
|
||||
|
||||
|
||||
{@a angular-configuration}
|
||||
|
||||
|
||||
|
||||
## Angular configuration
|
||||
|
||||
Angular configuration can make the difference between whether the app launches quickly or doesn't load at all.
|
||||
|
||||
|
||||
{@a base-tag}
|
||||
|
||||
|
||||
### The `base` tag
|
||||
|
||||
The HTML [_<base href="..."/>_](/guide/router)
|
||||
specifies a base path for resolving relative URLs to assets such as images, scripts, and style sheets.
|
||||
For example, given the `<base href="/my/app/">`, the browser resolves a URL such as `some/place/foo.jpg`
|
||||
into a server request for `my/app/some/place/foo.jpg`.
|
||||
During navigation, the Angular router uses the _base href_ as the base path to component, template, and module files.
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
See also the [*APP_BASE_HREF*](api/common/APP_BASE_HREF "API: APP_BASE_HREF") alternative.
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
In development, you typically start the server in the folder that holds `index.html`.
|
||||
That's the root folder and you'd add `<base href="/">` near the top of `index.html` because `/` is the root of the app.
|
||||
|
||||
But on the shared or production server, you might serve the app from a subfolder.
|
||||
For example, when the URL to load the app is something like `http://www.mysite.com/my/app/`,
|
||||
the subfolder is `my/app/` and you should add `<base href="/my/app/">` to the server version of the `index.html`.
|
||||
|
||||
When the `base` tag is misconfigured, the app fails to load and the browser console displays `404 - Not Found` errors
|
||||
for the missing files. Look at where it _tried_ to find those files and adjust the base tag appropriately.
|
||||
|
||||
See the [CLI Documentation](https://github.com/angular/angular-cli/wiki/build)
|
||||
for details about available build options and what they do.
|
||||
|
||||
{@a enable-prod-mode}
|
||||
|
||||
|
||||
### Enable production mode
|
||||
|
||||
Angular apps run in development mode by default, as you can see by the following message on the browser
|
||||
console:
|
||||
|
||||
|
||||
<code-example format="nocode">
|
||||
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
|
||||
</code-example>
|
||||
|
||||
Switching to _production mode_ can make it run faster by disabling development specific checks such as the dual change detection cycles.
|
||||
|
||||
|
||||
Switching to production mode can make it run faster by disabling development specific checks such as the dual change detection cycles.
|
||||
|
||||
To enable [production mode](api/core/enableProdMode) when running remotely, add the following code to the `main.ts`.
|
||||
|
||||
|
||||
<code-example path="deployment/src/main.ts" region="enableProdMode" title="src/main.ts (enableProdMode)" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
Building for production (or appending the `--environment=prod` flag) enables _production mode_
|
||||
Look at the CLI-generated `main.ts` to see how this works.
|
||||
|
||||
{@a lazy-loading}
|
||||
|
||||
|
||||
### Lazy loading
|
||||
|
||||
You can dramatically reduce launch time by only loading the application modules that
|
||||
@ -423,24 +115,133 @@ Because lazy loaded modules aren't imported in JavaScript (as just noted), bundl
|
||||
Bundlers don't know about the router configuration and won't create separate bundles for lazy loaded modules.
|
||||
You have to create these bundles manually.
|
||||
|
||||
The
|
||||
The CLI runs the
|
||||
[Angular Ahead-of-Time Webpack Plugin](https://github.com/angular/angular-cli/tree/master/packages/%40ngtools/webpack)
|
||||
automatically recognizes lazy loaded `NgModules` and creates separate bundles for them.
|
||||
which automatically recognizes lazy loaded `NgModules` and creates separate bundles for them.
|
||||
|
||||
{@a measure}
|
||||
|
||||
### Measure performance
|
||||
|
||||
You can make better decisions about what to optimize and how when you have a clear and accurate understanding of
|
||||
what's making the application slow.
|
||||
The cause may not be what you think it is.
|
||||
You can waste a lot of time and money optimizing something that has no tangible benefit or even makes the app slower.
|
||||
You should measure the app's actual behavior when running in the environments that are important to you.
|
||||
|
||||
The
|
||||
<a href="https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing" title="Chrome DevTools Network Performance">
|
||||
Chrome DevTools Network Performance page</a> is a good place to start learning about measuring performance.
|
||||
|
||||
The [WebPageTest](https://www.webpagetest.org/) tool is another good choice
|
||||
that can also help verify that your deployment was successful.
|
||||
|
||||
{@a inspect-bundle}
|
||||
|
||||
### Inspect the bundles
|
||||
|
||||
The <a href="https://github.com/danvk/source-map-explorer/blob/master/README.md">source-map-explorer</a>
|
||||
tool is a great way to inspect the generated JavaScript bundles after a production build.
|
||||
|
||||
Install `source-map-explorer`:
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
npm install source-map-explorer --save-dev
|
||||
</code-example>
|
||||
|
||||
Build your app for production _including the source maps_
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
ng build --prod --sourcemaps
|
||||
</code-example>
|
||||
|
||||
List the generated bundles in the `dist/` folder.
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
ls dist/*.bundle.js
|
||||
</code-example>
|
||||
|
||||
Run the explorer to generate a graphical representation of one of the bundles.
|
||||
The following example displays the graph for the _main_ bundle.
|
||||
|
||||
<code-example language="none" class="code-shell">
|
||||
node_modules/.bin/source-map-explorer dist/main.*.bundle.js
|
||||
</code-example>
|
||||
|
||||
The `source-map-explorer` analyzes the source map generated with the bundle and draws a map of all dependencies,
|
||||
showing exactly which classes are included in the bundle.
|
||||
|
||||
Here's the output for the _main_ bundle of the QuickStart.
|
||||
|
||||
<figure>
|
||||
<img src="generated/images/guide/cli-quickstart/quickstart-sourcemap-explorer.png" alt="quickstart sourcemap explorer">
|
||||
</figure>
|
||||
|
||||
{@a base-tag}
|
||||
|
||||
## The `base` tag
|
||||
|
||||
The HTML [_<base href="..."/>_](/guide/router)
|
||||
specifies a base path for resolving relative URLs to assets such as images, scripts, and style sheets.
|
||||
For example, given the `<base href="/my/app/">`, the browser resolves a URL such as `some/place/foo.jpg`
|
||||
into a server request for `my/app/some/place/foo.jpg`.
|
||||
During navigation, the Angular router uses the _base href_ as the base path to component, template, and module files.
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
See also the [*APP_BASE_HREF*](api/common/APP_BASE_HREF "API: APP_BASE_HREF") alternative.
|
||||
|
||||
</div>
|
||||
|
||||
In development, you typically start the server in the folder that holds `index.html`.
|
||||
That's the root folder and you'd add `<base href="/">` near the top of `index.html` because `/` is the root of the app.
|
||||
|
||||
But on the shared or production server, you might serve the app from a subfolder.
|
||||
For example, when the URL to load the app is something like `http://www.mysite.com/my/app/`,
|
||||
the subfolder is `my/app/` and you should add `<base href="/my/app/">` to the server version of the `index.html`.
|
||||
|
||||
When the `base` tag is mis-configured, the app fails to load and the browser console displays `404 - Not Found` errors
|
||||
for the missing files. Look at where it _tried_ to find those files and adjust the base tag appropriately.
|
||||
|
||||
## _build_ vs. _serve_
|
||||
|
||||
You'll probably prefer `ng build` for deployments.
|
||||
|
||||
The **ng build** command is intended for building the app and deploying the build artifacts elsewhere.
|
||||
The **ng serve** command is intended for fast, local, iterative development.
|
||||
|
||||
Both `ng build` and `ng serve` **clear the output folder** before they build the project.
|
||||
The `ng build` command writes generated build artifacts to the output folder.
|
||||
The `ng serve` command does not.
|
||||
It serves build artifacts from memory instead for a faster development experience.
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
The output folder is `dist/` by default.
|
||||
To output to a different folder, change the `outDir` in `.angular-cli.json`.
|
||||
|
||||
</div>
|
||||
|
||||
The `ng serve` command builds, watches, and serves the application from a local CLI development server.
|
||||
|
||||
The `ng build` command generates output files just once and does not serve them.
|
||||
The `ng build --watch` command will regenerate output files when source files change.
|
||||
This `--watch` flag is useful if you're building during development and
|
||||
are automatically re-deploying changes to another server.
|
||||
|
||||
|
||||
See the [CLI `build` topic](https://github.com/angular/angular-cli/wiki/build) for more details and options.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a server-configuration}
|
||||
|
||||
|
||||
|
||||
## Server configuration
|
||||
|
||||
This section covers changes you may have make to the server or to files deployed to the server.
|
||||
|
||||
|
||||
{@a fallback}
|
||||
|
||||
|
||||
### Routed apps must fallback to `index.html`
|
||||
|
||||
Angular apps are perfect candidates for serving with a simple static HTML server.
|
||||
@ -450,7 +251,6 @@ Angular does that on the client-side.
|
||||
If the app uses the Angular router, you must configure the server
|
||||
to return the application's host page (`index.html`) when asked for a file that it does not have.
|
||||
|
||||
|
||||
{@a deep-link}
|
||||
|
||||
|
||||
@ -482,75 +282,65 @@ The list is by no means exhaustive, but should provide you with a good starting
|
||||
* [Lite-Server](https://github.com/johnpapa/lite-server): the default dev server installed with the
|
||||
[Quickstart repo](https://github.com/angular/quickstart) is pre-configured to fallback to `index.html`.
|
||||
|
||||
|
||||
* [Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server): setup the
|
||||
`historyApiFallback` entry in the dev server options as follows:
|
||||
|
||||
|
||||
<code-example>
|
||||
historyApiFallback: {
|
||||
disableDotRule: true,
|
||||
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
<code-example>
|
||||
historyApiFallback: {
|
||||
disableDotRule: true,
|
||||
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
|
||||
}
|
||||
</code-example>
|
||||
|
||||
|
||||
#### Production servers
|
||||
|
||||
* [Apache](https://httpd.apache.org/): add a
|
||||
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html)
|
||||
to the `.htaccess` file as show
|
||||
[here](https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
|
||||
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
|
||||
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
|
||||
|
||||
<code-example format=".">
|
||||
RewriteEngine On
|
||||
# If an existing asset or directory is requested go to it as it is
|
||||
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
|
||||
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
|
||||
RewriteRule ^ - [L]
|
||||
|
||||
<code-example format=".">
|
||||
RewriteEngine On
|
||||
# If an existing asset or directory is requested go to it as it is
|
||||
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
|
||||
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
|
||||
RewriteRule ^ - [L]
|
||||
|
||||
# If the requested resource doesn't exist, use index.html
|
||||
RewriteRule ^ /index.html
|
||||
|
||||
</code-example>
|
||||
|
||||
# If the requested resource doesn't exist, use index.html
|
||||
RewriteRule ^ /index.html
|
||||
</code-example>
|
||||
|
||||
|
||||
* [NGinx](http://nginx.org/): use `try_files`, as described in
|
||||
[Front Controller Pattern Web Apps](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#front-controller-pattern-web-apps),
|
||||
modified to serve `index.html`:
|
||||
|
||||
|
||||
<code-example format=".">
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
</code-example>
|
||||
|
||||
<code-example format=".">
|
||||
try_files $uri $uri/ /index.html;
|
||||
</code-example>
|
||||
|
||||
|
||||
* [IIS](https://www.iis.net/): add a rewrite rule to `web.config`, similar to the one shown
|
||||
[here](http://stackoverflow.com/a/26152011/2116927):
|
||||
|
||||
<code-example format='.'>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="Angular Routes" stopProcessing="true">
|
||||
<match url=".*" />
|
||||
<conditions logicalGrouping="MatchAll">
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
|
||||
</conditions>
|
||||
<action type="Rewrite" url="/src/" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
</system.webServer>
|
||||
|
||||
</code-example>
|
||||
<code-example format='.'>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="Angular Routes" stopProcessing="true">
|
||||
<match url=".*" />
|
||||
<conditions logicalGrouping="MatchAll">
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
|
||||
</conditions>
|
||||
<action type="Rewrite" url="/src/" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
</system.webServer>
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
* [GitHub Pages](https://pages.github.com/): you can't
|
||||
@ -563,24 +353,20 @@ It's also a good idea to
|
||||
and to
|
||||
[create a `.nojekyll` file](https://www.bennadel.com/blog/3181-including-node-modules-and-vendors-folders-in-your-github-pages-site.htm)
|
||||
|
||||
|
||||
* [Firebase hosting](https://firebase.google.com/docs/hosting/): add a
|
||||
[rewrite rule](https://firebase.google.com/docs/hosting/url-redirects-rewrites#section-rewrites).
|
||||
|
||||
<code-example format=".">
|
||||
"rewrites": [ {
|
||||
"source": "**",
|
||||
"destination": "/index.html"
|
||||
} ]
|
||||
|
||||
<code-example format=".">
|
||||
"rewrites": [ {
|
||||
"source": "**",
|
||||
"destination": "/index.html"
|
||||
} ]
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
</code-example>
|
||||
|
||||
{@a cors}
|
||||
|
||||
|
||||
|
||||
### Requesting services from a different server (CORS)
|
||||
|
||||
Angular developers may encounter a
|
||||
@ -593,12 +379,3 @@ There isn't anything the client application can do about these errors.
|
||||
The server must be configured to accept the application's requests.
|
||||
Read about how to enable CORS for specific servers at
|
||||
<a href="http://enable-cors.org/server.html" title="Enabling CORS server">enable-cors.org</a>.
|
||||
|
||||
|
||||
{@a next-steps}
|
||||
|
||||
|
||||
|
||||
## Next steps
|
||||
If you want to go beyond the [simple _copy-deploy_](guide/deployment#dev-deploy "Simplest deployment possible") approach,
|
||||
read the [AOT Cookbook](guide/aot-compiler "AOT Cookbook") next.
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
x
Reference in New Issue
Block a user