How do you deploy Angular apps once they reach the production phase?
All the guides I've seen so far (even on angular.io) are counting on a lite-server for serving and browserSync to reflect changes - but when you finish with development, how can you publish the app?
Do I import all the compiled .js
files on the index.html
page or do I minify them using gulp? Will they work? Do I need SystemJS at all in the production version?
Simple answer. Use the Angular CLI and issue the
ng build
command in the root directory of your project. The site will be created in the dist directory and you can deploy that to any web server.
This will build for test, if you have production settings in your app you should use
ng build --configuration production
This will build the project in the dist
directory and this can be pushed to the server.
Much has happened since I first posted this answer. The CLI is finally at a 1.0.0 so following this guide go upgrade your project should happen before you try to build. https://github.com/angular/angular-cli/wiki/stories-rc-update
You are actually here touching two questions in one.
The first one is How to host your application?. And as @toskv mentioned its really too broad question to be answered and depends on numerous different things.
The second one is How do you prepare the deployment version of the application?. You have several options here:
Deploy as it is. Just that - no minification, concatenation, name mangling, etc. Transpile all your ts project copy all your resulting js/css/... sources + dependencies to the hosting server and you are good to go. Deploy using special bundling tools, like webpack or systemjs builder. They come with all the possibilities that are lacking in #1. You can pack all your app code into just a couple of js/css/... files that you reference in your HTML. systemjs builder even allows you to get rid of the need to include systemjs as part of your deployment package. You can use ng deploy as of Angular 8 to deploy your app from your CLI. ng deploy will need to be used in conjunction with your platform of choice (such as @angular/fire). You can check the official docs to see what works best for you here
Yes you will most likely need to deploy systemjs
and bunch of other external libraries as part of your package. And yes you will be able to bundle them into just couple of js files you reference from your HTML page.
You do not have to reference all your compiled js files from the page though - systemjs
as a module loader will take care of that.
I know it sounds muddy - to help get you started with the #2 here are two really good sample applications:
SystemJS builder: angular2 seed
WebPack: angular2 webpack starter
node_modules
as well. Note - you should copy only dependencies required for the program to run. Do not copy deps that are used for development only (for example gulp/grunt/etc).
With the Angular CLI it's easy. An example for Heroku:
Create a Heroku account and install the CLI Move the angular-cli dep to the dependencies in package.json (so that it gets installed when you push to Heroku. Add a postinstall script that will run ng build when the code gets pushed to Heroku. Also add a start command for a Node server that will be created in the following step. This will place the static files for the app in a dist directory on the server and start the app afterward.
"scripts": {
// ...
"start": "node server.js",
"postinstall": "ng build --aot -prod"
}
Create an Express server to serve the app.
// server.js
const express = require('express');
const app = express();
// Run the app by serving the static files
// in the dist directory
app.use(express.static(__dirname + '/dist'));
// Start the app by listening on the default
// Heroku port
app.listen(process.env.PORT || 8080);
Create a Heroku remote and push to depoy the app.
heroku create
git add .
git commit -m "first deploy"
git push heroku master
Here's a quick writeup I did that has more detail, including how to force requests to use HTTPS and how to handle PathLocationStrategy
:)
I use with forever:
Build your Angular application with angular-cli to dist folder ng build --prod --output-path ./dist Create server.js file in your Angular application path: const express = require('express'); const path = require('path'); const app = express(); app.use(express.static(__dirname + '/dist')); app.get('/*', function(req,res) { res.sendFile(path.join(__dirname + '/dist/index.html')); }); app.listen(80); Start forever forever start server.js
That's all! your application should be running!
If You test app like me on localhost or You will have some problems with blank white page i use this:
ng build --prod --build-optimizer --base-href="http://127.0.0.1/my-app/"
Explanation:
ng build
Build app but in code there is many spaces, tabs and other stuff what makes code able be read by human. For server it isnt important how code looks. This is why i use:
ng build --prod --build-optimizer
This make code out for production and reduce size [--build-optimizer
] allow to reduce more code].
So at end i add --base-href="http://127.0.0.1/my-app/"
to show application where is 'main frame' [in simple words]. With it You can have even multiple angular apps in any folder.
Hopefully this may help, and hopefully I'll get to try this during the week.
Create Web app at Azure Create Angular 2 app in vs code. Webpack to bundle.js. Download Azure site published profile xml Configure Azure-deploy using https://www.npmjs.com/package/azure-deploy with site profile. Deploy. Taste the cream.
Can't resolve 'node-uuid' in path\azure-deploy\lib
. Is this still possible? I configured step 5 in app.module
and I'm not sure that I did step 3 and 4 correctly. Could you clarify those?
In order to deploy your Angular2 app to a production server, first and foremost, ensure your app runs locally on your machine.
Angular2 app can also be deployed as a node app.
So, create a node entry point file server.js/app.js (my example uses express)
var express = require('express'),
path = require('path'),
fs = require('fs');
var app = express();
var staticRoot = __dirname + '/';
app.set('port', (process.env.PORT || 3000));
app.use(express.static(staticRoot));
app.use(function(req, res, next){
// if the request is not html then move along
var accept = req.accepts('html', 'json', 'xml');
if(accept !== 'html'){
return next();
}
// if the request has a '.' assume that it's for a file, move along
var ext = path.extname(req.path);
if (ext !== ''){
return next();
}
fs.createReadStream(staticRoot + 'index.html').pipe(res);
});
app.listen(app.get('port'), function() {
console.log('app running on port', app.get('port'));
});
Also add express as a dependency in your package.json file.
Then deploy it on your preferred environment.
I have put together a small blog for deployment on IIS. follow link
To Deploy your application in IIS follow the below steps.
Step 1: Build your Angular application using command ng build --prod
Step 2: After build all files are stored in dist folder of your application path.
Step 3: Create a folder in C:\inetpub\wwwroot by name QRCode.
Step 4: Copy the contents of dist folder to C:\inetpub\wwwroot\QRCode folder.
Step 5: Open IIS Manager using command (Window + R) and type inetmgr click OK.
Step 6: Right click on Default Web Site and click on Add Application.
Step 7: Enter Alias name 'QRCode' and set the physical path to C:\inetpub\wwwroot\QRCode.
Step 8: Open index.html file and find the line href="\" and remove '\'.
Step 9: Now browse application in any browser.
You can also follow the video for better understanding.
Video url: https://youtu.be/F8EI-8XUNZc
If you deploy your application in Apache (Linux server) so you can follow following steps : Follow following steps :
Step 1: ng build --prod --env=prod
Step 2. (Copy dist into server) then dist folder created, copy dist folder and deploy it in root directory of server.
Step 3. Creates .htaccess
file in root folder and paste this in the .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
You get the smallest and quickest loading production bundle by compiling with the Ahead of Time compiler, and tree-shake/minify with rollup as shown in the angular AOT cookbook here: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
This is also available with the Angular-CLI as said in previous answers, but if you haven't made your app using the CLI you should follow the cookbook.
I also have a working example with materials and SVG charts (backed by Angular2) that it includes a bundle created with the AOT cookbook. You also find all the config and scripts needed to create the bundle. Check it out here: https://github.com/fintechneo/angular2-templates/
I made a quick video demonstrating the difference between number of files and size of an AoT compiled build vs a development environment. It shows the project from the github repository above. You can see it here: https://youtu.be/ZoZDCgQwnmQ
"This cookbook describes how to radically improve performance by compiling Ahead of Time (AOT) during a build process."
Angular 2 Deployment in Github Pages
Testing Deployment of Angular2 Webpack in ghpages
First get all the relevant files from the dist
folder of your application, for me it was the : + css files in the assets folder + main.bundle.js + polyfills.bundle.js + vendor.bundle.js
Then push this files in the repo which you have created.
1 -- If you want the application to run on the root directory - create a special repo with the name [yourgithubusername].github.io and push these files in the master branch
2 -- Where as if you want to create these page in the sub directory or in a different branch other than than the root, create a branch gh-pages and push these files in that branch.
In both the cases the way we access these deployed pages will be different.
For the First case it will be https://[yourgithubusername].github.io and for the second case it will be [yourgithubusername].github.io/[Repo name].
If suppose you want to deploy it using the second case make sure to change the base url of the index.html file in the dist as all the route mappings depend on the path you give and it should be set to [/branchname].
Link to this page
https://rahulrsingh09.github.io/Deployment
Git Repo
https://github.com/rahulrsingh09/Deployment
For a quick and cheap way to host an angular app, I have been using the Firbase hosting. It's free on the first tier and very easy to deploy new versions using the Firebase CLI. This article here explains the necessary steps to deploy your production angular 2 app to Firebase: https://medium.com/codingthesmartway-com-blog/hosting-angular-2-applications-on-firebase-f194688c978d
In short, you run ng build --prod
which creates a dist folder in the package and that's the folder that gets deployed to Firebase Hosting.
Deploying Angular 2 in azure is easy
Run ng build --prod , which will generate a dist folder with everything bundled inside few files including index.html. Create a resource group and a web app inside it. Place your dist folders files using FTP. In azure it will look for index.html to the run the application.
That's it. Your app is running !
As of 2017 the best way is to use angular-cli (v1.4.4) for your angular project.
ng build --prod --env=prod --aot --build-optimizer --output-hashing none
You needn't add --aot explicitly as its turned on by default with --prod.And the use of --output-hashing is as per your personal preference regarding cache bursting.
You could explicitly add CDN support by adding :
--deploy-url "https://<your-cdn-key>.cloudfront.net/"
if you plan to use CDN for hosting which is considerably fast.
With Angular CLI, you can use the following command:
ng build --prod
It generates a dist folder with all you need to deploy the application.
If you have no practice with web servers, I recommend you to use Angular to Cloud. You just need to compress the dist folder as zip file and upload it in the platform.
I would say a lot of people with Web experience prior to angular, are use to deploying their web artifacts inside a war (i.e. jquery and html inside a Java/Spring project). I ended up doing this to get around CORS issue, after attempting to keep my angular and REST projects separate.
My solution was to move all angular (4) contents, generated with CLI, from my-app to MyJavaApplication/angular. Then I modifed my Maven build to use maven-resources-plugin to move the contents from /angular/dist to the root of my distribution (i.e. $project.build.directory}/MyJavaApplication). Angular loads resources from root of the war by default.
When I started to add routing to my angular project, I further modifed maven build to copy index.html from /dist to WEB-INF/app. And, added a Java controller that redirects all server side rest calls to index.
You can build your application for production using
ng build --configuration=production
Then you can check you angular.json
for the key outputPath
where it normally has the value dist
but could be different as well.
"build": {
"options": {
"outputPath": "dist"
With dist
as value the outputed files from the build would be placed under the folder /dist
When built your angular project will consist only from static files Html, Javascript, Css and images or other assets. Because of that, what you need is just a web server that can serve static files to the client. Simple as that. Can be nginx, tomcat whatever can serve those static files to a client. This is also stated in the angular doc
Because these files are static, you can host them on any web server capable of serving files
Your built project under outputPath will already contain an index.html
which will automatically have all necessary imports so when index.html
is delivered to the client, the browser will also fetch all other necessary files. Necessary info is already contained in index.html
.
Your second part of the question
do I minify them using gulp
The official way
angular.json
will contain specific configurations for each environment and one of those will be optimization
optimization
can be a boolean (true, false)
"configurations": {
"production": {
"optimization": true --> will mean true for all properties of the next custom object
optimization
can also be a custom object
"configurations": {
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": true
},
"fonts": true
}
switching to "scripts": false
will have as a result the .js files to not be minified
also switching to styles -> "minify": false
will also avoid styles minifying.
Whatever configuration you have in angular.json for optimization, it can be overwritten if you provide a parameter during build. So by executing ng build --configuration=production --optimization=false
it will build your project for production and apply to each property of optimization
object the value false
, which will actually disable minifying for everything.
Just follow the below link,
Change your Index.html page Script File paths Change your component.html path incase your getting error that could not find the location
https://angular.io/docs/ts/latest/guide/deployment.html#!#dev-deploy
Success story sharing
Option "--prod" is deprecated: Use "--configuration production" instead.