mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-24 02:30:13 +00:00
Fix templates directory structure to produce correct nupkg output
This commit is contained in:
236
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/react/.gitignore
vendored
Normal file
236
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/react/.gitignore
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/Properties/launchSettings.json
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
bin/
|
||||
Bin/
|
||||
obj/
|
||||
Obj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
/wwwroot/dist/
|
||||
|
||||
/yarn.lock
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
/node_modules
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/dotnetcli.host",
|
||||
"symbolInfo": {
|
||||
"TargetFrameworkOverride": {
|
||||
"isHidden": "true",
|
||||
"longName": "target-framework-override",
|
||||
"shortName": ""
|
||||
},
|
||||
"Framework": {
|
||||
"longName": "framework"
|
||||
},
|
||||
"skipRestore": {
|
||||
"longName": "no-restore",
|
||||
"shortName": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"author": "Microsoft",
|
||||
"classifications": [
|
||||
"Web",
|
||||
"MVC",
|
||||
"SPA"
|
||||
],
|
||||
"groupIdentity": "Microsoft.DotNet.Web.Spa.ProjectTemplates.React",
|
||||
"identity": "Microsoft.DotNet.Web.Spa.ProjectTemplates.React.CSharp",
|
||||
"name": "ASP.NET Core with React.js",
|
||||
"preferNameDirectory": true,
|
||||
"primaryOutputs": [
|
||||
{
|
||||
"path": "ReactSpa.csproj"
|
||||
}
|
||||
],
|
||||
"shortName": "react",
|
||||
"sourceName": "ReactSpa",
|
||||
"sources": [
|
||||
{
|
||||
"source": "./",
|
||||
"target": "./",
|
||||
"exclude": [
|
||||
".template.config/**"
|
||||
]
|
||||
}
|
||||
],
|
||||
"symbols": {
|
||||
"TargetFrameworkOverride": {
|
||||
"type": "parameter",
|
||||
"description": "Overrides the target framework",
|
||||
"replaces": "TargetFrameworkOverride",
|
||||
"datatype": "string",
|
||||
"defaultValue": ""
|
||||
},
|
||||
"Framework": {
|
||||
"type": "parameter",
|
||||
"description": "The target framework for the project.",
|
||||
"datatype": "choice",
|
||||
"choices": [
|
||||
{
|
||||
"choice": "netcoreapp2.0",
|
||||
"description": "Target netcoreapp2.0"
|
||||
}
|
||||
],
|
||||
"replaces": "netcoreapp2.0",
|
||||
"defaultValue": "netcoreapp2.0"
|
||||
},
|
||||
"HostIdentifier": {
|
||||
"type": "bind",
|
||||
"binding": "HostIdentifier"
|
||||
},
|
||||
"skipRestore": {
|
||||
"type": "parameter",
|
||||
"datatype": "bool",
|
||||
"description": "If specified, skips the automatic restore of the project on create.",
|
||||
"defaultValue": "false"
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"language": "C#",
|
||||
"type": "project"
|
||||
},
|
||||
"postActions": [
|
||||
{
|
||||
"condition": "(!skipRestore)",
|
||||
"description": "Restore NuGet packages required by this project.",
|
||||
"manualInstructions": [
|
||||
{
|
||||
"text": "Run 'dotnet restore'"
|
||||
}
|
||||
],
|
||||
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
|
||||
"continueOnError": true
|
||||
},
|
||||
{
|
||||
"condition": "(HostIdentifier == \"dotnetcli\" || HostIdentifier == \"dotnetcli-preview\")",
|
||||
"actionId": "AC1156F7-BB77-4DB8-B28F-24EEBCCA1E5C",
|
||||
"description": "\n\n-------------------------------------------------------------------\nIMPORTANT: Before running this project on the command line,\n you must restore NPM packages by running \"npm install\"\n-------------------------------------------------------------------\n",
|
||||
"manualInstructions": [
|
||||
{
|
||||
"text": "Run \"npm install\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/vs-2017.3.host",
|
||||
"name": {
|
||||
"text": "React.js",
|
||||
"package": "{0CD94836-1526-4E85-87D3-FB5274C5AFC9}",
|
||||
"id": "1500"
|
||||
},
|
||||
"description": {
|
||||
"text": "A project template for creating an ASP.NET Core application with React.js",
|
||||
"package": "{0CD94836-1526-4E85-87D3-FB5274C5AFC9}",
|
||||
"id": "1501"
|
||||
},
|
||||
"order": 301,
|
||||
"icon": "icon.png",
|
||||
"learnMoreLink": "https://github.com/aspnet/JavaScriptServices",
|
||||
"uiFilters": [
|
||||
"oneaspnet"
|
||||
],
|
||||
"minFullFrameworkVersion": "4.6.1"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import './css/site.css';
|
||||
import 'bootstrap';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { AppContainer } from 'react-hot-loader';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import * as RoutesModule from './routes';
|
||||
let routes = RoutesModule.routes;
|
||||
|
||||
function renderApp() {
|
||||
// This code starts up the React app when it runs in a browser. It sets up the routing
|
||||
// configuration and injects the app into a DOM element.
|
||||
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
|
||||
ReactDOM.render(
|
||||
<AppContainer>
|
||||
<BrowserRouter children={ routes } basename={ baseUrl } />
|
||||
</AppContainer>,
|
||||
document.getElementById('react-app')
|
||||
);
|
||||
}
|
||||
|
||||
renderApp();
|
||||
|
||||
// Allow Hot Module Replacement
|
||||
if (module.hot) {
|
||||
module.hot.accept('./routes', () => {
|
||||
routes = require<typeof RoutesModule>('./routes').routes;
|
||||
renderApp();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import * as React from 'react';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
|
||||
interface CounterState {
|
||||
currentCount: number;
|
||||
}
|
||||
|
||||
export class Counter extends React.Component<RouteComponentProps<{}>, CounterState> {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { currentCount: 0 };
|
||||
}
|
||||
|
||||
public render() {
|
||||
return <div>
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p>This is a simple example of a React component.</p>
|
||||
|
||||
<p>Current count: <strong>{ this.state.currentCount }</strong></p>
|
||||
|
||||
<button onClick={ () => { this.incrementCounter() } }>Increment</button>
|
||||
</div>;
|
||||
}
|
||||
|
||||
incrementCounter() {
|
||||
this.setState({
|
||||
currentCount: this.state.currentCount + 1
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import * as React from 'react';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
import 'isomorphic-fetch';
|
||||
|
||||
interface FetchDataExampleState {
|
||||
forecasts: WeatherForecast[];
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
export class FetchData extends React.Component<RouteComponentProps<{}>, FetchDataExampleState> {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { forecasts: [], loading: true };
|
||||
|
||||
fetch('api/SampleData/WeatherForecasts')
|
||||
.then(response => response.json() as Promise<WeatherForecast[]>)
|
||||
.then(data => {
|
||||
this.setState({ forecasts: data, loading: false });
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
let contents = this.state.loading
|
||||
? <p><em>Loading...</em></p>
|
||||
: FetchData.renderForecastsTable(this.state.forecasts);
|
||||
|
||||
return <div>
|
||||
<h1>Weather forecast</h1>
|
||||
<p>This component demonstrates fetching data from the server.</p>
|
||||
{ contents }
|
||||
</div>;
|
||||
}
|
||||
|
||||
private static renderForecastsTable(forecasts: WeatherForecast[]) {
|
||||
return <table className='table'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{forecasts.map(forecast =>
|
||||
<tr key={ forecast.dateFormatted }>
|
||||
<td>{ forecast.dateFormatted }</td>
|
||||
<td>{ forecast.temperatureC }</td>
|
||||
<td>{ forecast.temperatureF }</td>
|
||||
<td>{ forecast.summary }</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>;
|
||||
}
|
||||
}
|
||||
|
||||
interface WeatherForecast {
|
||||
dateFormatted: string;
|
||||
temperatureC: number;
|
||||
temperatureF: number;
|
||||
summary: string;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import * as React from 'react';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
|
||||
export class Home extends React.Component<RouteComponentProps<{}>, {}> {
|
||||
public render() {
|
||||
return <div>
|
||||
<h1>Hello, world!</h1>
|
||||
<p>Welcome to your new single-page application, built with:</p>
|
||||
<ul>
|
||||
<li><a href='https://get.asp.net/'>ASP.NET Core</a> and <a href='https://msdn.microsoft.com/en-us/library/67ef8sbd.aspx'>C#</a> for cross-platform server-side code</li>
|
||||
<li><a href='https://facebook.github.io/react/'>React</a> and <a href='http://www.typescriptlang.org/'>TypeScript</a> for client-side code</li>
|
||||
<li><a href='https://webpack.github.io/'>Webpack</a> for building and bundling client-side resources</li>
|
||||
<li><a href='http://getbootstrap.com/'>Bootstrap</a> for layout and styling</li>
|
||||
</ul>
|
||||
<p>To help you get started, we've also set up:</p>
|
||||
<ul>
|
||||
<li><strong>Client-side navigation</strong>. For example, click <em>Counter</em> then <em>Back</em> to return here.</li>
|
||||
<li><strong>Webpack dev middleware</strong>. In development mode, there's no need to run the <code>webpack</code> build tool. Your client-side resources are dynamically built on demand. Updates are available as soon as you modify any file.</li>
|
||||
<li><strong>Hot module replacement</strong>. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, rebuilt React components will be injected directly into your running application, preserving its live state.</li>
|
||||
<li><strong>Efficient production builds</strong>. In production mode, development-time features are disabled, and the <code>webpack</code> build tool produces minified static CSS and JavaScript files.</li>
|
||||
</ul>
|
||||
<h4>Going further</h4>
|
||||
<p>
|
||||
For larger applications, or for server-side prerendering (i.e., for <em>isomorphic</em> or <em>universal</em> applications), you should consider using a Flux/Redux-like architecture.
|
||||
You can generate an ASP.NET Core application with React and Redux using <code>dotnet new reactredux</code> instead of using this template.
|
||||
</p>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import * as React from 'react';
|
||||
import { NavMenu } from './NavMenu';
|
||||
|
||||
export interface LayoutProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export class Layout extends React.Component<LayoutProps, {}> {
|
||||
public render() {
|
||||
return <div className='container-fluid'>
|
||||
<div className='row'>
|
||||
<div className='col-sm-3'>
|
||||
<NavMenu />
|
||||
</div>
|
||||
<div className='col-sm-9'>
|
||||
{ this.props.children }
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import * as React from 'react';
|
||||
import { Link, NavLink } from 'react-router-dom';
|
||||
|
||||
export class NavMenu extends React.Component<{}, {}> {
|
||||
public render() {
|
||||
return <div className='main-nav'>
|
||||
<div className='navbar navbar-inverse'>
|
||||
<div className='navbar-header'>
|
||||
<button type='button' className='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>
|
||||
<span className='sr-only'>Toggle navigation</span>
|
||||
<span className='icon-bar'></span>
|
||||
<span className='icon-bar'></span>
|
||||
<span className='icon-bar'></span>
|
||||
</button>
|
||||
<Link className='navbar-brand' to={ '/' }>ReactSpa</Link>
|
||||
</div>
|
||||
<div className='clearfix'></div>
|
||||
<div className='navbar-collapse collapse'>
|
||||
<ul className='nav navbar-nav'>
|
||||
<li>
|
||||
<NavLink to={ '/' } exact activeClassName='active'>
|
||||
<span className='glyphicon glyphicon-home'></span> Home
|
||||
</NavLink>
|
||||
</li>
|
||||
<li>
|
||||
<NavLink to={ '/counter' } activeClassName='active'>
|
||||
<span className='glyphicon glyphicon-education'></span> Counter
|
||||
</NavLink>
|
||||
</li>
|
||||
<li>
|
||||
<NavLink to={ '/fetchdata' } activeClassName='active'>
|
||||
<span className='glyphicon glyphicon-th-list'></span> Fetch data
|
||||
</NavLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
.main-nav li .glyphicon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* Highlighting rules for nav menu items */
|
||||
.main-nav li a.active,
|
||||
.main-nav li a.active:hover,
|
||||
.main-nav li a.active:focus {
|
||||
background-color: #4189C7;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Keep the nav menu independent of scrolling and on top of other items */
|
||||
.main-nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
/* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */
|
||||
body {
|
||||
padding-top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
/* On small screens, convert the nav menu to a vertical sidebar */
|
||||
.main-nav {
|
||||
height: 100%;
|
||||
width: calc(25% - 20px);
|
||||
}
|
||||
.main-nav .navbar {
|
||||
border-radius: 0px;
|
||||
border-width: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
.main-nav .navbar-header {
|
||||
float: none;
|
||||
}
|
||||
.main-nav .navbar-collapse {
|
||||
border-top: 1px solid #444;
|
||||
padding: 0px;
|
||||
}
|
||||
.main-nav .navbar ul {
|
||||
float: none;
|
||||
}
|
||||
.main-nav .navbar li {
|
||||
float: none;
|
||||
font-size: 15px;
|
||||
margin: 6px;
|
||||
}
|
||||
.main-nav .navbar li a {
|
||||
padding: 10px 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.main-nav .navbar a {
|
||||
/* If a menu item's text is too long, truncate it */
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import * as React from 'react';
|
||||
import { Route } from 'react-router-dom';
|
||||
import { Layout } from './components/Layout';
|
||||
import { Home } from './components/Home';
|
||||
import { FetchData } from './components/FetchData';
|
||||
import { Counter } from './components/Counter';
|
||||
|
||||
export const routes = <Layout>
|
||||
<Route exact path='/' component={ Home } />
|
||||
<Route path='/counter' component={ Counter } />
|
||||
<Route path='/fetchdata' component={ FetchData } />
|
||||
</Layout>;
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ReactSpa.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Error()
|
||||
{
|
||||
ViewData["RequestId"] = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ReactSpa.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
public class SampleDataController : Controller
|
||||
{
|
||||
private static string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public IEnumerable<WeatherForecast> WeatherForecasts()
|
||||
{
|
||||
var rng = new Random();
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
DateFormatted = DateTime.Now.AddDays(index).ToString("d"),
|
||||
TemperatureC = rng.Next(-20, 55),
|
||||
Summary = Summaries[rng.Next(Summaries.Length)]
|
||||
});
|
||||
}
|
||||
|
||||
public class WeatherForecast
|
||||
{
|
||||
public string DateFormatted { get; set; }
|
||||
public int TemperatureC { get; set; }
|
||||
public string Summary { get; set; }
|
||||
|
||||
public int TemperatureF
|
||||
{
|
||||
get
|
||||
{
|
||||
return 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ReactSpa
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
BuildWebHost(args).Run();
|
||||
}
|
||||
|
||||
public static IWebHost BuildWebHost(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--/-:cnd:noEmit -->
|
||||
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||
<!-- Ensure Node.js is installed -->
|
||||
<Exec Command="node --version" ContinueOnError="true">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
|
||||
</Exec>
|
||||
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
|
||||
|
||||
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||
a different machine, so rebuild them if not already present. -->
|
||||
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||
</Target>
|
||||
<!--/+:cnd:noEmit -->
|
||||
|
||||
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||
<Exec Command="npm install" />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js --env.prod" />
|
||||
|
||||
<!-- Include the newly-built files in the publish output -->
|
||||
<ItemGroup>
|
||||
<DistFiles Include="wwwroot\dist\**" />
|
||||
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
|
||||
<RelativePath>%(DistFiles.Identity)</RelativePath>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</ResolvedFileToPublish>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.SpaServices.Webpack;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ReactSpa
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
|
||||
{
|
||||
HotModuleReplacement = true,
|
||||
ReactHotModuleReplacement = true
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
routes.MapSpaFallbackRoute(
|
||||
name: "spa-fallback",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div id="react-app">Loading...</div>
|
||||
|
||||
@section scripts {
|
||||
<script src="~/dist/main.js" asp-append-version="true"></script>
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (!string.IsNullOrEmpty((string)ViewData["RequestId"]))
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@ViewData["RequestId"]</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
||||
</p>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - ReactSpa</title>
|
||||
<base href="~/" />
|
||||
|
||||
<link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true" />
|
||||
<environment exclude="Development">
|
||||
<link rel="stylesheet" href="~/dist/site.css" asp-append-version="true" />
|
||||
</environment>
|
||||
</head>
|
||||
<body>
|
||||
@RenderBody()
|
||||
|
||||
<script src="~/dist/vendor.js" asp-append-version="true"></script>
|
||||
@RenderSection("scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
@using ReactSpa
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper *, Microsoft.AspNetCore.SpaServices
|
||||
@@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3377
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/react/npm-shrinkwrap.json
generated
Normal file
3377
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/react/npm-shrinkwrap.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "ReactSpa",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"devDependencies": {
|
||||
"@types/history": "4.6.0",
|
||||
"@types/react": "15.0.35",
|
||||
"@types/react-dom": "15.5.1",
|
||||
"@types/react-hot-loader": "3.0.3",
|
||||
"@types/react-router": "4.0.12",
|
||||
"@types/react-router-dom": "4.0.5",
|
||||
"@types/webpack-env": "1.13.0",
|
||||
"aspnet-webpack": "^2.0.1",
|
||||
"aspnet-webpack-react": "^3.0.0",
|
||||
"awesome-typescript-loader": "3.2.1",
|
||||
"bootstrap": "3.3.7",
|
||||
"css-loader": "0.28.4",
|
||||
"event-source-polyfill": "0.0.9",
|
||||
"extract-text-webpack-plugin": "2.1.2",
|
||||
"file-loader": "0.11.2",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"jquery": "3.2.1",
|
||||
"json-loader": "0.5.4",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1",
|
||||
"react-hot-loader": "3.0.0-beta.7",
|
||||
"react-router-dom": "4.1.1",
|
||||
"style-loader": "0.18.2",
|
||||
"typescript": "2.4.1",
|
||||
"url-loader": "0.5.9",
|
||||
"webpack": "2.5.1",
|
||||
"webpack-hot-middleware": "2.18.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"target": "es5",
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"strict": true,
|
||||
"types": ["webpack-env"]
|
||||
},
|
||||
"exclude": [
|
||||
"bin",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
|
||||
const bundleOutputDir = './wwwroot/dist';
|
||||
|
||||
module.exports = (env) => {
|
||||
const isDevBuild = !(env && env.prod);
|
||||
return [{
|
||||
stats: { modules: false },
|
||||
entry: { 'main': './ClientApp/boot.tsx' },
|
||||
resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
|
||||
output: {
|
||||
path: path.join(__dirname, bundleOutputDir),
|
||||
filename: '[name].js',
|
||||
publicPath: 'dist/'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' },
|
||||
{ test: /\.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader?minimize' }) },
|
||||
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new CheckerPlugin(),
|
||||
new webpack.DllReferencePlugin({
|
||||
context: __dirname,
|
||||
manifest: require('./wwwroot/dist/vendor-manifest.json')
|
||||
})
|
||||
].concat(isDevBuild ? [
|
||||
// Plugins that apply in development builds only
|
||||
new webpack.SourceMapDevToolPlugin({
|
||||
filename: '[file].map', // Remove this line if you prefer inline source maps
|
||||
moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
|
||||
})
|
||||
] : [
|
||||
// Plugins that apply in production builds only
|
||||
new webpack.optimize.UglifyJsPlugin(),
|
||||
new ExtractTextPlugin('site.css')
|
||||
])
|
||||
}];
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
|
||||
module.exports = (env) => {
|
||||
const extractCSS = new ExtractTextPlugin('vendor.css');
|
||||
const isDevBuild = !(env && env.prod);
|
||||
return [{
|
||||
stats: { modules: false },
|
||||
resolve: {
|
||||
extensions: [ '.js' ]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' },
|
||||
{ test: /\.css(\?|$)/, use: extractCSS.extract([ isDevBuild ? 'css-loader' : 'css-loader?minimize' ]) }
|
||||
]
|
||||
},
|
||||
entry: {
|
||||
vendor: ['bootstrap', 'bootstrap/dist/css/bootstrap.css', 'event-source-polyfill', 'isomorphic-fetch', 'react', 'react-dom', 'react-router-dom', 'jquery'],
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, 'wwwroot', 'dist'),
|
||||
publicPath: 'dist/',
|
||||
filename: '[name].js',
|
||||
library: '[name]_[hash]',
|
||||
},
|
||||
plugins: [
|
||||
extractCSS,
|
||||
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
|
||||
new webpack.DllPlugin({
|
||||
path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
|
||||
name: '[name]_[hash]'
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': isDevBuild ? '"development"' : '"production"'
|
||||
})
|
||||
].concat(isDevBuild ? [] : [
|
||||
new webpack.optimize.UglifyJsPlugin()
|
||||
])
|
||||
}];
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Reference in New Issue
Block a user