Skip to content

Commit b4fd30d

Browse files
Add links and syntax highlighting to SpaServices README.md
1 parent 266ea88 commit b4fd30d

File tree

1 file changed

+27
-26
lines changed
  • src/Microsoft.AspNetCore.SpaServices

1 file changed

+27
-26
lines changed

src/Microsoft.AspNetCore.SpaServices/README.md

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ If you're building an ASP.NET Core application, and want to use Angular 2, React
44

55
This package enables:
66

7-
* [**Server-side prerendering**](#server-sideprerendering) for *universal* (a.k.a. *isomorphic*) applications, where your Angular 2 / React / etc. components are first rendered on the server, and then transferred to the client where execution continues
7+
* [**Server-side prerendering**](#server-side-prerendering) for *universal* (a.k.a. *isomorphic*) applications, where your Angular 2 / React / etc. components are first rendered on the server, and then transferred to the client where execution continues
88
* [**Webpack middleware**](#webpack-dev-middleware) so that, during development, any webpack-build resources will be generated on demand, without you having to run webpack manually or compile files to disk
99
* [**Hot module replacement**](#webpack-hot-module-replacement) so that, during development, your code and markup changes will be sent to your browser and updated in the running application, without even needing to reload the page
1010
* [**Routing helpers**](#routing-helper-mapspafallbackroute) for integrating server-side routing with client-side routing
@@ -59,7 +59,7 @@ If you run your application now, and browse to whatever page renders the view yo
5959

6060
Create a JavaScript file at the path matching the `asp-prerender-module` value you specified above. In this example, that means creating a folder called `ClientApp` at the root of your project, and creating a file inside it called `boot-server.js`. Try putting the following into it:
6161

62-
```
62+
```javascript
6363
module.exports = function(params) {
6464
return new Promise(function (resolve, reject) {
6565
var result = '<h1>Hello world!</h1>'
@@ -80,13 +80,15 @@ As you can see, your JavaScript code receives context information (such as the U
8080

8181
If you want to pass some contextual data from your server-side code to your client-side code (for example, to avoid having to load the same data you just loaded on the server again on the client), you can supply a `globals` object alongside the initial `html`, e.g.:
8282

83-
resolve({
84-
html: result,
85-
globals: {
86-
albumsList: someDataHere,
87-
userData: someMoreDataHere
88-
}
89-
});
83+
```javascript
84+
resolve({
85+
html: result,
86+
globals: {
87+
albumsList: someDataHere,
88+
userData: someMoreDataHere
89+
}
90+
});
91+
```
9092

9193
When the `aspnet-prerender-*` tag helper emits this result into the document, as well as injecting the `html` string, it will also emit code that populates `window.albumsList` and `window.userData` with JSON-serialized copies of the objects you passed.
9294

@@ -118,7 +120,7 @@ Let's say you want to write your boot module and SPA code in TypeScript. First e
118120

119121
Next, create a file `webpack.config.js` at the root of your project, containing:
120122

121-
```
123+
```javascript
122124
module.exports = {
123125
resolve: { extensions: [ '', '.js', '.ts' ] },
124126
module: {
@@ -133,7 +135,7 @@ This tells webpack that it should compile `.ts` files using TypeScript, and that
133135

134136
Now you can delete `ClientApp/boot-server.js`, and in its place, create `ClientApp/boot-server.ts`, containing the TypeScript equivalent of what you had before:
135137

136-
```
138+
```javascript
137139
export default function (params: any): Promise<{ html: string}> {
138140
return new Promise((resolve, reject) => {
139141
const html = `
@@ -181,7 +183,7 @@ React components can be executed synchronously on the server quite easily, altho
181183

182184
Let's say you want to write a React component in ES2015 code. You might install the NPM modules `react react-dom babel-loader babel-preset-react babel-preset-es2015`, and then prepare Webpack to build `.jsx` files by creating `webpack.config.js` in your project root, containing:
183185

184-
```
186+
```javascript
185187
var path = require('path');
186188

187189
module.exports = {
@@ -203,15 +205,15 @@ module.exports = {
203205

204206
You will also need a `.babelrc` file in your project root, containing:
205207

206-
```
208+
```javascript
207209
{
208210
"presets": ["es2015", "react"]
209211
}
210212
```
211213

212214
This is enough to be able to build ES2015 `.jsx` files via Webpack. Now you could implement a simple React component, for example the following at `ClientApp/react-app.jsx`:
213215

214-
```
216+
```javascript
215217
import * as React from 'react';
216218

217219
export class HelloMessage extends React.Component
@@ -224,21 +226,21 @@ export class HelloMessage extends React.Component
224226

225227
... and the following code to run it in a browser at `ClientApp/boot-client.jsx`:
226228

227-
```
229+
```javascript
228230
import * as React from 'react';
229231
import * as ReactDOM from 'react-dom';
230232
import { HelloMessage } from './react-app';
231233

232234
ReactDOM.render(<HelloMessage message="World" />, document.getElementById('my-spa'));
233235
```
234236

235-
At this stage, run `webpack` on the command line to build `wwwroot/dist/main.js`. Or, to avoid having to do this manually, you could use the `SpaServices` package to enable Webpack dev middleware.
237+
At this stage, run `webpack` on the command line to build `wwwroot/dist/main.js`. Or, to avoid having to do this manually, you could use the `SpaServices` package to [enable Webpack dev middleware](#webpack-dev-middleware).
236238

237239
You can now run your React code on the client by adding the following to one of your MVC views:
238240

239241
<div id="my-spa"></div>
240242
<script src="/dist/main.js"></script>
241-
243+
242244
#### Running React code on the server
243245

244246
Now you have React code being built using Webpack, you can enable server-side prerendering using the `aspnet-prerender-*` tag helpers as follows:
@@ -248,7 +250,7 @@ Now you have React code being built using Webpack, you can enable server-side pr
248250

249251
... along with the following boot module at `ClientApp/boot-server.jsx`:
250252

251-
```
253+
```javascript
252254
import * as React from 'react';
253255
import { renderToString } from 'react-dom/server';
254256
import { HelloMessage } from './react-app';
@@ -292,7 +294,7 @@ It lets you work as if the browser natively understands whatever file types you
292294

293295
After installing the `Microsoft.AspNetCore.SpaServices` NuGet package and the `aspnet-webpack` NPM package, go to your `Startup.cs` file, and **before your call to `UseStaticFiles`**, add the following:
294296

295-
```
297+
```csharp
296298
if (env.IsDevelopment()) {
297299
app.UseWebpackDevMiddleware();
298300
}
@@ -302,7 +304,7 @@ if (env.IsDevelopment()) {
302304

303305
You will also need to edit your webpack configuration at `webpack.config.js`. Since `UseWebpackDevMiddleware` needs to know which incoming requests to intercept, specify a `publicPath` value on your `output`, for example:
304306

305-
```
307+
```javascript
306308
module.exports = {
307309
// ... rest of your webpack config is here ...
308310

@@ -336,21 +338,21 @@ npm install --save webpack-hot-middleware
336338

337339
At the top of your `Startup.cs` file, add the following namespace reference:
338340

339-
```
341+
```csharp
340342
using Microsoft.AspNetCore.SpaServices.Webpack;
341343
```
342344

343345
Now amend your call to `UseWebpackDevMiddleware` as follows:
344346

345-
```
347+
```csharp
346348
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
347349
HotModuleReplacement = true
348350
});
349351
```
350352

351353
Also, to work around a temporary issue in `SpaServices`, you must ensure that your Webpack config includes a `plugins` array, even if it's empty. For example, in `webpack.config.js`:
352354

353-
```
355+
```javascript
354356
module.exports = {
355357
// ... rest of your webpack config is here ...
356358

@@ -372,7 +374,7 @@ If you edit any of your source files that get built by webpack, the result will
372374

373375
Webpack has built-in support for updating React components in place. To enable this, amend your `UseWebpackDevMiddleware` call further as follows:
374376

375-
```
377+
```csharp
376378
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
377379
HotModuleReplacement = true,
378380
ReactHotModuleReplacement = true
@@ -404,7 +406,7 @@ If a request arrives for `/some/page`, and it doesn't match any server-side rout
404406

405407
To help distinguish between these cases, the `Microsoft.AspNetCore.SpaServices` NuGet package includes a routing helper, `MapSpaFallbackRoute`. For example, in your `Startup.cs` file's `Configure` method, you might add:
406408

407-
```
409+
```csharp
408410
app.UseStaticFiles();
409411

410412
app.UseMvc(routes =>
@@ -428,4 +430,3 @@ Then, since `MapSpaFallbackRoute` is last, any other requests **that don't appea
428430
Any requests that do appear to be for static files (i.e., those that end with filename extensions), will *not* be handled by `MapSpaFallbackRoute`, and so will end up as 404s.
429431

430432
This is not a perfect solution to the problem of identifying 404s, because for example `MapSpaFallbackRoute` will not match requests for `/users/albert.einstein`, because it appears to contain a filename extension (`.einstein`). If you need your SPA to handle routes like that, then don't use `MapSpaFallbackRoute` - just use a regular MVC catch-all route. But then beware that requests for unknown static files will result in your client-side app being rendered.
431-

0 commit comments

Comments
 (0)