Skip to content

Commit 210b792

Browse files
SSR Guide: Remove app.js (#1297)
* Remove app.js * Fix typos, code style Co-authored-by: Natalia Tepluhina <[email protected]> * Fix typos * Fix code style * Fix code style * Fix code style * Fix code style * Fix wrong async function Co-authored-by: Natalia Tepluhina <[email protected]>
1 parent 47691ed commit 210b792

File tree

3 files changed

+72
-69
lines changed

3 files changed

+72
-69
lines changed

src/guide/ssr/routing.md

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,50 @@ It is recommended to use the official [vue-router](https://github.com/vuejs/vue-
88

99
```js
1010
// router.js
11-
import { createRouter, createMemoryHistory, createWebHistory } from 'vue-router'
11+
import { createRouter } from 'vue-router'
1212
import MyUser from './components/MyUser.vue'
1313

14-
const isServer = typeof window === 'undefined'
15-
16-
const createHistory = isServer ? createMemoryHistory : createWebHistory
17-
1814
const routes = [{ path: '/user', component: MyUser }]
1915

20-
export default function() {
16+
export default function (history) {
2117
return createRouter({
22-
history: createHistory(),
18+
history,
2319
routes
2420
})
2521
}
2622
```
2723

28-
And update our `app.js`, client and server entries:
24+
And update our client and server entries:
25+
26+
```js
27+
// entry-client.js
28+
import { createApp } from 'vue'
29+
import { createWebHistory } from 'vue-router'
30+
import createRouter from './router.js'
31+
import App from './App.vue'
32+
33+
// ...
34+
35+
const app = createApp(App)
36+
37+
const router = createRouter(createWebHistory())
38+
39+
app.use(router)
40+
41+
// ...
42+
```
2943

3044
```js
31-
// app.js
45+
// entry-server.js
3246
import { createSSRApp } from 'vue'
47+
// server router uses a different history from the client one
48+
import { createMemoryHistory } from 'vue-router'
49+
import createRouter from './router.js'
3350
import App from './App.vue'
34-
import createRouter from './router'
3551

36-
export default function(args) {
37-
const app = createSSRApp(App)
38-
const router = createRouter()
52+
export default function () {
53+
const app = createSSRApp(Vue)
54+
const router = createRouter(createMemoryHistory())
3955

4056
app.use(router)
4157

@@ -46,20 +62,6 @@ export default function(args) {
4662
}
4763
```
4864

49-
```js
50-
// entry-client.js
51-
const { app, router } = createApp({
52-
/*...*/
53-
})
54-
```
55-
56-
```js
57-
// entry-server.js
58-
const { app, router } = createApp({
59-
/*...*/
60-
})
61-
```
62-
6365
## Code-Splitting
6466

6567
Code-splitting, or lazy-loading part of your app, helps reduce the size of assets that need to be downloaded by the browser for the initial render, and can greatly improve TTI (time-to-interactive) for apps with large bundles. The key is "loading just what is needed" for the initial screen.
@@ -77,15 +79,20 @@ const routes = [
7779
]
7880
```
7981

80-
On both client and server we need to wait for router to resolve async route components ahead of time in order to properly invoke in-component hooks. For this we will be using [router.isReady](https://next.router.vuejs.org/api/#isready) method Let's update our client entry:
82+
On both client and server we need to wait for the router to resolve async route components ahead of time in order to properly invoke in-component hooks. For this we will be using [router.isReady](https://next.router.vuejs.org/api/#isready) method Let's update our client entry:
8183

8284
```js
8385
// entry-client.js
84-
import createApp from './app'
86+
import { createApp } from 'vue'
87+
import { createWebHistory } from 'vue-router'
88+
import createRouter from './router.js'
89+
import App from './App.vue'
8590

86-
const { app, router } = createApp({
87-
/* ... */
88-
})
91+
const app = createApp(App)
92+
93+
const router = createRouter(createWebHistory())
94+
95+
app.use(router)
8996

9097
router.isReady().then(() => {
9198
app.mount('#app')

src/guide/ssr/server.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
The [code structure](./structure.html) and [webpack configuration](./build-config.html) we've described also require some changes to our Express server code.
44

5-
- we need to create an application with a built `app.js` from the resulting bundle. A path to it can be found using the webpack manifest:
5+
- we need to create an application with a built `entry-server.js` from the resulting bundle. A path to it can be found using the webpack manifest:
66

77
```js
88
// server.js
99
const path = require('path')
1010
const manifest = require('./dist/server/ssr-manifest.json')
1111

12+
// the 'app.js' name is taken from the name of the entrypoint with an added `.js` postfix
1213
const appPath = path.join(__dirname, './dist', 'server', manifest['app.js'])
1314
const createApp = require(appPath).default
1415
```
@@ -78,7 +79,7 @@ server.use(
7879
)
7980

8081
server.get('*', async (req, res) => {
81-
const { app } = await createApp()
82+
const { app } = createApp()
8283

8384
const appContent = await renderToString(app)
8485

src/guide/ssr/structure.md

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44

55
When writing client-only code, we can assume that our code will be evaluated in a fresh context every time. However, a Node.js server is a long-running process. When our code is first imported by the process, it will be evaluated once and then stay in memory. This means that if you create a singleton object, it will be shared between every incoming request, with the risk of cross-request state pollution.
66

7-
Therefore, we need to **create a new root Vue instance for each request.** In order to do that, we need to write a factory function that can be repeatedly executed to create fresh app instances for each request:
7+
Therefore, we need to **create a new root Vue instance for each request.** In order to do that, we need to write a factory function that can be repeatedly executed to create fresh app instances for each request, so our server code now becomes:
88

99
```js
10-
// app.js
10+
// server.js
1111
const { createSSRApp } = require('vue')
12+
const { renderToString } = require('@vue/server-renderer')
13+
const express = require('express')
14+
15+
const server = express()
1216

1317
function createApp() {
1418
return createSSRApp({
@@ -20,15 +24,6 @@ function createApp() {
2024
template: `<div>Current user is: {{ user }}</div>`
2125
})
2226
}
23-
```
24-
25-
And our server code now becomes:
26-
27-
```js
28-
// server.js
29-
const { renderToString } = require('@vue/server-renderer')
30-
const server = require('express')()
31-
const { createApp } = require('src/app.js')
3227

3328
server.get('*', async (req, res) => {
3429
const app = createApp()
@@ -49,7 +44,7 @@ server.get('*', async (req, res) => {
4944
server.listen(8080)
5045
```
5146

52-
The same rule applies to other instances as well (such as the router or store). Instead of exporting the router or store directly from a module and importing it across your app, you should create a fresh instance in `createApp` and inject it from the root Vue instance.
47+
The same rule applies to other instances as well (such as the router or store). Instead of exporting the router or store directly from a module and importing it across your app, you should create a fresh instance in `createApp` and inject it from the root Vue instance each time a new request is made.
5348

5449
## Introducing a Build Step
5550

@@ -76,42 +71,43 @@ src
7671
├── components
7772
│ ├── MyUser.vue
7873
│ └── MyTable.vue
79-
├── App.vue
80-
├── app.js # universal entry
74+
├── App.vue # the root of your application
8175
├── entry-client.js # runs in browser only
8276
└── entry-server.js # runs on server only
8377
```
8478

85-
### `app.js`
79+
### `App.vue`
8680

87-
`app.js` is the universal entry to our app. In a client-only app, we would create the Vue application instance right in this file and mount directly to DOM. However, for SSR that responsibility is moved into the client-only entry file. `app.js` instead creates an application instance and exports it:
81+
You may have noticed we now have a file called `App.vue` in the root of our `src` folder. That's where the root component of your application will be stored. We can now safely move the application code from `server.js` to the `App.vue` file:
8882

89-
```js
90-
import { createSSRApp } from 'vue'
91-
import App from './App.vue'
92-
93-
// export a factory function for creating a root component
94-
export default function(args) {
95-
const app = createSSRApp(App)
83+
```vue
84+
<template>
85+
<div>Current user is: {{ user }}</div>
86+
</template>
9687
97-
return {
98-
app
88+
<script>
89+
export default {
90+
name: 'App',
91+
data() {
92+
return {
93+
user: 'John Doe'
94+
}
9995
}
10096
}
97+
</script>
10198
```
10299

103100
### `entry-client.js`
104101

105-
The client entry creates the application using the root component factory and mounts it to the DOM:
102+
The client entry creates the application using the `App.vue` component and mounts it to the DOM:
106103

107104
```js
108-
import createApp from './app'
105+
import { createSSRApp } from 'vue'
106+
import App from './App.vue'
109107

110108
// client-specific bootstrapping logic...
111109

112-
const { app } = createApp({
113-
// here we can pass additional arguments to app factory
114-
})
110+
const app = createSSRApp(App)
115111

116112
// this assumes App.vue template root element has `id="app"`
117113
app.mount('#app')
@@ -122,12 +118,11 @@ app.mount('#app')
122118
The server entry uses a default export which is a function that can be called repeatedly for each render. At this moment, it doesn't do much other than returning the app instance - but later we will perform server-side route matching and data pre-fetching logic here.
123119

124120
```js
125-
import createApp from './app'
121+
import { createSSRApp } from 'vue'
122+
import App from './App.vue'
126123

127-
export default function() {
128-
const { app } = createApp({
129-
/*...*/
130-
})
124+
export default function () {
125+
const app = createSSRApp(Vue)
131126

132127
return {
133128
app

0 commit comments

Comments
 (0)