# 源码结构
# 避免状态单例
为每个请求创建一个新的根 Vue 实例,应该暴露一个可以重复执行的工厂函数。
同样的规则也适用于 router、store 和 event bus 实例。你不应该直接从模块导出并将其导入到应用程序中,而是需要在 createApp 中创建一个新的实例,并从根 Vue 实例注入。
# 构建步骤
通常 Vue 应用程序是由 webpack 和 vue-loader 构建,并且许多 webpack 特定功能不能直接在 Node.js 中运行(例如通过 file-loader 导入文件,通过 css-loader 导入 CSS)。
尽管 Node.js 最新版本能够完全支持 ES2015 特性,我们还是需要转译客户端代码以适应老版浏览器。这也会涉及到构建步骤。
对于客户端应用程序和服务器应用程序,我们都要使用 webpack 打包 - 服务器需要「服务器 bundle」然后用于服务器端渲染(SSR),而「客户端 bundle」会发送给浏览器,用于混合静态标记。
# 项目结构
src
├── components
│ ├── Foo.vue
│ ├── Bar.vue
│ └── Baz.vue
├── App.vue
├── app.js # 通用 entry(universal entry)
├── entry-client.js # 仅运行于浏览器
└── entry-server.js # 仅运行于服务器
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- app.js
app.js 是应用程序的「通用 entry」。在纯客户端应用程序中,我们将在此文件中创建根 Vue 实例,并直接挂载到 DOM。但是,对于服务器端渲染(SSR),改为在纯客户端 entry 文件中实现。app.js 简单地使用 export 导出一个 createApp 函数:
import Vue from 'vue'
import App from './APP.vue'
export function createApp() {
const app = new Vue({
render: h => h(App)
})
return { app }
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- entry-client.js
客户端 entry 只需创建应用程序,并且将其挂载到 DOM 中:
import { createApp } from './app'
const app = createApp()
app.$mount('#app')
1
2
3
4
5
2
3
4
5
- entry-server.js
服务器 entry 使用 default export 导出函数,并在每次渲染中重复调用此函数。
import { createApp } from "./app";
export default context => {
const { app } = createApp()
return app
}
1
2
3
4
5
6
7
2
3
4
5
6
7