Angular 2 in dev and production with IIS and webpack - iis

I'm building an Angular 2 web application that communicates with webapis to get data, the app will be hosted on IIS with Windows authentication and I have some questions :
Should I use system.config as the main examples of Angular 2 work with?
If so, what about production and how can I work with sass?
Should I use webpack as angular-cli? If so, how can I combine with the advantages of the webpack Dev server (Hot reloading, sass trans-pilers, etc.)
and IIS hosting with Windows authentication?
Sorry if the questions are irrelevant but I'm a .NET developer and new to Angular 2 and Webpack.

You can use the angular-cli to develop the angular 2 app. To deploy the app on production on IIS you can use:
ng-build --prod command from angular-cli command prompt to build the app. This will generate the files required for deployment in dest folder. These are just HTML, javascript, css and other assets that your app uses.
You can copy contents of dest folder and deploy in folder of your IIS web application.
Note:
Angular 2 routing (with hash) will work without any issue on IIS. Just create default URL rewrite rule which will redirect all the requests to index.html file of your angular app. Rule will redirect all requests to index.html except for required js files and actual angular app urls (i.e. index.html or index.html#/{route-value}.
EX: <rules> <rule name="Default"> <match url="(.* ).js|index.html(.*)" negate="true" /> <action type="Rewrite" url="/index.html" /> </rule> </rules>
Angular 2 routing (without hash) will not work with IIS. In case of pure HTML application IIS will be routing the incoming request and it will redirect the request to error page if such page does not exist at that location.
In case of .Net MVC application you can create a default route to handle all the incoming request url's and redirect it to your angular index view.
Ex Route for MVC application:
routes.MapRoute(
name: "Angular",
url: "{*url}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { url = new AppFeatureUrlConstraint() }
public class AppFeatureUrlConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (values[parameterName] != null)
{
var url = values[parameterName].ToString();
if (url.StartsWith("angular/", StringComparison.InvariantCultureIgnoreCase))
return true;
else
return false;
}
return false;
}
}

I recommend Angular cli with webpack. It has hot module reloading already integrated and has out of the box development and production environments with bundling and tree shaking functionality.

Related

Redirects doesn't work on netlify with nextjs

I simply followed the doc by adding this to my next.config.js
module.exports = {
reactStrictMode: true,
async redirects() {
return [
{
source: "/",
destination: "/coming-soon",
permanent: false,
},
];
},
}
It does work on my machin even when I build the app but on netlify there is no redirect at all for some reason
According to the official Netlify docs:
Redirects and rewrites using next.config.js aren't currently supported for Next.js sites on Netlify. If you have these specified in a next.config.js file for your project, check out our redirects and rewrites docs to learn how to set them up in a _redirects or netlify.toml file instead.
So you basically need to create a _redirects file at the top level of your project with the following contents:
/ /coming-soon 302
The 302 status code is equivalent to permanent: false that you've done in your config.
If you have a netlify.toml, then you can add something like this to make your stuff work:
[[redirects]]
from = "/"
to = "/coming-soon"
status = 302
force = false
References:
Redirects and rewrites | Netlify Docs
Redirect options | Netlify Docs
Migrating an existing Next.js project to Netlify
When we deploy a Next.js project on Netlify it automatically gets all the necessary dependencies including the Essential Next.js plugin (If it is not installed in the plugin tab, we have to install it manually). This plugin configures your Netlify site to allow essential Next.js capabilities. Version 4 of the Essential Next.js plugin adds support for native Next.js rewrites and redirects.
Basically, you can use native Next.js redirects/rewrites (configured in next.config.js) in Netlify by installing the Essential Next.js plugin version 4 or higher to your Next.js site deployed in Netlify.
Refer this to learn more about using Next.js and Netlify redirects/rewrites rules.
https://github.com/netlify/netlify-plugin-nextjs/blob/main/docs/redirects-rewrites.md

Vuejs Deployment issues: IIS, routes

I am struggling with the deployment of a Vuejs front-end on my local IIS.
I would like to have my app deployed into a folder named FE_STB which is a sub-directory within my C:\inetpub\wwwroot folder.
Ideally, the URL to access the front-end would be http://localhost/FE_STB/.
In order to do so, I tried the following in vue.config.js:
module.exports = {
// Used to build the path for the css, js
baseUrl: process.env.NODE_ENV === 'production'
? '/FE_STB/'
: '/',
// The folder where the app will be built in the project directory instead of the default dist folder
// outputDir: 'Vue',
};
running npm run build generates an index.html, a favicon.ico, my img, js, css and fonts folders.
The index.html contains link tags such as (<link href=/FE_STB/css/chunk-05c5.672f5bfa.css />) and i thought it was going in the good direction.
However, it keeps returning a
404 not found error
when i try to access http://localhost/FE_STB/.
On the other hand, If I copy only the index.html into the root directory of my IIS installation (wwwroot) instead of the FE_STB subdirectory, and check the http://localhost/ URL, my app appears correctly.
However, when I start browsing the app and hit the refresh button, I get an error. For example, If I am on http://localhost/about/ on my app and refresh it with F5, I will get a 404 error as it’s looking for C:\inetpub\wwwroot\about\ directory which doesn’t exist obviously.
I also tried the web.config and the IISrewrite solutions as explained on the vuejs website or tried to add:
const router = new VueRouter({
mode: 'history',
// To define sub-directory folder for the deployment
base: 'FE_STB',
routes,
linkActiveClass: 'active',
scrollBehavior(to, from, savedPosition) {
return savedPosition || { x: 0, y: 0 };
},
});
in my router.js but it doesn’t change anything.
Any tips or directions would be really helpful.
Thank you
S.

IIS Router Site rewrite rule doesn't find resource file when accessed with resource /current

On my IIS I have configured rewrite rules in the following way.
There is a Router Site which listens on port 80 and rewrites to proper websites by specified resource e.g when user enters host http://testpage.com/current it rewrites it to another website hosted under port 5001. Sample config:
<rule name="RewriteRule" stopProcessing="true">
<match url="^current(.*)?" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://{HTTP_HOST}:5001/{R:1}" />
</rule>
The site hosted under 5001 contains index.html and javascript file index.js which is referenced in index.html like this:
<script type="text/javascript" src="/index.js">
The entire configuration works super fine when I replace
<match url="^current(.*)?" />
with
<match url="^(.*)?" />
However when I use current here then it finds index.html located in page hosted under port 5001 but it can't find index.js. I suspect that the reason is because it tries to find /current/index.js but it doesn't exist.
I always thought that my RewriteRule should basically rewrite url to
http://testpage.com:5001
then get index.html and resolve index.js from current directory so it shouldn't have any knowledge about "current" resource.
Is there an easy way to fix this?
Obviously when I enter to the website like this: http://testpage.com:5001, bypassing rewrite rules it works fine.
I'll answer this for my future reference. It's not an issue with rewrite rules. The issue is with the way html resolves resources.
We need to do a few steps:
Set <base href="virtualpath">, in this example virtualpath should be equal to /current. We use webpack during TeamCity deployment to put correct value here. Example:
<script type="text/javascript">
window.virtualpath = window.location.pathname.toLowerCase().indexOf("${virtual_path_legacy}") >= 0 ? "/${virtual_path_legacy}" : "";
document.write("<base href='" + window.virtualpath + "/'/>");
</script>
new webpack.DefinePlugin({ "process.env": { NODE_ENV: JSON.stringify("production") }, virtual_path_legacy: JSON.stringify(virtual_path_legacy) })
In webpack.config.js make sure your publicPath is "" instead of "/"
If you use SignalR make sure you pass your virtualpath to $.hubConnection(If SignalR is hosted under virtualpath)
in .NET Core:
app.UseAppBuilder(appBuilder => appBuilder.MapSignalR(rootPath, hubConfiguration), camelCaseSerialization);
If you use react-router make sure you pass virtualpath to useRouterHistory. Example:
const browserHistory = useRouterHistory(createHistory)({
basename: infoService.virtualpath,
});
If you use libraries like fetch to connect to the API make sure to prefix all your api urls with virtualpath (if your API is also using virtualpath)

How to re-route certain request url to different server in NodeJS

I have here an Angular 2 application which is certainly running on NodeJS but heres the catch, consider this ng application is in the main directory www.angular2app.com and I have 2 other sub modules which is totally not angular which is
www.angular2app.com/blog > WordPress App 1
www.angular2app.com/events > WordPress App 2
www.angular2app.com/anythingelse > Angular 2
Is there a way to handle this requests properly in NodeJS? WordPress 1 and WordPress 2 are totally different sites. There is no apache or nginx here because it's on running on MS Azure
Hope some evangelic could help me with this problem.
Thank you
You can try to use the solution similar with Virtual Directory in IIS configuration. Please consider the following test structure in Azure Web Apps.
For simple reference, my test project only contains a node.js and a php application.
The project's structure:
wwwroot/
-nodejs/
-server.js
-web.config
-php/
-index.php
The server.js is a simple node.js server script:
var http = require("http");
var server = http.createServer(function(request, response) {
response.write("Hello World!");
response.end();
});
server.listen(process.env.PORT ||1337);
console.log("Server is listening");
The web.config is a iisnode configuration file for starter nodejs application, you can find the content at https://github.com/projectkudu/kudu/wiki/Using-a-custom-web.config-for-Node-apps.
And the index.php script contents a test sentence phpinfo().
When you browse domain/nodejs, the requests are against to the node.js application.
And when you browse domain/php, the requests are against to the PHP application.
Any further concern, please feel free to let me know.

How and what to deploy Angular2 to IIS

Take for instance angular2-quickstart. What files need to be deployed and what settings need to be set to launch this web app from IIS?
This is a Typescript tutorial that I have opted to compile to JavaScript.
Setting up Angular 2 for me was quite an issue because the HTML5 routes (without a hashbang) weren't working.
To get an Angular2 project working on an IIS environment without serving it using the Angular-CLI (you still need it to build it!):
After you're finished with development on your project, you'll need to build (or compile) it to a different environment. If you need to set that up, read this.
The shortest build command you need is:
ng b
In your build folder (if you didn't add an external/different folder, this will be the 'dist' folder in your project), copy the contents to your IIS server.
Ensure the folder of your IIS server has the needed permissions for the IIS_IUSRS group and IUSR user to access it. (Right click on the folder -> Properties -> Security -> Edit -> Add, and type those in. You can click the 'Check Name' button to ensure it's the correct ones you're typing in)
The next issue you need to tackle is getting a web.config file to put in your server folder to fix routing issues.
If we were working with Apache, we would need an .htaccess, but for IIS, we're using a web.config. The one found here worked for me if your application is routing from the root directory of your server.
(Note: As reminded by #Demortes, this will require an additional module to be added to your IIS environment called URLRewrite)
This (web.config) file goes in the root directory of your server.
Hope this helps anyone who had similar issues to me :)
Cheers.
Download and install IIS rewrite plugin https://www.iis.net/downloads/microsoft/url-rewrite
Create application under default website.
Create a folder in c:\inetpub\wwwroot to host the application
After step 8 copy dist folder contents to c:\inetpu\wwwroot\
Before build in index.html change base href="/" to base href="//"
To skip steps 1,2 and 3 for every new build check out step 9 as alternative to step 8
Web config structure.
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Main Rule" >
<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="/<appname subfolder>/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Note: Create a Web.config in src folder and add a reference to it in angular-cli.json in assets section so that it gets copied over during each build. -
Otherwise you will have manually create this file every time ng build is used.
not applicable
In angular-cli.json put web.config in assets block
"assets": [
"assets",
"favicon.ico",
"Web.config"
],
In angular-cli.josn put custom css path example so that it will be packaged in styles..bundle.cs
"styles": [
"../node_modules/font-awesome/css/font-awesome.min.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"assets/site.css",
"assets/page.css",
"assets/menu.css",
"styles.css",
"../node_modules/primeng/resources/primeng.min.css",
"../node_modules/primeng/resources/themes/omega/theme.css"
],
If you have custom scripts put those path under scripts section example
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"index.js"
],
ng build --prod
Note: ng build --prod starts AOT (ahead of time compilation) by default in latest version of angular-cli
Note: ng build command deletes dist folder and recreates that folder every time you ng build command
Alternative build command:
ng build --prod --output-path 'C:\inetpub\wwwroot\<appname subfolder>' --base-href /<appname subfolder>'/
a- if you don't want to manually update base-href in index.html
b- if you don't want to copy dist folder and wwwroot folder of app.
Note1: Following command will only work if you open visual code (or any terminal app) with administrative privileges. Otherwise mkdir command to create output folder in wwwroot will fail.
Note2: You still need to update Web.config with . See step 4
Note3: Checkout slash / at both starting and end of --base-href /'/
Check direct quote from one of the posting. Not sure if changing security privileges of IIS_IUSRS group and IUSR user for ...wwwroot\
as described in one of the web links is required. May be it is not required but I am highlighting it over here for you to keep in mind.
Direct quote from another use : " Ensure the folder of your IIS server has the needed permissions for the IIS_IUSRS group and IUSR user to access it. (Right click on the folder -> Properties -> Security -> Edit -> Add, and type those in. You can click the 'Check Name' button to ensure it's the correct ones you're typing in)"
References :
- How and what to deploy Angular2 to IIS
- https://www.youtube.com/watch?v=K0XORWxG11k
The webapp itself needs no server intelligence, as it is just static files - web assets ( *.js, *.html files etc). The static files are what angular2-quickstart generates as output of its build process, which you run in your dev environment (probably locally on your personal computer). The dev environment will need node (+ npm). And infact, you can test this tutorial on your local dev environment without the need for any external server.
edit:
If u look in the package.json u can see it has lite-server:
"scripts": {
"start": "npm run lite",
"lite": "lite-server"
},
Lite server is a small server that simulates a simple (web) file server.
Lightweight development only node server that serves a web app, opens
it in the browser, refreshes when html or javascript change, injects
CSS changes using sockets, and has a fallback page when a route is not
found.
To give you an answer, to serve your app with IIS, you only need http://docs.asp.net/en/latest/fundamentals/static-files.html
I have created a small github project that has Angular2 current as of today (10/13/2016) that runs in IIS 7.5 with routing and under ng serve.
It does use the hash based URL strategy.
It uses angular-cli, the read me has details on how to setup under IIS or ng serve.
https://github.com/howserss/Angular2-IIS-sample-app
Angular 2 routing (with hash) will work without any issue on IIS. Just create default URL rewrite rule which will redirect all the requests to index.html file of your angular app. Rule will redirect all requests to index.html except for required js files and actual angular app urls (i.e. index.html or index.html#/{route-value}.
EX:
<rules>
<rule name="Default">
<match url="(.* ).js|index.html(.*)" negate="true" />
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
Angular 2 routing (without hash) will not work with IIS.
In case of pure HTML application IIS will be routing the incoming request and it will redirect the request to error page if such page does not exist at that location.
In case of .Net MVC application you can create a default route to handle all the incoming request url's and redirect it to your angular index view.
Ex Route for MVC application:
routes.MapRoute(
name: "Angular",
url: "{*url}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { url = new AppFeatureUrlConstraint() }
public class AppFeatureUrlConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (values[parameterName] != null)
{
var url = values[parameterName].ToString();
if (url.StartsWith("angular/", StringComparison.InvariantCultureIgnoreCase))
return true;
else
return false;
}
return false;
}
}
Here is a nice and detailed explanation for deploying angular app in IIS. The summarized steps for publishing as a separate website are as follows:-
Create a web site in IIS, lets say the physical path you provided for this web application is C:\Publish.
publish you angular app using the below command:-
ng build --prod
After the application is built successfully copy and paste the contents of dist folder to C:\Publish folder.
Add web.config file to folder C:\Publish with following contents:-
<configuration>
<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="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
All done, now just go to IIS and browse your web-site, you will see it working.
after you build it, copy all files in dist fold put in a fold in your IIS server, it only contains html, css and js files, so just host it like a static website.
It works for any web server, no matter Apache, IIS or nginx.

Resources