17 KiB
Deployment
When you are ready to deploy your Angular application to a remote server, you have various options for deployment.
{@a dev-deploy} {@a copy-files}
Simplest deployment possible
For the simplest deployment, build for development and copy the output directory to a web server.
- Start with the development build:
-
Copy everything within the output folder (
dist/
by default) to a folder on the server. -
Configure the server to redirect requests for missing files to
index.html
. Learn more about server-side redirects below.
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. For the next steps in deployment, see Optimize for production.
{@a deploy-to-github}
Deploy to GitHub pages
Another simple way to deploy your Angular app is to use GitHub Pages.
-
You need to create a GitHub account if you don't have one, and then create a repository for your project. Make a note of the user name and project name in GitHub.
-
Build your project using Github project name, with the Angular CLI command
ng build
and the options shown here: ng build --prod --output-path docs --base-href <project_name> -
When the build is complete, make a copy of
docs/index.html
and name itdocs/404.html
. -
Commit your changes and push.
-
On the GitHub project page, configure it to publish from the docs folder.
You can see your deployed page at https://<user_name>.github.io/<project_name>/
.
{@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. You don't need a server-side engine to dynamically compose application pages because 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}
A routed application should support "deep links".
A deep link is a URL that specifies a path to a component inside the app.
For example, http://www.mysite.com/heroes/42
is a deep link to the hero detail page
that displays the hero with id: 42
.
There is no issue when the user navigates to that URL from within a running client. The Angular router interprets the URL and routes to that page and hero.
But clicking a link in an email, entering it in the browser address bar, or merely refreshing the browser while on the hero detail page — all of these actions are handled by the browser itself, outside the running application. The browser makes a direct request to the server for that URL, bypassing the router.
A static server routinely returns index.html
when it receives a request for http://www.mysite.com/
.
But it rejects http://www.mysite.com/heroes/42
and returns a 404 - Not Found
error unless it is
configured to return index.html
instead.
Fallback configuration examples
There is no single configuration that works for every server. The following sections describe configurations for some of the most popular servers. The list is by no means exhaustive, but should provide you with a good starting point.
Development servers
During development, the ng serve
CLI command lets you run your app in a local browser.
The CLI recompiles the application each time you save a file,
and reloads the browser with the newly compiled application.
The app is hosted in local memory and served on http://localhost:4200/
, using webpack-dev-server.
{@a serve-from-disk}
Later in development, you might want a closer approximation of how your app will behave when deployed.
You can output your distribution folder (dist
) to disk, but you need to install a different web server.
Try installing lite-server; like webpack-dev-server
, it can automatically reload your browser when you write new files.
To get the live-reload experience, you will need to run two terminals.
The first runs the build in a watch mode and compiles the application to the dist
folder.
The second runs the web server against the dist
folder.
The combination of these two processes provides the same behavior as ng serve
.
-
Start the build in terminal A: ng build --watch
-
Start the web server in terminal B: lite-server --baseDir="dist" The default browser opens to the appropriate URL.
-
Lite-Server: the default dev server installed with the Quickstart repo is pre-configured to fallback to
index.html
. -
Webpack-Dev-Server: setup the
historyApiFallback: { disableDotRule: true, htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'] }historyApiFallback
entry in the dev server options as follows:
Production servers
-
Apache: add a rewrite rule to the
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].htaccess
file as shown (https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):# If the requested resource doesn't exist, use index.html RewriteRule ^ /index.html
-
Nginx: use
try_files $uri $uri/ /index.html;try_files
, as described in Front Controller Pattern Web Apps, modified to serveindex.html
: -
IIS: add a rewrite rule to
<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="/index.html" /> </rule> </rules> </rewrite> </system.webServer>web.config
, similar to the one shown here: -
GitHub Pages: you can't directly configure the GitHub Pages server, but you can add a 404 page. Copy
index.html
into404.html
. It will still be served as the 404 response, but the browser will process that page and load the app properly. It's also a good idea to serve fromdocs/
on master and to create a.nojekyll
file -
Firebase hosting: add a rewrite rule.
"rewrites": [ { "source": "**", "destination": "/index.html" } ]
{@a cors}
Requesting services from a different server (CORS)
Angular developers may encounter a cross-origin resource sharing error when making a service request (typically a data service request) to a server other than the application's own host server. Browsers forbid such requests unless the server permits them explicitly.
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 enable-cors.org.
{@a optimize}
Optimize for production
Although deploying directly from the development environment works,
you can generate an optimized build with additional CLI command line flags,
starting with --prod
.
Build with --prod
ng build --prodThe --prod
meta-flag engages the following optimization features.
- Ahead-of-Time (AOT) Compilation: pre-compiles Angular component templates.
- Production 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 much unused code.
The remaining copy deployment steps are the same as before.
See ng build
for more about CLI 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:
Angular is running in the development mode. Call enableProdMode() to enable the production mode.Switching to production mode can make it run faster by disabling development specific checks such as the dual change detection cycles.
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 absolutely must be present when the app starts.
Configure the Angular Router to defer loading of all other modules (and their associated code), either by waiting until the app has launched or by lazy loading them on demand.
If you mean to lazy-load a module, be careful not import it
in a file that's eagerly loaded when the app starts (such as the root AppModule
).
If you do that, the module will be loaded immediately.
The bundling configuration must take lazy loading into consideration. Because lazy-loaded modules aren't imported in JavaScript, bundlers exclude them by default. Bundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules. You would have to create these bundles manually.
The CLI runs the
Angular Ahead-of-Time Webpack Plugin
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 Chrome DevTools Network Performance page is a good place to start learning about measuring performance.
The WebPageTest tool is another good choice that can also help verify that your deployment was successful.
{@a inspect-bundle}
Inspect the bundles
The source-map-explorer tool is a great way to inspect the generated JavaScript bundles after a production build.
Install source-map-explorer
:
Build your app for production including the source maps
ng build --prod --source-mapList the generated bundles in the dist/
folder.
Run the explorer to generate a graphical representation of one of the bundles. The following example displays the graph for the main bundle.
node_modules/.bin/source-map-explorer dist/main.*.bundle.jsThe 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.
{@a base-tag}
The base
tag
The HTML <base href="..."/>
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.
See also the APP_BASE_HREF alternative.
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.
Building and serving for deployment
When you are designing and developing applications, you typically use ng serve
to build your app for fast, local, iterative development.
When you are ready to deploy, however, you must use the ng build
command to build the app and deploy the build artifacts elsewhere.
Both ng build
and ng serve
clear the output folder before they build the project, but only the ng build
command writes the generated build artifacts to the output folder.
The output folder is dist/
by default.
To output to a different folder, change the outputPath
in angular.json
.
The ng serve
command builds, watches, and serves the application from local memory, using a local development server.
When you have deployed your app to another server, however, you might still want to serve the app so that you can continue to see changes that you make in it.
You can do this by adding the --watch
option to the ng build
command.
ng build --watch
Like the ng serve
command, this regenerates output files when source files change.
For complete details of the CLI commands, see the CLI command reference.