ãšã³ããªãŒ
ãã®èšäºã¯ãAngularã.NET Coreãšçµã¿åãããŠåŠç¿ããããã®æåã®äžæ©ãèžã¿åºãåå¿è ã察象ãšããŠããŸãã
éçºã«Visual Studioã䜿çšããŠããå Žåã¯ãAngularãæ¥ç¶ãããæ¢è£œã®ãããžã§ã¯ããã³ãã¬ãŒãã«æ¢ã«ééããŠããå¯èœæ§ããããŸãã ãããã®ãã³ãã¬ãŒãã䜿çšãããšãæ°åã¯ãªãã¯ããã ãã§ãæ§ææžã¿ã®ã«ãŒã¿ãŒãšããã€ãã®æ¢è£œã®ã³ã³ããŒãã³ããåããã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸãã åäœäžã®ã¢ããªã±ãŒã·ã§ã³ã®æ§æãæå°éã«æããããã«æéãç¡é§ã«ããå¿ èŠã¯ãããŸãããåäœäžã®WebPackãå ±éã³ã³ããŒãã³ãçšã®ç¬ç«ããã¢ãžã¥ãŒã«ãæ§ææžã¿ã®ã«ãŒã¿ãŒãBootstrapãæ¥ç¶æžã¿ã§ãã ãã¹ãŒããŒïŒ ãã£ãããïŒ ååã®äœæ¥ãå®äºããŸããïŒã ããããå®éã«ã¯ããå°ãè€éã§ã...
è€éããšèœãšãç©Žã¯ããã®ã¢ãããŒããšæšæºãã³ãã¬ãŒãã«ã¯ããã€ãã®é倧ãªæ¬ ç¹ããããšããäºå®ã«ãããŸãã
ããŸããŸãªãã¹ããã©ã¯ãã£ã¹ ã«ãããã¢ããªã±ãŒã·ã§ã³ã2ã€ã®å¥åã®ãããžã§ã¯ãã«åå²ããããšããå§ãããŸãããã®å Žåããã®ãããžã§ã¯ãã¯.NET Core Web APIãšAngularãããžã§ã¯ãã§ãã ãã®ã¢ãããŒãã®äž»ãªå©ç¹ã¯æ¬¡ã®ãšããã§ãã
- Webã€ã³ã¿ãŒãã§ã€ã¹ãšãµãŒããŒããŒãã®ããŒãæ¥ç¶
- ã¢ããªã±ãŒã·ã§ã³ã®éåžžã«è€éã§æå°éåäœããããŒãžã§ã³
- Angular CLIã䜿çšã§ããªã
- è¿œå ã®ãã¬ã€ã³ã¹ããŒã«ããã±ãŒãž
- Angular Style Guideã®ããã€ãã®ååãžã®éå
ãã®ã·ããªãªã«ã¯ã2ã€ã®çç£ã·ããªãªããããŸãã
- 2ã€ã®ç¬ç«ãããããžã§ã¯ãããµãŒããŒåŽã§ãããžã§ã¯ãã«è§Šããããšãªãã代æ¿ã€ã³ã¿ãŒãã§ã€ã¹ãããã«å®è£ ã§ããŸãã
- çãã°ããŒãã«æ€çŽ¢ç¯å² ãæ€çŽ¢ãããå¹ççãã€ç°¡åã«ããŸã
- ãµãŒããŒããŒããéçºãããŠããäœæ¥ç°å¢ãããšãã°Visual Studioããæœè±¡å-VS CodeãSublime TextãAtomããŸãã¯äŸ¿å©ãªå¥ã®ãšãã£ã¿ãŒã䜿çšã§ããŸã
ç§ã®ã¿ã¹ã¯ã¯2çªç®ã®ã·ããªãªã«éããªãã£ããããçµæžçãªçç±ããããæãŸãããã®ã§ããã ã§ãããã.NET Core Web APIãããžã§ã¯ããšAngularãããžã§ã¯ããšåéãäœãæ¹æ³ãèŠã€ããããšããŠããã®ã§ã éçºäžã«2ã€ã®å¥ã ã®ãããžã§ã¯ãããããå®çšŒåäžã«1ã€ã ã ãå ·äœçã«ã¯ãããžã§ã¯ãããããŸãã ã NET Core Webãµã€ãã§ã¯ãããŒãããå®çšçãªã¢ããªã±ãŒã·ã§ã³ãŸã§ããšããå®å šãªã¬ã€ããèŠã€ããããšãã§ããŸããã§ããã è±èªã話ããã©ãŒã©ã ãããã°ãããœãªã¥ãŒã·ã§ã³ãã€ãªãåãããå¿ èŠããããŸããã çªç¶åãåé¡ãçºçããå Žåã¯ãç§ã®èšäºãèªãã ãã§ååã§ãã
- ããã¢ãã¬ã¹ã§Webã€ã³ã¿ãŒãã§ãŒã¹ããã¹ãããå¥ã®ã¢ãã¬ã¹ã§ãµãŒããŒããã¹ããã
- ãŸãã¯ã éæ³ã®ããã«ãããžã§ã¯ãã1ã€ã«ãŸãšããŠãããã ãããã¹ãããŸã
è¡ããïŒ
ã§ã¯ãäœã䜿çšããŸããïŒ æ¬¡ã®ãã®ãå¿ èŠã§ãã
Visual Studio 2017ãæ¢ã«ã€ã³ã¹ããŒã«ãããŠãããã€ã³ã¹ããŒã«äžã«.NET Core Developmentãéžæããå Žå㯠ã ãã§ã«.NET Core SDKããããã€ã³ã¹ããŒã«ããå¿ èŠã¯ãããŸããã ãã ãã Node.js éçºãéžæãããŠããå Žåã§ãã Node.js㯠åå¥ã«ã€ã³ã¹ããŒã«ããå¿ èŠããããŸã ã Npmã¯Node.jsãšå ±ã«ã€ã³ã¹ããŒã«ãããŸãã Angular CLIã¯ãã³ãã³ãã©ã€ã³ããnpmãä»ããŠã°ããŒãã«ã«ã€ã³ã¹ããŒã«ãããŸãïŒæé ã¯äžèšã®ãªã³ã¯ã«ãããŸãïŒã
- .NET Core SDK -2.0ããŒãžã§ã³ä»¥äž
- Node.js -8.9.0ããŒãžã§ã³ä»¥é
- npm-5.5.0ããŒãžã§ã³ä»¥é
- Angular CLI -1.6.5以éã®ããŒãžã§ã³
- ããžã¥ã¢ã«ã¹ã¿ãžãªã³ãŒã
次ã«ããã¹ãŠãã€ã³ã¹ããŒã«ãããæºåãã§ããŠãããã©ããã確èªããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãã³ãã³ãããã³ããïŒã¿ãŒããã«ïŒãéãã以äžã®ã³ãã³ããé£ç¶ããŠå®è¡ããŸãã
dotnet --version # .NET Core node --version # Node.js npm --version # npm ng --version # Angular CLI
ã³ãã³ãã©ã€ã³ã®çµæïŒããŒãžã§ã³ã¯ç°ãªãå ŽåããããŸããã倧ããããšã¯ãããŸããïŒ
.NET Core Web APIãããžã§ã¯ãã®äœæ
ãã®èšäºã§ã¯ã.NET CoreããµããŒãããŠãããããã³ãã³ãã©ã€ã³ãšVSã³ãŒãã䜿çšããŠãã¹ãŠã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸãã ãã ãã.NETãããžã§ã¯ãã§ã®äœæ¥ã«Visual Studio 2017ã䜿çšããå Žåã¯ãããã䜿çšããŠãããžã§ã¯ããå®å šã«äœæããã³ç·šéã§ããŸãã
æåã®ã¹ããã
Projectãããžã§ã¯ãã®ã«ãŒããã©ã«ããŒãäœæããVS Codeã§éãã Ctrl +ã ïŒãã«ããæåïŒãæŒããŠã¿ãŒããã«ãèµ·åããŸãã ãããŸã§ã®ãšããè€éãªããšã¯ãããŸãã:)
VSã³ãŒããŠã£ã³ããŠãšå®è¡äžã®ã¿ãŒããã«
第äºæ®µé
次ã«ããããžã§ã¯ããäœæããå¿ èŠããããŸãã ãããè¡ãã«ã¯ã次ã®ã³ãã³ããå®è¡ããŸãã
dotnet new webapi -n Project.WebApi
éããŠãããããžã§ã¯ããšå®è¡äžã®ã¿ãŒããã«ãå«ãVSã³ãŒããŠã£ã³ããŠ
第äžæ®µé
ãã¹ãŠãæ©èœãããã©ããã確èªããŸãã ã¿ãŒããã«ãä»ããŠãæ°ããäœæããããããžã§ã¯ãããããã©ã«ããŒã«ç§»åãããã®åŸã³ãã³ããå®è¡ããŸãã
dotnet run
éããŠãããããžã§ã¯ããšå®è¡äžã®ã¿ãŒããã«ãå«ãVSã³ãŒããŠã£ã³ããŠ
第4ã¹ããã
æåŸã®ã¹ãããã§ãã¹ãŠãããŸããããã Listen ïŒ localhost ïŒ5000ããã³ã³ãœãŒã«ã«è¡šç€ºããããããµãŒããŒã¯æ£åžžã«èµ·åããŸããã localhost ïŒ5000 / api / values ïŒèªåçã«äœæããããã¹ãã³ã³ãããŒã©ãŒïŒã«ç§»åããŸãã ãã¹ãããŒã¿ãå«ãJSONã衚瀺ãããŸãã
ãã©ãŠã¶ã§ã®çµæ
第5ã¹ããã
VS Codeã«æ»ããã¿ãŒããã«ã§Ctrl + CãæŒããŠãµãŒããŒãåæ¢ããŸãã
éããŠãããããžã§ã¯ããšå®è¡äžã®ã¿ãŒããã«ãå«ãVSã³ãŒããŠã£ã³ããŠ
è§åºŠãããžã§ã¯ãã®äœæ
次ã«ãAngularãããžã§ã¯ããäœæããŸãã ãã®ããã«ãAngular CLIãVS Codeã³ãã³ããããã³ãã«ãã€ã³ã¿ãŒããã«ã䜿çšããŸãã
æåã®ã¹ããã
ã¿ãŒããã«ã§ãProject ãããžã§ã¯ãã®ã«ãŒããã©ã«ããŒã«ç§»åãã Project.Angularãšããæ°ãããããžã§ã¯ããäœæããŸãïŒå°ãåŸ ã€å¿ èŠããããŸãïŒã
cd ..\ ng new Project.Angular
éããŠãããããžã§ã¯ããšå®è¡äžã®ã¿ãŒããã«ãå«ãVSã³ãŒããŠã£ã³ããŠ
第äºæ®µé
ã¿ãŒããã«ã§ãæ°ããäœæãããããžã§ã¯ãã®ãã©ã«ããŒã«ç§»åããŠå®è¡ããŸãã
cd ./Project.Angular ng serve --open
éããŠãããããžã§ã¯ããšå®è¡äžã®ã¿ãŒããã«ãå«ãVSã³ãŒããŠã£ã³ããŠ
第äžæ®µé
æåŸã®ã¹ãããã§ãã¹ãŠãããŸãããã NG Live Development Serverãlocalhostã§ãªãã¹ã³ããŠããå ŽåïŒ4200ãã³ã³ãœãŒã«ã«è¡šç€ºããããµãŒããŒã¯æ£åžžã«èµ·åããŸããã localhost ïŒ4200ã«ç§»åããŸãã Angularãã¹ãããŒãžã衚瀺ãããŸãã
ãã©ãŠã¶ã§ã®çµæ
第4ã¹ããã
VS Codeã«æ»ããã¿ãŒããã«ã§Ctrl + CãæŒãã Yãå ¥åããŠãµãŒããŒãåæ¢ããŸãã
éããŠãããããžã§ã¯ããšå®è¡äžã®ã¿ãŒããã«ãå«ãVSã³ãŒããŠã£ã³ããŠ
Angularãããžã§ã¯ããã»ããã¢ãããã
次ã«ã2ã€ã®ããšãæ§æããå¿ èŠããããŸããproxy.config.jsonã䜿çšããŠããµãŒããŒãžã®èŠæ±ãç®çã®ããŒãã«ãªãã€ã¬ã¯ãããŸããæãéèŠãªã®ã¯ãwwwrootãã©ã«ããŒã§ã¢ã»ã³ããªãæ§æããããšã§ãã
æåã®ã¹ããã
Project.Angularãããžã§ã¯ãã®ã«ãŒãã«proxy.config.jsonãšãããã¡ã€ã«ãäœæãã次ã®å 容ãè¿œå ããŸãã
{ "/api/*": { "target": "http://localhost:5000/", "secure": false, "logLevel": "debug" } }
proxy.config.json
{ "/api/*": { "target": "http://localhost:5000/", "secure": false, "logLevel": "debug" } }
ãã®èšå®ã¯ã/ api / ...ã§å§ãŸããã¹ãŠã®èŠæ±ãlocalhost ïŒ5000 /ã«éä¿¡ãããããšã瀺ããŸãã ã€ãŸããçµæã®ã¯ãšãªã¯localhost ïŒ5000 / api / ...
第äºæ®µé
éçºã¢ãŒãã§ã¯ãã®proxy.configã䜿çšããå¿ èŠãããããšãAngularã«äŒããŸãã ãããè¡ãã«ã¯ã package.jsonãã¡ã€ã«ïŒåãã«ãŒãã«ãããŸãïŒãéãã scripts- > startã³ãã³ããèŠã€ããŠãå€ã次ã®ããã«çœ®ãæããŸãã
{ ... scripts: { ... "start": "ng serve --proxy-config proxy.config.json", } }
package.json
{ { "name": "project.angular", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.config.json", "build": "ng build --prod", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "^5.2.0", "@angular/common": "^5.2.0", "@angular/compiler": "^5.2.0", "@angular/core": "^5.2.0", "@angular/forms": "^5.2.0", "@angular/http": "^5.2.0", "@angular/platform-browser": "^5.2.0", "@angular/platform-browser-dynamic": "^5.2.0", "@angular/router": "^5.2.0", "core-js": "^2.4.1", "rxjs": "^5.5.6", "zone.js": "^0.8.19" }, "devDependencies": { "@angular/cli": "1.6.7", "@angular/compiler-cli": "^5.2.0", "@angular/language-service": "^5.2.0", "@types/jasmine": "~2.8.3", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "codelyzer": "^4.0.1", "jasmine-core": "~2.8.0", "jasmine-spec-reporter": "~4.2.1", "karma": "~2.0.0", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.1.2", "ts-node": "~4.1.0", "tslint": "~5.9.1", "typescript": "~2.5.3" } } }
å°æ¥ãAngularãããžã§ã¯ããéå§ããã«ã¯ã ng serveãšäžç·ã«npm startã³ãã³ãã䜿çšããŸãã npm startã³ãã³ãã¯ãpackage.jsonã§æå®ããã³ãã³ãã®çç¥åœ¢ã§ãã
第äžæ®µé
æåŸã®ã¹ãããã¯ããããžã§ã¯ãã®wwwroot .NET Core Web APIã§ãããžã§ã¯ãã®ãã«ãïŒã³ãã³ãäžïŒãåçŽã«æ§æããããšã§ãã éããŠããpackage.jsonãã¡ã€ã«ã§ã ã¹ã¯ãªãã-> buildã³ãã³ããèŠã€ããŠãå€ã次ã®ãã®ã«çœ®ãæããŸãã
{ ... scripts: { ... "build": "ng build --prod --output-path ../Project.WebApi/wwwroot", } }
package.json
{ { "name": "project.angular", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve --proxy-config proxy.config.json", "build": "ng build --prod --output-path ../Project.WebApi/wwwroot", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "^5.2.0", "@angular/common": "^5.2.0", "@angular/compiler": "^5.2.0", "@angular/core": "^5.2.0", "@angular/forms": "^5.2.0", "@angular/http": "^5.2.0", "@angular/platform-browser": "^5.2.0", "@angular/platform-browser-dynamic": "^5.2.0", "@angular/router": "^5.2.0", "core-js": "^2.4.1", "rxjs": "^5.5.6", "zone.js": "^0.8.19" }, "devDependencies": { "@angular/cli": "1.6.7", "@angular/compiler-cli": "^5.2.0", "@angular/language-service": "^5.2.0", "@types/jasmine": "~2.8.3", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "codelyzer": "^4.0.1", "jasmine-core": "~2.8.0", "jasmine-spec-reporter": "~4.2.1", "karma": "~2.0.0", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.1.2", "ts-node": "~4.1.0", "tslint": "~5.9.1", "typescript": "~2.5.3" } } }
ãã®ã¢ã¯ã·ã§ã³ãå®è¡ããã«ã¯ãã¿ãŒããã«ã§npm run buildã³ãã³ããå®è¡ããŸãã çµæã¯ãwwwrootãã©ã«ããŒã«åéããããããžã§ã¯ããã¡ã€ã«ã«ãªããŸãã
.NET Core Web APIãããžã§ã¯ããã»ããã¢ãããã
ãµãŒããŒã«éçãã¡ã€ã«ãæäœããå¥ã®ããŒãããã®èŠæ±ãèš±å¯ããããã«æããããšã¯æ®ã£ãŠããŸãã
æåã®ã¹ããã
Startup.csãéãããµãŒããŒãéçãã¡ã€ã«ãåŠçã§ããããã«ããè¡ãConfigureã¡ãœããã«è¿œå ããŸãã
app.UseDefaultFiles(); app.UseStaticFiles();
Startup.csã®ã¡ãœãããæ§æãã
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseDefaultFiles(); app.UseStaticFiles(); app.UseMvc(); }
第äºæ®µé
Startup.csã®Configureã¡ãœããã§ããµãŒããŒãããŒã4200ããã®èŠæ±ãåãå ¥ããããšãèš±å¯ããè¡ãè¿œå ããŸãã
app.UseCors(builder => builder.WithOrigins("http://localhost:4200"));
Startup.csã®ã¡ãœãããæ§æãã
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseDefaultFiles(); app.UseStaticFiles(); app.UseCors(builder => builder.WithOrigins("http://localhost:4200")); app.UseMvc(); }
第äžæ®µé
ConfigureServicesã¡ãœããã§ãCORSãµããŒããè¿œå ããŸãã
services.AddCors();
Startup.csã®ConfigureServicesã¡ãœãã
public void ConfigureServices(IServiceCollection services) { services.AddCors(); services.AddMvc(); }
æçµçã«ãStartup.csãã¡ã€ã«ã«ã¯æ¬¡ã®å 容ãå«ãŸããŠããå¿ èŠããããŸãã
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace Project.WebApi { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddCors(); // <-- } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseDefaultFiles(); // <-- app.UseStaticFiles(); // <-- app.UseCors(builder => builder.WithOrigins("http://localhost:4200")); // <-- :) app.UseMvc(); } } }
ã§ããïŒ ããã§ãAngularãããžã§ã¯ãããAPIã³ã³ãããŒã©ãŒã«å®å šã«ã¢ã¯ã»ã¹ã§ããŸãã ãŸããAngularãããžã§ã¯ãã«å¯ŸããŠnpm run buildã³ãã³ããåŒã³åºãããšã«ãããWeb APIã¢ããªã±ãŒã·ã§ã³ã®ããŒãžã§ã³ããããã€ããæºåãæŽããŸãã
ãããã«
ããã¯ã2ã€ã®å¥åã®ãããžã§ã¯ããäœæããããããå šäœãšããŠæ©èœãããããã«äœãããå¿ èŠããããã«ã€ããŠã®çãã¬ã€ãã§ããã
CORSã®æ§æãšãã«ãã£ã³ã°ãªãŒãã¡ãŒã·ã§ã³ã¯ãå®çšŒåããŒãžã§ã³ã®ãµããããŸããã ãã ããã©ãã調ã¹ãŠæãããç¥ã£ãŠããŸãã ç§ã®èšäºã誰ãã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã å人çã«ã¯ãããã2ã€ã®ãã¯ãããžãŒéã®éä¿¡ã確ç«ããããšããŠããååãªãã®ããããŸããã§ããã
ãã®èšäºã§ã¯ãWeb APIãããžã§ã¯ãã§ã®ã«ãŒãã£ã³ã°ãããæè»ãªCORSæ§æãèªåã¢ã»ã³ããªãªã©ã«é¢ããããã€ãã®ãã€ã³ãã¯åãäžããŸããã§ããã ãã®ãããªã¢ããªã±ãŒã·ã§ã³ããªã¢ã³ãã®è£œåããŒãžã§ã³ãã¢ã»ã³ãã«ããæ¹æ³ã«ã€ããŠããã詳现ãªèšäºãæžãäºå®ã§ãã çªç¶è³ªåãããå Žåã¯ãã³ã¡ã³ããŸãã¯ãããã¡ã€ã«ã§æå®ãããé£çµ¡å ã®ããããã«æžã蟌ã¿ãç§ã¯ããªããå©ããããšããŸãã