Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ASP.NET Core & Angular Universal advanced starter - PWA w/ server-side rendering for SEO, Bootstrap, i18n internationalization, TypeScript, unit testing, WebAPI REST setup, SignalR, Swagger docs, and more! By@TrilonIO

License

NotificationsYou must be signed in to change notification settings

TrilonIO/aspnetcore-angular-universal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation



Trilon.io - Angular Universal, NestJS, JavaScript Application Consulting Development and Training

Made with ❤️ byTrilon.io


Harness the power of Angular 7+, ASP.NET Core 2.1, now with SEO !

Angular SEO in action:

ASP.NET Core Angular7 SEO

Angular Universal Application Architecture

ASP.NET Core 2.1 Angular 7+ Starter

This repository is maintained byTrilon.io and theAngular Universal team and is meant to be an advanced starterfor both ASP.NET Core 2.1 using Angular 7.0+, not only for the client-side, but to be rendered on the server for instantapplication paints (Note: If you don't need SSRread here on how to disable it).

This is meant to be a Feature-Rich Starter application containing all of the latest technologies, best build systems available, and include many real-world examples and libraries needed in todays Single Page Applications (SPAs).

This utilizes all the latest standards, no gulp, no bower, no typings, no manually "building" anything. NPM, Webpack and .NET handle everything for you!

Join us on Gitter

Gitter chat

Table of Contents


Features:

These are just some of the features found in this starter!

  • ASP.NET 2.1 - VS2017 support now!

    • Azure delpoyment straight from VS2017
    • Built in docker support through VS2017
    • RestAPI (WebAPI) integration
    • SQL Database CRUD demo
    • Swagger WebAPI documentation when running in development mode
    • SignalR Chat demo! (Thanks to@hakonamatata)
  • Angular 7.0.0 :

    • PWA (Progressive Web App)
    • (Minimal) Angular-CLI integration
      • This is to be used mainly for Generating Components/Services/etc.
      • Usage examples:
        • ng g c components/example-component
        • ng g s shared/some-service
    • Featuring Server-side rendering (Platform-Server, aka: "Universal")
      • Faster initial paints, SEO (Search-engine optimization w Title/Meta/Link tags), social media link-previews, etc
    • i18n internationalization support (via/ ngx-translate)
    • Baked in best-practices (follows Angular style guide)
    • Bootstrap3 (with ngx-bootstrap) - (can be rendered on the server!)
      • Can be easily replaced with bootstrap4 (3 is provided for browser support)
      • Bootstrap using SCSS / SASS for easy theming / styling!
  • Webpack build system (Webpack 4)

    • HMR : Hot Module Reloading/Replacement
    • Production builds w/ AoT Compilation
  • Testing frameworks

    • Unit testing with Jest (Going back to Karma soon)
  • Productivity

    • Typescript 2
    • Codelyzer (for Real-time static code analysis)
      • VSCode & Atom provide real-time analysis out of the box.
  • ASP.NET Core 2.1

    • Integration with NodeJS to provide pre-rendering, as well as any other Node module asset you want to use.
  • Azure

    • Microsoft Application Insights setup (for MVC & Web API routing)
    • Client-side Angular Application Insights integration
      // Add the Module to your importsApplicationInsightsModule.forRoot({instrumentationKey:'Your-Application-Insights-instrumentationKey'})
  • Docker

    • Built in Visual Studio F5 Debugging support
    • Uses the very light weight microsoft/dotnet image
    • Currently limited to Linux image as there is a bug with running nodejs in a container on Windows.


Getting Started?

  • Make sure you have at least Node 8.11.1 or higher (w/ npm 5+) installed!
  • This repository uses ASP.Net Core 2.1, which has a hard requirement on .NET Core Runtime 2.1 and .NET Core SDK 2.1. Please install these items fromhere

Visual Studio 2017

Make sure you have .NET Core 2.1 installed and/or VS2017 15.3.VS2017 will automatically install all the neccessary npm & .NET dependencies when you open the project.

Simply push F5 to start debugging !

Docker-Support: Change the startup project to docker-compose and press F5

Note: If you get any errors after this such asmodule not found: boot.server (or similar), open up command line and runnpm run build:dev to make sure all the assets have been properly built by Webpack.

Visual Studio Code

Note: Make sure you have the C# extension & .NET Core Debugger installed.

The project comes with the configured Launch.json files to let you just push F5 to start the project.

# cd into the directory you cloned the project intonpm install&& npm run build:dev&& dotnet restore# or yarn install

If you're running the project from command line withdotnet run make sure you set your environment variables to Development (otherwise things like HMR might not work).

# on Windows:set ASPNETCORE_ENVIRONMENT=Development# on Mac/Linuxexport ASPNETCORE_ENVIRONMENT=Development

Upcoming Features:

  • Clean API / structure / simplify application
  • Refactor to latest RxJs pipeable syntax
  • Attempt to integrate with Angular-CLI fully


Deployment

Dotnet publish

Usingdotnet publish, when it's finished place the generated folder onto your server and use IIS to fire everything up.

Heroku

Deploy on Heroku

Azure

git remote add azure https://your-user-name@my-angular2-site.scm.azurewebsites.net:443/my-angular2-site.git                     // ^ get this from Azure (Web App Overview section - Git clone url)git push --set-upstream azure master

Application Structure:

Note: This application has WebAPI (our REST API) setup inside the same project, but of course all of thiscould be abstracted out into a completely separate project('s) ideally. .NET Core things are all done in the same projectfor simplicity's sake.

Root level files

Here we have theusual suspects found at the root level.

Front-end oriented files:

  • package.json - NPM project dependencies & scripts
  • .tsconfig - TypeScript configuration (here we setup PATHs as well)
  • webpack - configuration files (modular bundling + so much more)
  • karma - configuration files (unit testing)
  • protractor - config files (e2e testing)
  • tslint - TypeScript code linting rules

/ClientApp/ - Everything Angular

Let's take a look at how this is structured so we can make some sense of it all!

With Angular Universal, we need to split our applicatoin logicper platform soif we look inside this folder,you'll see the 2 root files, that branch the entire logic for browser & server respectively.

  • Boot.Browser.ts -This file starts up the entire Angular application for the Client/browser platform.

Here we setup a few things, client Angular bootstrapping.

You'll barely need to touch this file, but something to note, this is the file where you would import libraries that youonly wantbeing used in the Browser. (Just know that you'd have to provide a mock implementation for the Server when doing that).

  • Boot.Server.ts -This file is where Angularplatform-serverserializes the Angular application itself on the .NET serverwithin a very quick Node process, and renders it a string. This is what causes that initial fast paintof the entire application to the Browser, and helps us get all ourSEO goodness ✨

Notice the folder structure here in./ClientApp/ :

+ /ClientApp/+   /app/    App NgModule - our Root NgModule (you'll insert Components/etc here most often)    AppComponent / App Routes / global css styles    * Notice that we have 2 dividing NgModules:        app.module.browser & app.module.server    You'll almost always be using the common app.module, but these 2 are used to split up platform logic    for situations where you need to use Dependency Injection / etc, between platforms.Note: You could use whatever folder conventions you'd like, I prefer to split up things in terms of whether they are re-usable      "components" or routeable / page-like components that group together and organize entire sections.++ > ++ > /components/          Here are all the regular Components that aren't "Pages" or container Components++ > ++ > /containers/          These are the routeable or "Page / Container" Components, sometimes known as "Dumb" Components++ > ++ > /shared/          Here we put all shared Services / Directives / Pipes etc

When adding new features/components/etc to your application you'll be commonly adding things to the RootNgModule (locatedin/ClientApp/app/app.module.ts), but why are theretwo other NgModules in this folder?

This is because we want to split our logicper Platform, but notice they both share the Common NgModulenamedapp.module.ts. When adding most things to your application, this is the onlyplace you'll have to add in your new Component / Directive / Pipe / etc. You'll only occassional need to manuallyadd in the Platform specific things to eitherapp.module.browser || app.module.server.

To illustrate this point with an example, you can see how we're using Dependency Injection to inject aStorageService that is differentfor the Browser & Server.

// For the Browser (app.module.browser){provide:StorageService,useClass:BrowserStorage}// For the Server (app.module.server){provide:StorageService,useClass:ServerStorage}

Just remember, you'll usually only need to worry aboutapp.module.ts, as that's where you'll be adding mostof your applications new aspects!

/Server/ - Our REST API (WebApi) - MVC Controller

As we pointed out, these are here for simplicities sake, and realistically you may want separate projectsfor all your microservices / REST API projects / etc.

We're utilizing MVC within this application, but we only need & have ONE Controller, namedHomeController. This is where our entireAngular application gets serialized into a String, sent to the Browser, along with all the assets it needs to then bootstrap on the client-side, and become a full-blown SPA afterwards.


The short-version is that we invoke that Node process, passing in our Request object & invoke theboot.server file, and we get back a nice object that we pass into .NETsViewData object, and sprinkle through out ourViews/Shared/_Layout.cshtml and/Views/Home/index.cshtml files!

A more detailed explanation can be found here:ng-AspnetCore-Engine Readme

// Prerender / Serialize applicationvarprerenderResult=awaitPrerenderer.RenderToString(/* all of our parameters / options / boot.server file / customData object goes here */);ViewData["SpaHtml"]=prerenderResult.Html;ViewData["Title"]=prerenderResult.Globals["title"];ViewData["Styles"]=prerenderResult.Globals["styles"];ViewData["Meta"]=prerenderResult.Globals["meta"];ViewData["Links"]=prerenderResult.Globals["links"];returnView();// let's render the MVC View

Take a look at the_Layout.cshtml file for example, notice how we let .NET handle and inject all our SEO magic (that we extracted from Angular itself) !

<!DOCTYPE html><html><head><basehref="/"/><!-- Title will be the one you set in your Angular application --><title>@ViewData["Title"] - AspNET.Core Angular 7.0.0 (+) starter</title><metacharset="utf-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/>        @Html.Raw(ViewData["Meta"])<!-- <meta /> tags -->        @Html.Raw(ViewData["Links"])<!-- <link /> tags --><linkrel="stylesheet"href="~/dist/vendor.css"asp-append-version="true"/>        @Html.Raw(ViewData["Styles"])<!-- <style /> tags --></head>    ... etc ...

OurViews/Home/index.cshtml simply renders the application and serves the bundled webpack files in it.

@Html.Raw(ViewData["SpaHtml"])<scriptsrc="~/dist/vendor.js"asp-append-version="true"></script>@section scripts {<scriptsrc="~/dist/main-client.js"asp-append-version="true"></script>}

What happens after the App gets server rendered?

Well now, your Client-side Angular will take over, and you'll have a fully functioning SPA. (But we gained all these great SEO benefits of being server-rendered) !



"Gotchas"

  • This repository uses ASP.Net Core 2.1, which has a hard requirement on .NET Core Runtime 2.1 and .NET Core SDK 2.1. Please install these items fromhere

When building components in Angular 7 there are a few things to keep in mind.

  • Make sure you provide Absolute URLs when calling any APIs. (The server can't understand relative paths, so/api/whatever will fail).

  • API calls will be ran during a server, and once again during the client render, so make sure you're using transfering data that's important to you so that you don't see a flicker.

  • window,document,navigator, and other browser types -do not exist on the server - so using them, or any library that uses them (jQuery for example) will not work. You do have some options, if you truly need some of this functionality:

    • If you need to use them, consider limiting them to only your client and wrapping them situationally. You can use the Object injected using the PLATFORM_ID token to check whether the current platform is browser or server.
    import{PLATFORM_ID}from'@angular/core';import{isPlatformBrowser,isPlatformServer}from'@angular/common';constructor(@Inject(PLATFORM_ID)privateplatformId:Object){ ...}ngOnInit(){if(isPlatformBrowser(this.platformId)){// Client only code.      ...}if(isPlatformServer(this.platformId)){// Server only code.     ...}}
    • Try tolimit oravoid usingsetTimeout. It will slow down the server-side rendering process. Make sure to remove themngOnDestroy in Components.
    • Also for RxJs timeouts, make sure tocancel their stream on success, for they can slow down rendering as well.
  • Don't manipulate the nativeElement directly. Use theRenderer2. We do this to ensure that in any environment we're able to change our view.

constructor(element:ElementRef,renderer:Renderer2){this.renderer.setStyle(element.nativeElement,'font-size','x-large');}
  • The application runs XHR requests on the server & once again on the Client-side (when the application bootstraps)
    • Use a cache that's transferred from server to client (TODO: Point to the example)
  • Know the difference between attributes and properties in relation to the DOM.
  • Keep your directives stateless as much as possible. For stateful directives, you may need to provide an attribute that reflects the corresponding property with an initial string value such as url in img tag. For our native element the src attribute is reflected as the src property of the element type HTMLImageElement.
  • Error:sass-loader requiresnode-sass >=4: Either in the docker container or localhost runnpm rebuild node-sass -f


FAQ - Also check out the!FAQ Issues label! and the!HOW-TO Issues Label!

How can I disable SSR (Server-side rendering)?

Simply comment out the logic within HomeController, and replace@Html.Raw(ViewData["SpaHtml"]) with just your applications rootAppComponent tag ("app-root" in our case):<app-root></app-root>.

You could also remove anyisPlatformBrowser/etc logic, and delete the boot.server, app.module.browser & app.module.server files, just make sure yourboot.browser file points toapp.module.

How do I have code run only in the Browser?

Check theGotchas on how to useisPlatformBrowser().

How do I Material2 with this repo?

You'll either want to remove SSR for now, or wait as support should be coming to handle platform-server rendering.This is now possible, with the recently updated Angular Material changes. We do not have a tutorial available for this yet.

How can I use jQuery and/or some jQuery plugins with this repo?

Note: If at all possible, try to avoid using jQuery or libraries dependent on it, as there arebetter, more abstract ways of dealing with the DOM in Angular (5+) such as using the Renderer, etc.

Yes, of course but there are a few things you need to setup before doing this. First, make sure jQueryis included in webpack vendor file, and that you have a webpack Plugin setup for it.new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })

Now, make sure any "plugins" etc that you have, are only included in yourboot.browser.ts file. (ie:import 'slick-carousel';)In a Component you want to use jQuery, make sure to import it near the top like so:

import*as$from'jquery';

Always make sure to wrap anything jQuery oriented in Angular'sisPlatformBrowser() conditional!

How can I support IE9 through IE11?

To support IE9 through IE11 open thepolyfills.ts file in thepolyfills folder and uncomment out the 'import polyfills' as needed. ALSO - make sure that yourwebpack.config andwebpack.config.vendor change option ofTerserPlugin fromecma: 6 toecma: 5.


Special Thanks

Many thanks go out to Steve Sanderson (@SteveSandersonMS) from Microsoft and his amazing work on JavaScriptServices and integrating the world of Node with ASP.NET Core.

Also thank you to the many Contributors !


Found a Bug? Want to Contribute?

Check out our easier issues here

Nothing's ever perfect, but please let me know by creating an issue (make sure there isn't an existing one about it already), and we'll try and work out a fix for it! If you have any good ideas, or want to contribute, feel free to either make an Issue with the Proposal, or just make a PR from your Fork.


License

MIT License

Copyright (c) 2016-2019Mark Pieszak

Twitter Follow


Trilon - Angular & ASP.NET - Consulting | Training | Development

Check outTrilon.io for more info! Twitter@Trilon_io

Contact us athello@trilon.io, and let's talk about your projects needs.

Trilon.io - Angular Universal, NestJS, JavaScript Application Consulting Development and Training

Follow Trilon online:

Twitter:@Trilon_io

About

ASP.NET Core & Angular Universal advanced starter - PWA w/ server-side rendering for SEO, Bootstrap, i18n internationalization, TypeScript, unit testing, WebAPI REST setup, SignalR, Swagger docs, and more! By@TrilonIO

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors48


[8]ページ先頭

©2009-2025 Movatter.jp