Угловой SEO в действии:


Этот репозиторий поддерживается Trilon.io и Angular Universal Team и предназначен для того, чтобы стать расширенным стартером как для ASP.NET Core 2.1, используя Angular 7.0+, не только для клиента, но и для того, чтобы быть отображаемым на сервере для мгновенных применений (примечание: если вам не нужно, чтобы SSR читал здесь о том, как отключить его).
Это предназначено для того, чтобы быть богатым стартовым приложением, содержащим все новейшие технологии, лучшие системы сборки, и включает в себя множество реальных примеров и библиотек, необходимых в современных приложениях для одностраничных страниц (SPA).
Это использует все последние стандарты, без глотка, без разжигания, без типинга, ни вручного «строительства». NPM, WebPack и .NET обрабатывают все для вас!
Это лишь некоторые из функций, найденных в этом стартере!
ASP.NET 2.1 - VS2017 Поддержка сейчас!
Угловой 7,0.0 :
ng gc components/example-componentng gs shared/some-serviceСистема сборки WebPack (WebPack 4)
Тестирование структуры
Производительность
ASP.NET CORE 2.1
Лазур
npm i -S @markpieszak/ng-application-insights в качестве зависимостей. // Add the Module to your imports
ApplicationInsightsModule . forRoot ( {
instrumentationKey : 'Your-Application-Insights-instrumentationKey'
} )Докер
Убедитесь, что у вас установлен .net Core 2.1 и/или VS2017 15.3. VS2017 автоматически установит все необходимые зависимости NPM и .NET, когда вы откроете проект.
Просто подтолкните F5, чтобы начать отладку!
Docker-поддержка : измените проект запуска на Docker-Compose и нажмите F5
ПРИМЕЧАНИЕ . Если вы получаете какие -либо ошибки после этого, например, module not found: boot.server (или аналогичный), откройте командную строку и запустите npm run build:dev , чтобы убедиться, что все активы были должным образом созданы WebPack.
Примечание. Убедитесь, что у вас установлен C# Extension & .net Core Debugger.
Проект поставляется с файлами настройки запуска unward.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) в одном и том же проекте, но, конечно, все это может быть абстрагировано в совершенно отдельный проект () в идеале. .Net Core Things все сделаны в одном и том же проекте ради простоты.
Файлы корневого уровня
Здесь у нас есть обычные подозреваемые, найденные на корневом уровне.
Фронтовые ориентированные файлы:
package.json - NPM -зависимости проекта и сценариев.tsconfig - Конфигурация TypeScript (здесь мы также настроем пути)webpack - файлы конфигурации (модульная комплексная комплекс + гораздо больше)karma - файлы конфигурации (модульное тестирование)protractor - Config Files (E2E тестирование)tslint - Правила снятия кода типовойДавайте посмотрим на то, как это структурировано, чтобы мы могли понять все это!
С Angular Universal нам нужно разделить нашу логику Applicatoin на платформу, поэтому, если мы посмотрим на эту папку, вы увидите 2 корневые файлы, которые отражают всю логику для браузера и сервера соответственно.
Здесь мы настроем несколько вещей, клиентскую угловую загрузку.
Вам едва нужно коснуться этого файла, но что -то, что нужно отметить, это файл, в котором вы импортируете библиотеки, которые вы хотите использовать только в браузере. (Просто знайте, что вам придется предоставить фиктивную реализацию для сервера при этом).
Обратите внимание на структуру папок здесь, в ./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 При добавлении новых функций/компонентов/и т. Д. В ваше приложение вы обычно добавляете вещи в корневой ngmodule (расположенный в /ClientApp/app/app.module.ts app.module.ts), но почему в этой папке есть два других нгмодула?
Это потому, что мы хотим разделить нашу логику на платформу , но обратите внимание, что они оба делятся общим NGModule с именем app.module.ts . При добавлении большинства вещей в ваше приложение, это единственное место, где вам придется добавить в свой новый компонент / директива / труба / и т. Д. Вам нужно только вручную добавить в платформу конкретные вещи в либо 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 -проектов / и т. Д.
Мы используем MVC в этом приложении, но нам нужен только один контроллер, названный HomeController . Именно здесь все наше угловое приложение сериализуется в строку, отправляется в браузер, вместе со всеми активами, которые ему необходимы, а затем начать на стороне клиента, а затем стать полномасштабным спа-салоном.
Краткая версия заключается в том, что мы вызываем этот процесс узла, передав наш объект запроса и вызовыте файл boot.server , и мы возвращаем хороший объект, который мы переходим в объект .nets ViewData и разбрызгивают наши Views/Shared/_Layout.cshtml и /Views/Home/index.cshtml !
Более подробное объяснение можно найти здесь: ng-aspnetcore-engine readme
// 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 просто отображают приложение и обслуживают в нем файлы в комплекте.
@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 есть несколько вещей, которые следует помнить.
Убедитесь, что вы предоставляете абсолютные URL -адреса при вызове любых API. (Сервер не может понять относительные пути, так что /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 Run npm Rebuild Node-sass -f Просто прокомментируйте логику в HomeController и замените @Html.Raw(ViewData["SpaHtml"]) только на теги root appcomponent ("App-root"): <app-root></app-root> .
Вы также можете удалить любую логику
isPlatformBrowser/etcи удалить файлы boot.server, app.module.browser & app.module.server, просто убедитесь, что ваш файлboot.browserнаapp.module.
Проверьте GotChas о том, как использовать isPlatformBrowser() .
Вы либо захотите удалить SSR на данный момент, либо подождать, так как поддержка должна быть для обработки рендеринга с сервером платформы. Теперь это возможно, с недавно обновленными изменениями угловых материалов. У нас еще нет учебника для этого.
Примечание. Если это вообще возможно, старайтесь избегать использования jQuery или библиотек, зависящих от него, так как есть лучшие, более абстрактные способы работы с DOM в угловых (5+), таких как использование рендеринга и т. Д.
Да, конечно, но есть несколько вещей, которые вам нужно настроить перед этим. Во -первых, убедитесь, что jQuery включен в файл поставщика WebPack, и что у вас есть настройка плагинов WebPack для него. new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })
Теперь убедитесь, что любые «плагины» и т. Д. У вас есть только в вашем файле boot.browser.ts . (IE: import 'slick-carousel'; ) в компоненте, который вы хотите использовать jQuery, обязательно импортируйте его рядом с верхом, как SO:
import * as $ from 'jquery' ; Всегда обязательно оберните что -нибудь jquery, ориентированное на Angular's isPlatformBrowser() .
Чтобы поддержать IE9 через IE11, откройте файл polyfills.ts в папке polyfills и по мере необходимости выстрелить из «импортных полифиллов». Также - убедитесь, что вариант вашего webpack.config и webpack.config.vendor Изменение TerserPlugin с ecma: 6 на ecma: 5 .
Большое спасибо Стиву Сандерсону (@stevesandersonms) из Microsoft и его удивительную работу над Javascriptservices и интеграцией мира узла с Asp.net Core.
Также спасибо многим участникам!
Проверьте наши более простые проблемы здесь
Ничего не идеально, но, пожалуйста, дайте мне знать, создав проблему (убедитесь, что в этом уже нет существующего), и мы постараемся решить для этого! Если у вас есть какие -либо хорошие идеи или вы хотите внести свой вклад, не стесняйтесь либо решать проблему с предложением, либо просто сделать пиар из вашей вилки.
Copyright (C) 2016-2019 Mark Pieszak
Проверьте Trilon.io для получения дополнительной информации! Twitter @trilon_io
Свяжитесь с нами по адресу [email protected], и давайте поговорим о ваших потребностях проектов.
Twitter: @trilon_io