Angular SEO在作用:


该存储库由Trilon.io和Angular Universal Team维护,本来可以使用ASP.NET Core 2.1使用Angular 7.0+的高级开始,不仅用于客户端,而且要在服务器上渲染以进行即时应用程序涂料(请注意:如果您不需要在此处使用SSR读取如何拒绝它)。
这是一个包含所有最新技术,最佳构建系统的功能启动应用程序,并包括当今单页应用程序(SPA)中所需的许多真实示例和库。
这利用了所有最新标准,没有毛孔,没有鲍尔,没有打字,没有手动“构建”任何东西。 NPM,WebPack和.NET为您处理一切!
这些只是此入门者中发现的一些功能!
ASP.NET 2.1 -VS2017支持!
Angular 7.0.0 :
ng gc components/example-componentng gs shared/some-serviceWebPack构建系统(WebPack 4)
测试框架
生产率
ASP.NET Core 2.1
azure
npm i -S @markpieszak/ng-application-insights作为依赖项即可。 // Add the Module to your imports
ApplicationInsightsModule . forRoot ( {
instrumentationKey : 'Your-Application-Insights-instrumentationKey'
} )Docker
确保已安装.NET Core 2.1和/或VS2017 15.3。打开项目时,VS2017将自动安装所有必要的NPM&.NET依赖关系。
只需推动F5即可开始调试!
Docker-Support :更改启动项目以Docker-Compose并按F5
注意:如果在此之后遇到任何错误,例如module not found: boot.server (或类似),打开命令行并运行npm run build:dev确保所有资产已由WebPack正确构建。
注意:确保安装了C#扩展和.NET Core调试器。
该项目带有配置的启动。JSON文件,让您只需按F5即可启动项目。
# cd into the directory you cloned the project into
npm install && npm run build:dev && dotnet restore
# or yarn install如果您正在使用dotnet run行运行项目,请确保将环境变量设置为开发(否则HMR可能无法使用)。
# on Windows:
set ASPNETCORE_ENVIRONMENT=Development
# on Mac/Linux
export ASPNETCORE_ENVIRONMENT=Development 使用dotnet publish后,将生成的文件夹放在服务器上并使用IIS启动所有内容。
git remote add azure https://[email protected]:443/my-angular2-site.git
// ^ get this from Azure (Web App Overview section - Git clone url)
git push --set-upstream azure master 注意:此应用程序在同一项目中具有WebAPI(我们的REST API)设置,但是当然,所有这些都可以将所有这些都提取为一个完全独立的项目('S)。为了简单起见,.net核心工作全部完成了同一项目。
根级文件
在这里,我们有在根层发现的通常的嫌疑人。
面向前端的文件:
package.json -NPM项目依赖项和脚本.tsconfig打字稿配置(在这里我们也设置路径)webpack配置文件(模块化捆绑 +更多)karma - 配置文件(单位测试)protractor - 配置文件(E2E测试)tslint打字稿代码覆盖规则让我们看一下这是如何结构化的,以便我们可以对此有所了解!
使用Angular Universal,我们需要将每个平台的应用程序逻辑分开,因此,如果我们在此文件夹中查看,您将看到两个root文件,分别为浏览器和服务器分别分支整个逻辑。
在这里,我们设置了几件事,客户端角启动。
您几乎不需要触摸此文件,但是要注意的是,这是您只想在浏览器中使用的库。 (只知道您必须在执行此操作时为服务器提供模拟实现)。
请注意此处的文件夹结构在./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在应用程序中添加新功能/组件/等时,您通常会将内容添加到root ngmodule (位于/ClientApp/app/app.module.ts中),但是为什么此文件夹中还有其他两个ngmodules?
这是因为我们想将每个平台的逻辑分开,但是请注意,它们都共享名为app.module.ts的通用ngmodule。当将大多数内容添加到应用程序时,这是您唯一必须在新组件 /指示 /管道 /管道中添加的地方。您只需要偶尔需要手动在平台特定的特定内容中添加到一个app.module.browser || app.module.server 。
为了用示例说明这一点,您可以看到我们如何使用依赖注入来注入浏览器和服务器不同的StorageService 。
// For the Browser (app.module.browser)
{ provide : StorageService , useClass : BrowserStorage }
// For the Server (app.module.server)
{ provide : StorageService , useClass : ServerStorage }请记住,通常您通常只需要担心
app.module.ts,因为那是您将添加大多数应用程序的新方面!
正如我们指出的那样,这些都是为简单起见的,实际上,您可能需要用于所有微服务 / REST API Projects /等的单独项目。
我们在此应用程序中使用MVC,但是我们只需要一个控制器,名为HomeController 。在这里,我们的整个Angular应用程序都将其序列化为字符串,发送到浏览器,以及所有需要在客户端上引导的资产,然后成为一个成熟的水疗中心。
短期是我们调用该节点过程,传递我们的请求对象并调用boot.server文件,然后回到一个不错的对象中,我们将其传递到.NETS ViewData对象中,然后浏览我们的Views/Shared/_Layout.cshtml /Views/Home/index.cshtml文件!
可以在此处找到一个更详细的解释:
// Prerender / Serialize application
var prerenderResult = await Prerenderer . 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" ] ;
return View ( ) ; // let's render the MVC View例如,查看_Layout.cshtml文件,请注意我们如何让.NET处理并注入所有SEO魔术(我们从Angular本身提取)!
<!DOCTYPE html >
< html >
< head >
< base href =" / " />
<!-- Title will be the one you set in your Angular application -->
< title > @ViewData["Title"] - AspNET.Core Angular 7.0.0 (+) starter </ title >
< meta charset =" utf-8 " />
< meta name =" viewport " content =" width=device-width, initial-scale=1.0 " />
@Html.Raw(ViewData["Meta"]) <!-- <meta /> tags -->
@Html.Raw(ViewData["Links"]) <!-- <link /> tags -->
< link rel =" stylesheet " href =" ~/dist/vendor.css " asp-append-version =" true " />
@Html.Raw(ViewData["Styles"]) <!-- <style /> tags -->
</ head >
... etc ...我们的Views/Home/index.cshtml简单地呈现应用程序,并在其中提供捆绑的webpack文件。
@Html.Raw(ViewData["SpaHtml"])
< script src =" ~/dist/vendor.js " asp-append-version =" true " > </ script >
@section scripts {
< script src =" ~/dist/main-client.js " asp-append-version =" true " > </ script >
}好了,您的客户端角将接管,您将拥有一个功能齐全的水疗中心。 (但是我们获得了所有这些巨大的SEO效果,可以通过服务器渲染)!
在Angular 7中构建组件时,请记住一些事情。
确保在调用任何API时提供绝对URL。 (服务器无法理解相对路径,所以/api/whatever将会失败的)。
API调用将在服务器期间进行,并在客户端渲染期间再次进行,因此请确保您使用的是对您重要的数据,以免看到闪烁。
window , document , navigator和其他浏览器类型 -服务器上不存在- 因此使用它们或使用它们的任何库(例如jQuery)将不起作用。您确实有一些选择,如果您确实需要一些此类功能:
import { PLATFORM_ID } from '@angular/core' ;
import { isPlatformBrowser , isPlatformServer } from '@angular/common' ;
constructor ( @ Inject ( PLATFORM_ID ) private platformId : Object ) { ... }
ngOnInit ( ) {
if ( isPlatformBrowser ( this . platformId ) ) {
// Client only code.
...
}
if ( isPlatformServer ( this . platformId ) ) {
// Server only code.
...
}
}setTimeout 。它将减慢服务器端渲染过程。确保将它们删除成组件中的ngOnDestroy 。不要直接操纵母语。使用Renderer2 。我们这样做是为了确保在任何环境中都能改变自己的看法。
constructor ( element : ElementRef , renderer : Renderer2 ) {
this . renderer . setStyle ( element . nativeElement , 'font-size' , 'x-large' ) ;
}sass-loader需要node-sass > = 4:在Docker容器或Localhost中运行NPM NPM重建节点sass -f只需在homecontroller中评论逻辑,然后用您的应用程序root appcomponent tag(在我们的情况下,“ app-root”)替换@Html.Raw(ViewData["SpaHtml"]) : <app-root></app-root> 。
您还可以删除任何
isPlatformBrowser/etc逻辑,并删除boot.server,app.module.module.browser&app.module.server文件,只需确保您的boot.browserfile Points toapp.module即可。
检查有关如何使用isPlatformBrowser()陷阱。
您要么要目前要删除SSR,要么等待支持应该来处理平台服务器渲染。现在可以随着最近更新的角材料的变化而进行的。我们还没有一个教程。
注意:如果可能的话,请尝试避免使用依赖于它的jQuery或库,因为有更好的,更抽象的方法可以在Angular(5+)(例如使用渲染器)中处理DOM,例如使用渲染器等。
是的,当然,但是在执行此操作之前,您需要设置一些事情。首先,确保jQuery包含在WebPack供应商文件中,并为其具有WebPack插件。 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })
现在,确保您拥有的任何“插件”等仅包含在boot.browser.ts文件中。 (即: import 'slick-carousel'; )在您要使用jQuery的组件中,请确保将其导入到顶部附近:
import * as $ from 'jquery' ;始终确保在Angular的isPlatformBrowser()条件下包裹任何面向jQuery的东西!
通过IE11在polyfills文件夹中打开polyfills.ts文件,并根据需要将“导入polyfills”取消。另外 - 确保您的webpack.config和webpack.config.vendor更改TerserPlugin从ecma: 6到ecma: 5 。
非常感谢Microsoft的Steve Sanderson(@stevesandersonms)以及他在JavaScriptServices上的出色工作,并将Node的世界与ASP.NET Core整合在一起。
还要感谢许多贡献者!
在这里查看我们的简单问题
没有什么是完美的,但是请通过创建一个问题让我知道(确保还没有现有问题),我们将尝试为此解决一个问题!如果您有任何好主意或想做出贡献,请随意对该提案提出问题,或者只是从叉子中造成公关。
版权(C)2016-2019 Mark Pieszak
查看Trilon.io以获取更多信息! Twitter @trilon_io
通过[email protected]与我们联系,让我们谈谈您的项目需求。
Twitter:@trilon_io