Egg + Vue 服務(wù)端渲染開發(fā)指南

1. 項(xiàng)目初始化

1.1 通過 easywebpack-cli 腳手架初始化

  1. 安裝腳手架 npm install easywebpack-cli -g 命令行迁匠,然后就可以使用 easywebpackeasy 命令

  2. 命令行運(yùn)行 easywebpack init

  3. 選擇 egg+vue server side render boilerplate 初始化骨架項(xiàng)目

  4. 安裝依賴 npm install

1.2 通過骨架項(xiàng)目初始化

git clone https://github.com/hubcarl/egg-vue-webpack-boilerplate.git
npm install

初始化的項(xiàng)目提供多頁面和SPA(vue-router/axios)服務(wù)端渲染實(shí)例殿雪,可以直接運(yùn)行。

2. 項(xiàng)目運(yùn)行

2.1 本地運(yùn)行

npm start

npm start 做了如下三件事情

  • 啟動 egg 應(yīng)用
  • 啟動 Webpack 構(gòu)建, 文件不落地磁盤栖榨,構(gòu)建的文件都在內(nèi)存里面(只在本地啟動, 發(fā)布模式是提前構(gòu)建好文件到磁盤)
  • 構(gòu)建會同時啟動兩個 Webpack 構(gòu)建服務(wù), 客戶端js構(gòu)建端口9000, 服務(wù)端端口9001
  • 構(gòu)建完成,Egg應(yīng)用正式可用错英,自動打開瀏覽器

2.2 發(fā)布模式

  • 構(gòu)建文件落地磁盤
npm run build 或 easywebpack build prod
  1. 啟動 Webpack 構(gòu)建秉宿,文件落地磁盤
  2. 服務(wù)端構(gòu)建的文件放到 app/view 目錄
  3. 客戶端構(gòu)建的文件放到 public 目錄
  4. 生成的 buildConfig.jsonmanifest.json 放到 config 目錄
  5. 構(gòu)建的文件都是gitignore的,部署時請注意把這些文件打包進(jìn)去
  • 運(yùn)行

啟動應(yīng)用前, 請?jiān)O(shè)置 EGG_SERVER_ENV 環(huán)境變量践叠,測試環(huán)境設(shè)置 test言缤, 正式環(huán)境設(shè)置 prod

npm start

3. 項(xiàng)目構(gòu)建

  • 通過 easywebpack-cli 統(tǒng)一構(gòu)建,支持 dev禁灼,test管挟,prod 模式構(gòu)建

  • easywebpack-cli 通過項(xiàng)目根目錄下的 webpack.config.js 配置文件構(gòu)造出 Webpack 實(shí)際的配置文件,配置項(xiàng)請見 webpack.config.js

  • 獲取 Webpack 實(shí)際的配置文件, egg-webpack 會使用到該功能弄捕。構(gòu)建會根據(jù) webpackConfigList.length 啟動對應(yīng)個數(shù)的 Webpack 編譯實(shí)例僻孝,這里會同時啟動兩個 Webpack 構(gòu)建服務(wù), 客戶端jsbundle構(gòu)建,端口9000, 服務(wù)端jsbundle構(gòu)建端口9001守谓。默認(rèn)端口為9000, 端口依次遞增穿铆。

// config/config.local.js 本地 npm start 使用
const EasyWebpack = require('easywebpack-vue');
exports.webpack = {
  webpackConfigList:EasyWebpack.getWebpackConfig()
};
  • 該項(xiàng)目中,app/web/page 目錄中所有 .vue 文件當(dāng)作 Webpack 構(gòu)建入口是采用 app/web/framework/vue/entry 的 client-loader.js 和 server-loader.js 模板實(shí)現(xiàn)的斋荞,這個需要結(jié)合 webpack.config.js 下的 entry.loader 使用荞雏。
entry: {
   include: ['app/web/page', { 'app/app': 'app/web/page/app/app.js?loader=false' }],
   exclude: ['app/web/page/[a-z]+/component', 'app/web/page/app'],
   loader: { // 如果沒有配置loader模板,默認(rèn)使用 .js 文件作為構(gòu)建入口
      client: 'app/web/framework/vue/entry/client-loader.js',
      server: 'app/web/framework/vue/entry/server-loader.js',
   }    
}

上面 { 'app/app': 'app/web/page/app/app.js?loader=false' } 這個 loader=false 的含義表示 app/web/page 目錄下的 app/app.js 不使用 entry.loader 模板平酿。因?yàn)檫@個app/app.js是一個SPA服務(wù)端渲染Example凤优,實(shí)現(xiàn)邏輯與其他普通的頁面不一樣,不能用 entry.loader 模板蜈彼, 這個功能在自定義entry文件構(gòu)建規(guī)范時使用筑辨。

4. 項(xiàng)目規(guī)范

  • 遵循 egg 開發(fā)規(guī)范
  • Vue 項(xiàng)目代碼放到 app/web 目錄,頁面入口目錄為 page幸逆,該目錄的 所有 vue 文件默認(rèn)會作為 Webpack 的 entry 構(gòu)建入口挖垛。建議每個頁面目錄的只保留一個vue文件,vue關(guān)聯(lián)的組件可以放到widget 或者 compnent目錄秉颗。如果非要放到當(dāng)前目前,請配置 webpack.config.js entry.exclude 排除 vue文件送矩。
egg-vue-project.png

5. 項(xiàng)目開發(fā)

支持多頁面/單頁面服務(wù)端渲染, 前端渲染, 靜態(tài)頁面三種方式.

5.1 多頁面服務(wù)端渲染實(shí)現(xiàn)

5.1.1 多頁面前端頁面實(shí)現(xiàn)

在app/web/page 目錄下面創(chuàng)建home目錄, home.vue 文件, Webpack自動根據(jù).vue文件創(chuàng)建entry入口, 具體實(shí)現(xiàn)請見webpack.config.js

  • home.vue 編寫界面邏輯, 根元素為layout(自定義組件, 全局注冊, 統(tǒng)一的html, meta, header, body, 你可以自定義 title蚕甥,description,keywords SEO信息栋荸,更多信息請擴(kuò)展layout).
<template>
  <layout title="基于egg-vue-webpack-dev和egg-view-vue插件的工程示例項(xiàng)目" description="vue server side render" keywords="egg, vue, webpack, server side render">
   {{message}}
  </layout>
</template>
<style>
  @import "home.css";
</style>
<script type="text/babel">

  export default {
    components: {

    },
    computed: {

    },
    methods: {

    },
    mounted() {

    }
  }
</script>

5.1.2 多頁面后端渲染實(shí)現(xiàn), 通過 egg-view-vue-ssr 插件 render 方法實(shí)現(xiàn)

  • 創(chuàng)建controller文件home.js
exports.index = function* (ctx) {
  yield ctx.render('home/home.js', { message: 'vue server side render!' });
};
  • 添加路由配置
app.get('/home', app.controller.home.home.index);

5.1.3 多頁面走前端渲染(后端路由)實(shí)現(xiàn), 通過 egg-view-vue-ssr 插件 renderClient 方法實(shí)現(xiàn)

  • 創(chuàng)建controller文件home.js
exports.client = function* (ctx) {
  yield ctx.renderClient('home/home.js', { message: 'vue server side render!' });
};
  • 添加路由配置
app.get('/client', app.controller.home.home.client);

5.2 HTML靜態(tài)頁面前端渲染

  • 直接有easywebpack構(gòu)建出靜態(tài)HTML文件, 請見 webpack.config.js 配置和 app/web/page/html代碼實(shí)現(xiàn)

  • 通過 egg-static 靜態(tài)文件訪問HTML文件

5.3 單頁面服務(wù)器渲染同構(gòu)實(shí)現(xiàn)

5.3.1 單頁面前端實(shí)現(xiàn)

在app/web/page 目錄下面創(chuàng)建app目錄, app.vue, app.js 文件.

  • app.vue 編寫界面邏輯, 根元素為layout(自定義組件, 全局注冊, 統(tǒng)一的html, meta, header, body)
<template>
  <app-layout>
    <transition name="fade" mode="out-in">
      <router-view></router-view>
    </transition>
  </app-layout>
</template>
<style lang="sass">

</style>
<script type="text/babel">
  export default {
    computed: {

    },
    mounted(){

    }
  }
</script>
  • app.js 頁面調(diào)用入口
import { sync } from 'vuex-router-sync';
import store from 'store/app';
import router from 'component/app/router';
import app from './app.vue';
import App from 'app';
import Layout from 'component/layout/app';

App.component(Layout.name, Layout);

sync(store, router);

export default App.init({
  base: '/app',
  ...app,
  router,
  store
});

5.3.2 單頁面后端實(shí)現(xiàn)

  • 創(chuàng)建controller文件app.js
exports.index = function* (ctx) {
  yield ctx.render('app/app.js', { url: this.url.replace(/\/app/, '') });
};
  • 添加路由配置
  app.get('/app(/.+)?', app.controller.app.app.index);

6. 項(xiàng)目部署

  • 正式環(huán)境部署菇怀,請?jiān)O(shè)置 EGG_SERVER_ENV=prod 環(huán)境變量, 更多請見運(yùn)行環(huán)境
  • 構(gòu)建的 app/view 目錄, public 目錄以及 buildConfig.jsonmanifest.json等文件, 都是 gitignore 的,部署時請注意把這些文件打包進(jìn)去晌块。

7. 項(xiàng)目和插件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末爱沟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匆背,更是在濱河造成了極大的恐慌呼伸,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異括享,居然都是意外死亡搂根,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門铃辖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剩愧,“玉大人,你說我怎么就攤上這事娇斩∪示恚” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵犬第,是天一觀的道長锦积。 經(jīng)常有香客問我,道長瓶殃,這世上最難降的妖魔是什么充包? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮遥椿,結(jié)果婚禮上基矮,老公的妹妹穿的比我還像新娘。我一直安慰自己冠场,他們只是感情好家浇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著碴裙,像睡著了一般钢悲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舔株,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天莺琳,我揣著相機(jī)與錄音,去河邊找鬼载慈。 笑死惭等,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的办铡。 我是一名探鬼主播辞做,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼寡具!你這毒婦竟也來了秤茅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤童叠,失蹤者是張志新(化名)和其女友劉穎框喳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帖努,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年撰豺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拼余。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡污桦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出匙监,到底是詐尸還是另有隱情凡橱,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布亭姥,位于F島的核電站稼钩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏达罗。R本人自食惡果不足惜坝撑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粮揉。 院中可真熱鬧巡李,春花似錦、人聲如沸扶认。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辐宾。三九已至狱从,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叠纹,已是汗流浹背季研。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留誉察,地道東北人与涡。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像冒窍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子豺鼻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 在實(shí)現(xiàn) egg + vue 服務(wù)端渲染工程化實(shí)現(xiàn)之前综液,我們先來看看前面兩篇關(guān)于Webpack構(gòu)建和Egg的文章: ...
    hubcarl閱讀 6,004評論 0 19
  • 1.概要 隨著越來越多的項(xiàng)目采用 Vue, React, Weex 進(jìn)行業(yè)務(wù)開發(fā), 在前端構(gòu)建方面大多數(shù)是用web...
    hubcarl閱讀 6,309評論 3 18
  • 嗯,我大一了儒飒。我想要的自己谬莹,可以每天在第一縷陽光下醒來,可以接受不同的新鮮事物,可以吸收不同的樂觀能量附帽,不熬夜不喝...
    心上人喜歡閱讀 118評論 0 0
  • 沒有任何提示音蕉扮,他準(zhǔn)點(diǎn)醒來整胃。拿出手機(jī)摁了一下,手機(jī)屏顯示“10月3日2:00”喳钟。再摁一下關(guān)機(jī)鍵屁使,閃著熒光的時間像一...
    撫琴_張顥閱讀 533評論 13 6
  • 每逢下雨天 就覺得天空離我很近 因?yàn)橛陰砹颂炜盏奈兜?聞著很舒服 呼吸時感到很輕松 一場雨 洗盡鉛華
    辰漁閱讀 283評論 0 2