{ "id": "guide/deployment", "title": "Deployment", "contents": "\n\n\n
\n mode_edit\n
\n\n\n
\n

Deploymentlink

\n

When you are ready to deploy your Angular application to a remote server, you have various options for deployment.

\n\n\n

Simple deployment optionslink

\n

Before fully deploying your application, you can test the process, build configuration, and deployed behavior by using one of these interim techniques.

\n

Building and serving from disklink

\n

During development, you typically use the ng serve command to build, watch, and serve the application from local memory, using webpack-dev-server.\nWhen you are ready to deploy, however, you must use the ng build command to build the app and deploy the build artifacts elsewhere.

\n

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.

\n
\n

The output folder is dist/project-name/ by default.\nTo output to a different folder, change the outputPath in angular.json.

\n
\n

As you near the end of the development process, serving the contents of your output folder from a local web server can give you a better idea of how your application will behave when it is deployed to a remote server.\nYou will need two terminals to get the live-reload experience.

\n\n
\n

This method is for development and testing only, and is not a supported or secure way of deploying an application.

\n
\n

Automatic deployment with the CLIlink

\n

The Angular CLI command ng deploy (introduced in version 8.3.0) executes the deploy CLI builder associated with your project. A number of third-party builders implement deployment capabilities to different platforms. You can add any of them to your project by running ng add [package name].

\n

When you add a package with deployment capability, it'll automatically update your workspace configuration (angular.json file) with a deploy section for the selected project. You can then use the ng deploy command to deploy that project.

\n

For example, the following command automatically deploys a project to Firebase.

\n\nng add @angular/fire\nng deploy\n\n

The command is interactive. In this case, you must have or create a Firebase account, and authenticate using that account. The command prompts you to select a Firebase project for deployment

\n

The command builds your application and uploads the production assets to Firebase.

\n

In the table below, you can find a list of packages which implement deployment functionality to different platforms. The deploy command for each package may require different command line options. You can read more by following the links associated with the package names below:

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Deployment toPackage
Firebase hosting@angular/fire
Azure@azure/ng-deploy
Now@zeit/ng-deploy
Netlify@netlify-builder/deploy
GitHub pagesangular-cli-ghpages
NPMngx-deploy-npm
Amazon Cloud S3@jefiozie/ngx-aws-deploy
\n

If you're deploying to a self-managed server or there's no builder for your favorite cloud platform, you can either create a builder that allows you to use the ng deploy command, or read through this guide to learn how to manually deploy your app.

\n

Basic deployment to a remote serverlink

\n

For the simplest deployment, create a production build and copy the output directory to a web server.

\n
    \n
  1. \n

    Start with the production build:

    \n\n\n ng build\n\n\n
  2. \n
\n
    \n
  1. \n

    Copy everything within the output folder (dist/project-name/ by default) to a folder on the server.

    \n
  2. \n
  3. \n

    Configure the server to redirect requests for missing files to index.html.\nLearn more about server-side redirects below.

    \n
  4. \n
\n

This is the simplest production-ready deployment of your application.

\n\n

Deploy to GitHub Pageslink

\n

To deploy your Angular application to GitHub Pages, complete the following steps:

\n
    \n
  1. \n

    Create a GitHub repository for your project.

    \n
  2. \n
  3. \n

    Configure git in your local project by adding a remote that specifies the GitHub repo you created in previous step.\nGitHub provides these commands when you create the repo so that you can copy and paste them at your command prompt.\nThe commands should be similar to the following, though GitHub fills in your project-specific settings for you:

    \n\ngit remote add origin https://github.com/your-username/your-project-name.git\ngit branch -M main\ngit push -u origin main\n\n

    When you paste these commands from GitHub, they run automatically.

    \n
  4. \n
  5. \n

    Create and check out a git branch named gh-pages.

    \n\ngit checkout -b gh-pages\n\n
  6. \n
  7. \n

    Build your project using the Github project name, with the Angular CLI command ng build and the following options, where your_project_name is the name of the project that you gave the GitHub repository in step 1.

    \n

    Be sure to include the slashes on either side of your project name as in /your_project_name/.

    \n\n\n ng build --output-path docs --base-href /your_project_name/\n\n\n
  8. \n
  9. \n

    When the build is complete, make a copy of docs/index.html and name it docs/404.html.

    \n
  10. \n
  11. \n

    Commit your changes and push.

    \n
  12. \n
  13. \n

    On the GitHub project page, go to Settings and scroll down to the GitHub Pages section to configure the site to publish from the docs folder.

    \n
  14. \n
  15. \n

    Click Save.

    \n
  16. \n
  17. \n

    Click on the GitHub Pages link at the top of the GitHub Pages section to see your deployed application.\nThe format of the link is https://<user_name>.github.io/<project_name>/.

    \n
  18. \n
\n
\n

Check out angular-cli-ghpages, a full featured package that does all this for you and has extra functionality.

\n
\n\n

Server configurationlink

\n

This section covers changes you may have to make to the server or to files deployed on the server.

\n\n

Routed apps must fallback to index.htmllink

\n

Angular apps are perfect candidates for serving with a simple static HTML server.\nYou don't need a server-side engine to dynamically compose application pages because\nAngular does that on the client-side.

\n

If the app uses the Angular router, you must configure the server\nto return the application's host page (index.html) when asked for a file that it does not have.

\n\n

A routed application should support \"deep links\".\nA deep link is a URL that specifies a path to a component inside the app.\nFor example, http://www.mysite.com/heroes/42 is a deep link to the hero detail page\nthat displays the hero with id: 42.

\n

There is no issue when the user navigates to that URL from within a running client.\nThe Angular router interprets the URL and routes to that page and hero.

\n

But clicking a link in an email, entering it in the browser address bar,\nor merely refreshing the browser while on the hero detail page —\nall of these actions are handled by the browser itself, outside the running application.\nThe browser makes a direct request to the server for that URL, bypassing the router.

\n

A static server routinely returns index.html when it receives a request for http://www.mysite.com/.\nBut it rejects http://www.mysite.com/heroes/42 and returns a 404 - Not Found error unless it is\nconfigured to return index.html instead.

\n

Fallback configuration exampleslink

\n

There is no single configuration that works for every server.\nThe following sections describe configurations for some of the most popular servers.\nThe list is by no means exhaustive, but should provide you with a good starting point.

\n\n\n\n\n\n\n

Requesting services from a different server (CORS)link

\n

Angular developers may encounter a\n\ncross-origin resource sharing error when making a service request (typically a data service request)\nto a server other than the application's own host server.\nBrowsers forbid such requests unless the server permits them explicitly.

\n

There isn't anything the client application can do about these errors.\nThe server must be configured to accept the application's requests.\nRead about how to enable CORS for specific servers at\nenable-cors.org.

\n\n

Production optimizationslink

\n

The production configuration engages the following build optimization features.

\n\n

See ng build for more about CLI build options and what they do.

\n\n

Enable runtime production modelink

\n

In addition to build optimizations, Angular also has a runtime production mode. Angular apps run in development mode by default, as you can see by the following message on the browser console:

\n\n\n Angular is running in development mode. Call enableProdMode() to enable production mode.\n\n\n

Production mode improves application performance by disabling development-only safety\nchecks and debugging utilities, such as the expression-changed-after-checked detection.\nBuilding your application with the production configuration automatically enables Angular's\nruntime production mode.

\n\n

Lazy loadinglink

\n

You can dramatically reduce launch time by only loading the application modules that\nabsolutely must be present when the app starts.

\n

Configure the Angular Router to defer loading of all other modules (and their associated code), either by\nwaiting until the app has launched\nor by lazy loading\nthem on demand.

\n
\n
Don't eagerly import something from a lazy-loaded module
\n

If you mean to lazy-load a module, be careful not to import it\nin a file that's eagerly loaded when the app starts (such as the root AppModule).\nIf you do that, the module will be loaded immediately.

\n

The bundling configuration must take lazy loading into consideration.\nBecause lazy-loaded modules aren't imported in JavaScript, bundlers exclude them by default.\nBundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules.\nYou would have to create these bundles manually.

\n

The CLI runs the\nAngular Ahead-of-Time Webpack Plugin\nwhich automatically recognizes lazy-loaded NgModules and creates separate bundles for them.

\n
\n\n

Measure performancelink

\n

You can make better decisions about what to optimize and how when you have a clear and accurate understanding of\nwhat's making the application slow.\nThe cause may not be what you think it is.\nYou can waste a lot of time and money optimizing something that has no tangible benefit or even makes the app slower.\nYou should measure the app's actual behavior when running in the environments that are important to you.

\n

The\n\nChrome DevTools Network Performance page is a good place to start learning about measuring performance.

\n

The WebPageTest tool is another good choice\nthat can also help verify that your deployment was successful.

\n\n

Inspect the bundleslink

\n

The source-map-explorer\ntool is a great way to inspect the generated JavaScript bundles after a production build.

\n

Install source-map-explorer:

\n\n\n npm install source-map-explorer --save-dev\n\n\n

Build your app for production including the source maps

\n\n\n ng build --source-map\n\n\n

List the generated bundles in the dist/project-name/ folder.

\n\n\n ls dist/project-name/*.js\n\n\n

Run the explorer to generate a graphical representation of one of the bundles.\nThe following example displays the graph for the main bundle.

\n\n\n node_modules/.bin/source-map-explorer dist/project-name/main*\n\n\n

The source-map-explorer analyzes the source map generated with the bundle and draws a map of all dependencies,\nshowing exactly which classes are included in the bundle.

\n

Here's the output for the main bundle of an example app called cli-quickstart.

\n
\n \"quickstart\n
\n\n

The base taglink

\n

The HTML <base href=\"...\"/>\nspecifies a base path for resolving relative URLs to assets such as images, scripts, and style sheets.\nFor example, given the <base href=\"/my/app/\">, the browser resolves a URL such as some/place/foo.jpg\ninto a server request for my/app/some/place/foo.jpg.\nDuring navigation, the Angular router uses the base href as the base path to component, template, and module files.

\n
\n

See also the APP_BASE_HREF alternative.

\n
\n

In development, you typically start the server in the folder that holds index.html.\nThat's the root folder and you'd add <base href=\"/\"> near the top of index.html because / is the root of the app.

\n

But on the shared or production server, you might serve the app from a subfolder.\nFor example, when the URL to load the app is something like http://www.mysite.com/my/app/,\nthe subfolder is my/app/ and you should add <base href=\"/my/app/\"> to the server version of the index.html.

\n

When the base tag is mis-configured, the app fails to load and the browser console displays 404 - Not Found errors\nfor the missing files. Look at where it tried to find those files and adjust the base tag appropriately.

\n\n

Differential Loadinglink

\n

When building web applications, you want to make sure your application is compatible with the majority of browsers.\nEven as JavaScript continues to evolve, with new features being introduced, not all browsers are updated with support for these new features at the same pace.

\n

The code you write in development using TypeScript is compiled and bundled into ES2015, the JavaScript syntax that is compatible with most browsers.\nAll modern browsers support ES2015 and beyond, but in most cases, you still have to account for users accessing your application from a browser that doesn't.\nWhen targeting older browsers, polyfills can bridge the gap by providing functionality that doesn't exist in the older versions of JavaScript supported by those browsers.

\n

To maximize compatibility, you could ship a single bundle that includes all your compiled code, plus any polyfills that may be needed.\nUsers with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.\nDifferential loading, which is supported in Angular CLI version 8 and higher, can help solve this problem.

\n

Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled the CLI builds two separate bundles as part of your deployed application.

\n\n

Differential buildslink

\n

When you deploy using the Angular CLI build process, you can choose how and when to support differential loading.\nThe ng build CLI command queries the browser configuration and the configured build target to determine if support for legacy browsers is required, and whether the build should produce the necessary bundles used for differential loading.

\n

The following configurations determine your requirements.

\n\n
\n

Differential loading is currently only supported when using es2015 as a compilation target. When used with targets higher than es2015, the build process emits a warning.

\n
\n

For a development build, the output produced by ng build is simpler and easier to debug, allowing you to rely less on sourcemaps of compiled code.

\n

For a production build, your configuration determines which bundles are created for deployment of your application.\nWhen needed, the index.html file is also modified during the build process to include script tags that enable differential loading, as shown in the following example.

\n\n<body>\n <app-root></app-root>\n <script src=\"runtime-es2015.js\" type=\"module\"></script>\n <script src=\"runtime-es5.js\" nomodule></script>\n <script src=\"polyfills-es2015.js\" type=\"module\"></script>\n <script src=\"polyfills-es5.js\" nomodule></script>\n <script src=\"styles-es2015.js\" type=\"module\"></script>\n <script src=\"styles-es5.js\" nomodule></script>\n <script src=\"vendor-es2015.js\" type=\"module\"></script>\n <script src=\"vendor-es5.js\" nomodule></script>\n <script src=\"main-es2015.js\" type=\"module\"></script>\n <script src=\"main-es5.js\" nomodule></script>\n</body>\n\n

Each script tag has a type=\"module\" or nomodule attribute. Browsers with native support for ES modules only load the scripts with the module type attribute and ignore scripts with the nomodule attribute. Legacy browsers only load the scripts with the nomodule attribute, and ignore the script tags with the module type that load ES modules.

\n
\n

Some legacy browsers still download both bundles, but only execute the appropriate scripts based on the attributes mentioned above. You can read more on the issue here.

\n
\n

Configuring differential loadinglink

\n

To include differential loading in your application builds, you must configure the Browserslist and TypeScript configuration files in your application project.

\n

The following examples show a .browserslistrc and tsconfig.json file for a newly created Angular application. In this configuration, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.

\n\n# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.\n# For additional information regarding the format and rule options, please see:\n# https://github.com/browserslist/browserslist#queries\n\n# For the full list of supported browsers by the Angular framework, please see:\n# https://angular.io/guide/browser-support\n\n# You can see what browsers were selected by your queries by running:\n# npx browserslist\n\nlast 1 Chrome version\nlast 1 Firefox version\nlast 2 Edge major versions\nlast 2 Safari major versions\nlast 2 iOS major versions\nFirefox ESR\nnot IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.\n\n\n\n{\n \"compileOnSave\": false,\n \"compilerOptions\": {\n \"baseUrl\": \"./\",\n \"outDir\": \"./dist/out-tsc\",\n \"sourceMap\": true,\n \"declaration\": false,\n \"module\": \"esnext\",\n \"moduleResolution\": \"node\",\n \"emitDecoratorMetadata\": true,\n \"experimentalDecorators\": true,\n \"importHelpers\": true,\n \"target\": \"es2015\",\n \"typeRoots\": [\n \"node_modules/@types\"\n ],\n \"lib\": [\n \"es2018\",\n \"dom\"\n ]\n }\n}\n\n\n
\n

To see which browsers are supported and determine which settings meet to your browser support requirements, see the Browserslist compatibility page.

\n
\n

The Browserslist configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.

\n

If your Browserslist configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
BrowserslistES targetBuild result
ES5 support disabledes2015Single build, ES5 not required
ES5 support enabledes5Single build w/conditional polyfills for ES5 only
ES5 support enabledes2015Differential loading (two builds w/conditional polyfills)
\n\n

Local development in older browserslink

\n

Differential loading is not enabled by default for application projects that were generated with Angular CLI 10 and above.\nThe ng serve, ng test, and ng e2e commands, however, generate a single ES2015 build which cannot run in older browsers that don't support the modules, such as IE 11.

\n

To maintain the benefits of differential loading, however, a better option is to define multiple configurations for ng serve, ng e2e, and ng test.

\n\n

Configuring serve for ES5link

\n

To do this for ng serve, create a new file, tsconfig-es5.app.json next to tsconfig.app.json with the following content.

\n\n\n{\n \"extends\": \"./tsconfig.app.json\",\n \"compilerOptions\": {\n \"target\": \"es5\"\n }\n}\n\n\n

In angular.json add two new configuration sections under the build and serve targets to point to the new TypeScript configuration.

\n\n\n\"build\": {\n \"builder\": \"@angular-devkit/build-angular:browser\",\n \"options\": {\n ...\n },\n \"configurations\": {\n \"production\": {\n ...\n },\n \"es5\": {\n \"tsConfig\": \"./tsconfig-es5.app.json\"\n }\n }\n},\n\"serve\": {\n \"builder\": \"@angular-devkit/build-angular:dev-server\",\n \"options\": {\n ...\n },\n \"configurations\": {\n \"production\": {\n ...\n },\n \"es5\": {\n \"browserTarget\": \"<app-name>:build:es5\"\n }\n }\n},\n\n\n

You can then run the ng serve command with this configuration. Make sure to replace <app-name> (in \"<app-name>:build:es5\") with the actual name of the app, as it appears under projects in angular.json. For example, if your app name is myAngularApp the config will become \"browserTarget\": \"myAngularApp:build:es5\".

\n\n\nng serve --configuration es5\n\n\n\n

Configuring the test commandlink

\n

Create a new file, tsconfig-es5.spec.json next to tsconfig.spec.json with the following content.

\n\n\n{\n \"extends\": \"./tsconfig.spec.json\",\n \"compilerOptions\": {\n \"target\": \"es5\"\n }\n}\n\n\n\n\n\"test\": {\n \"builder\": \"@angular-devkit/build-angular:karma\",\n \"options\": {\n ...\n },\n \"configurations\": {\n \"es5\": {\n \"tsConfig\": \"./tsconfig-es5.spec.json\"\n }\n }\n},\n\n\n

You can then run the tests with this configuration

\n\n\nng test --configuration es5\n\n\n

Configuring the e2e commandlink

\n

Create an ES5 serve configuration as explained above, and configuration an ES5 configuration for the E2E target.

\n\n\n\"e2e\": {\n \"builder\": \"@angular-devkit/build-angular:protractor\",\n \"options\": {\n ...\n },\n \"configurations\": {\n\t \"production\": {\n\t\t ...\n\t },\n \"es5\": {\n \"devServerTarget\": \"<app-name>:serve:es5\"\n }\n }\n},\n\n\n

You can then run the ng e2e command with this configuration. Make sure to replace <app-name> (in \"<app-name>:serve:es5\") with the actual name of the app, as it appears under projects in angular.json. For example, if your app name is myAngularApp the config will become \"devServerTarget\": \"myAngularApp:serve:es5\".

\n\n\nng e2e --configuration es5\n\n\n\n \n
\n\n\n" }