egg+vue服務(wù)端渲染模板項(xiàng)目介紹

egg-vue-webpack-boilerplate

基于 Egg + Vue + Webpack SSR 服務(wù)端渲染和 CSR 前端渲染工程骨架項(xiàng)目,包括前臺系統(tǒng)(SSR MPA)和后臺管理系統(tǒng)(SSR SPA)。

系統(tǒng)功能

前臺博客系統(tǒng) http://localhost:7001

采用 Egg + Vue 服務(wù)端渲染

[圖片上傳失敗...(image-a57696-1602485610603)]

  • 博客首頁
  • 文章列表
  • 文章詳情

后臺管理系統(tǒng) http://localhost:7001/admin

采用 Egg + Vue + Vue-Router + Element 單頁面服務(wù)端同構(gòu)渲染

[圖片上傳失敗...(image-2c10d1-1602485610603)]

  • Dashboard
  • Markdown
  • 文章管理

骨架介紹

常用功能

常用 Example 實(shí)現(xiàn)見 awesome 分支代碼少漆。

  • Sass/Less/Stylus 功能
  • Dynamic Component Load
  • Element-UI 集成
  • Single Page Application

純凈分支

因該項(xiàng)目包含了多種實(shí)現(xiàn), 提供多種例子實(shí)現(xiàn),為防干擾, 特提供了兩個純凈版本分支用于實(shí)際項(xiàng)目開發(fā), 請自行選用。

以上項(xiàng)目脖律,你可以通過 easywebpack-cli 初始化

版本

  • Egg 版本: ^2.x.x
  • Node 版本: ^8.x.x+
  • Vue 版本: ^2.5.0
  • Webpack 版本: ^4.x.x, 對應(yīng) easywebpack-vue 版本為 ^4.x.x
  • Webpack3 版本項(xiàng)目骨架請見 webpack3 分支, 對應(yīng) easywebpack-react 版本為 3.x.x

文檔

特性

  • 支持服務(wù)端渲染SSR(Server Side Render), 前端渲染CSR(Client Side Render) 方式

  • 支持 Node 和 前端代碼修改, Webpack 自動編譯和熱更新, npm run dev 一鍵啟動應(yīng)用

  • 基于 vue + axios 多頁面服務(wù)端渲染, 客戶端渲染同構(gòu)實(shí)現(xiàn), 支持 asyncData 渲染

  • 基于 vue + vuex + vue-router + axios 單頁面服務(wù)器客戶端同構(gòu)實(shí)現(xiàn)

  • 支持 js/css/image 資源依賴, 內(nèi)置支持 CDN 特性, 支持 css/sass/less 樣式編寫

  • 支持根據(jù) .vue 文件自動創(chuàng)建 Webpack Entry 入口文件

  • 開始支持多進(jìn)程和緩存編譯, 支持 Webpack dll 自動化構(gòu)建, 與多進(jìn)程編譯結(jié)合腕侄,構(gòu)建速度減少 2/3

  • 支持 Vue 組件 import 異步加載, 具體實(shí)例請看app/web/page/dynamic

  • 支持服務(wù)端渲染(SSR)失敗時小泉,自動降級為前端渲染(CSR)模式

  • 提供 國際化 i18n 多語言支持方案

插件

使用

安裝cli(非必需)

npm install @easy-team/easywebpack-cli -g

easywebpack-cli 已內(nèi)置 devDependencies 中, 無需安裝芦疏。如果你需要在命令行使用 easy 命令, 可以單獨(dú)全局安裝。

安裝依賴

npm install

本地開發(fā)

啟動構(gòu)建細(xì)節(jié)請閱讀:https://www.yuque.com/easy-team/egg-vue/build

npm run dev

應(yīng)用訪問: http://127.0.0.1:7001

[圖片上傳失敗...(image-7223e2-1602485610603)]

  • 本地開發(fā)啟動 Webpack 構(gòu)建, 默認(rèn)配置文件為項(xiàng)目根目錄 webpack.config.js 文件微姊。 SSR 需要配置兩份 Webpack 配置酸茴,所以構(gòu)建會同時啟動兩個 Webpack 構(gòu)建服務(wù)。web 表示構(gòu)建 JSBundle 給前端用兢交,構(gòu)建后文件目錄 public, 默認(rèn)端口 9000; node 表示構(gòu)建 JSBundle 給前端用薪捍,構(gòu)建后文件目錄 app/view, 默認(rèn)端口 9001.

  • 本地構(gòu)建是 Webpack 內(nèi)存構(gòu)建,文件不落地磁盤配喳,所以 app/viewpublic 在本地開發(fā)時酪穿,是看不到文件的。 只有發(fā)布模式(npm run build)才能在這兩個目錄中看到構(gòu)建后的內(nèi)容晴裹。

線上部署

部署細(xì)節(jié)請閱讀:https://www.yuque.com/easy-team/egg-vue/online

  • 首先在本地或者 ci 進(jìn)行項(xiàng)目構(gòu)建
npm run build 
  • 上傳源代碼以及構(gòu)建的相關(guān)文件到服務(wù)器被济,然后啟動應(yīng)用
npm start 

構(gòu)建配置

webpack 配置構(gòu)建是通過 easywebpack 實(shí)現(xiàn)的,具體見 https://www.yuque.com/easy-team/egg-vue/qpeiowhttps://github.com/easy-team/easywebpack-cli

  • Egg Webpack 配置代碼調(diào)用入口
// ${root}/config/config.local.js
exports.webpack = { // 默認(rèn)是如下配置涧团,可不配置
  // browser: 'http://localhost:7001', // 配置 false 可以關(guān)閉自動打開瀏覽器
  // webpackConfigList: require('@easy-team/easywebpack-vue').getWebpackConfig()
};
  • 運(yùn)行 npm run build 可以進(jìn)行 Webpack 項(xiàng)目構(gòu)建
  • 通過 easy print 可以打印 Webpack 原生配置

項(xiàng)目結(jié)構(gòu)

├── app
│   ├── controller
│   │   ├── test
│   │   │   └── test.js
│   ├── extend
│   ├── lib
│   ├── middleware
│   ├── mocks
│   ├── proxy
│   ├── router.js
│   ├── view
│   │   ├── home
│   │   │     └── home.js                 // Webpack 服務(wù)器編譯的jsbundle文件, 對應(yīng) app/web/page/home/home.vue
│   └── web                               // 前端工程目錄
│       ├── asset                         // 存放公共js,css資源
│       ├── framework                     // 前端公共庫和第三方庫
│       │   ├── fastclick
│       │   │   └── fastclick.js
│       │   ├── sdk
│       │   │   ├── sdk.js
│       │   ├── storage
│       │   │   └── storage.js
│       │   └── vue                           // 與vue相關(guān)的公開代碼
│       │       ├── app.js                    // 前后端調(diào)用入口, 默認(rèn)引入componet/directive/filter
│       │       ├── component.js              // 組件入口, 可以增加component目錄,類似下面的directive
│       │       ├── directive                 // directive 目錄,存放各種directive組件
│       │       ├── directive.js              // directive引用入口
│       │       └── filter.js                 // filter引用入口
│       ├── page                              // 前端頁面和webpack構(gòu)建目錄, 也就是webpack打包配置entryDir
│       │   ├── home                          // 每個頁面遵循目錄名, js文件名, scss文件名, vue文件名相同
│       │   │   ├── home.scss
│       │   │   ├── home.vue
│       │   │   ├── images                    // 頁面自有圖片,公共圖片和css放到asset下面
│       │   │   │   └── icon_more.png
│       │   │   └── w-week                    // 頁面自有組件,公共組件放到widget下面
│       │   │       ├── w-week.scss
│       │   │       └── w-week.vue
│       │   └── test                          // 每個頁面遵循目錄名, js文件名, scss文件名, vue文件名相同
│       │       └── test.vue
│       ├── store                             // 引入vuex 的基本規(guī)范, 可以分模塊
│       │   ├── app
│       │   │   ├── actions.js
│       │   │   ├── getters.js
│       │   │   ├── index.js
│       │   │   ├── mutation-type.js
│       │   │   └── mutations.js
│       │   └── store.js
│       └── component                         // 公共業(yè)務(wù)組件, 比如loading, toast等, 遵循目錄名, js文件名, scss文件名, vue文件名相同
│           ├── loading
│           │   ├── loading.scss
│           │   └── loading.vue
│           ├── test
│           │   ├── test.vue
│           │   └── test.scss
│           └── toast
│               ├── toast.scss
│               └── toast.vue
├── build                                   //  webpack 自定義配置入口, 會與默認(rèn)配置進(jìn)行合并(看似這么多,其實(shí)這里只是占個位說明一下)
│   ├── base
│   │   └── index.js                        // 公共配置        
│   ├──  client                             // 客戶端webpack編譯配置
│   │   ├── dev.js
│   │   ├── prod.js
│   │   └── index.js
│   ├──  server                             // 服務(wù)端webpack編譯配置
│   │    ├── dev.js
│   │    ├── prod.js
│   │    └── index.js
│   └── index.js
├── config
│   ├── manifest.json                      // webpack 構(gòu)建的資源依賴依賴表
│   ├── config.default.js
│   ├── config.local.js
│   ├── config.prod.js
│   ├── config.test.js
│   └── plugin.js
├── doc
├── index.js
├── public                                 // webpack 編譯的前端靜態(tài)資源存入目錄
│   ├── static
│   │   ├── css
│   │   │   ├── home
│   │   │   │   ├── home.07012d33.css
│   │   │   └── test
│   │   │       ├── test.4bbb32ce.css
│   │   ├── img
│   │   │   ├── change_top.4735c57.png
│   │   │   └── intro.0e66266.png
│   ├── test
│   │   └── test.js
│   └── vendor.js                         // 生成的公共打包庫

功能實(shí)現(xiàn)

多頁面服務(wù)端渲染/前端渲染同構(gòu)實(shí)現(xiàn)

多頁面前端頁面實(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)
<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>

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

  • 創(chuàng)建controller文件home.js
exports.index = function* (ctx) {
  // index/index.js 是 app/web/page/index/index.vue 構(gòu)建后的服務(wù)端頁面渲染的 JSBundle 文件只磷。
  yield ctx.render('index/index.js', { message: 'vue server side render!' });
};
  • 添加路由配置
app.get('/home', app.controller.home.home.index);

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

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

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

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

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

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

單頁面前端實(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
});

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

  • 創(chuàng)建controller文件app.js
exports.index = function* (ctx) {
  // app/app.js 是 app/web/page/app/app.js 構(gòu)建后的服務(wù)端頁面渲染的 JSBundle 文件。
  yield ctx.render('app/app.js', { url: this.url.replace(/\/app/, '') });
};
  • 添加路由配置
  app.get('/app(/.+)?', app.controller.app.app.index);

文章

https://www.yuque.com/easy-team/egg-vue

交流

功能性需求或者Bug問題, 歡迎大家 PR 完善, 如果你需要了解更多信息泌绣,請加 QQ 群: 433207205 (備注:easyjs)

Contributors ?

Thanks goes to these wonderful people (emoji key):




<table>
<tr>
<td align="center"><a ><img src="https://avatars2.githubusercontent.com/u/4983042?v=4" width="100px;" alt=""/><br /><b>sky</b></a><br /><a title="Code">??</a> <a title="Documentation">??</a></td>
<td align="center"><a ><img src="https://avatars0.githubusercontent.com/u/13363216?v=4" width="100px;" alt=""/><br /><b>jasonjcpeng</b></a><br /><a title="Code">??</a> <a title="Documentation">??</a></td>
<td align="center"><a ><img src="https://avatars2.githubusercontent.com/u/5542777?v=4" width="100px;" alt=""/><br /><b>Kevin Zhong</b></a><br /><a title="Code">??</a> <a title="Documentation">??</a></td>
<td align="center"><a ><img src="https://avatars0.githubusercontent.com/u/15319816?v=4" width="100px;" alt=""/><br /><b>HiuYanChong</b></a><br /><a title="Code">??</a> <a title="Documentation">??</a></td>
<td align="center"><a ><img src="https://avatars2.githubusercontent.com/u/958063?v=4" width="100px;" alt=""/><br /><b>Suyi</b></a><br /><a title="Code">??</a> <a title="Documentation">??</a></td>
<td align="center"><a ><img src="https://avatars0.githubusercontent.com/u/3274850?v=4" width="100px;" alt=""/><br /><b>Roy Li</b></a><br /><a title="Code">??</a> <a title="Documentation">??</a></td>
<td align="center"><a ><img src="https://avatars0.githubusercontent.com/u/5856440?v=4" width="100px;" alt=""/><br /><b>吖猩</b></a><br /><a title="Code">??</a></td>
</tr>
<tr>
<td align="center"><a ><img src="https://avatars1.githubusercontent.com/u/12657964?v=4" width="100px;" alt=""/><br /><b>Peng Gao</b></a><br /><a title="Code">??</a></td>
</tr>
</table>



This project follows the all-contributors specification. Contributions of any kind welcome!

License

MIT

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钮追,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子赞别,更是在濱河造成了極大的恐慌畏陕,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仿滔,死亡現(xiàn)場離奇詭異,居然都是意外死亡犹芹,警方通過查閱死者的電腦和手機(jī)崎页,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腰埂,“玉大人飒焦,你說我怎么就攤上這事∮炝” “怎么了牺荠?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長驴一。 經(jīng)常有香客問我休雌,道長,這世上最難降的妖魔是什么肝断? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任杈曲,我火速辦了婚禮驰凛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘担扑。我一直安慰自己恰响,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布涌献。 她就那樣靜靜地躺著胚宦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪燕垃。 梳的紋絲不亂的頭發(fā)上间唉,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音利术,去河邊找鬼呈野。 笑死,一個胖子當(dāng)著我的面吹牛印叁,可吹牛的內(nèi)容都是我干的被冒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼轮蜕,長吁一口氣:“原來是場噩夢啊……” “哼昨悼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起跃洛,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤率触,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后汇竭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葱蝗,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年细燎,在試婚紗的時候發(fā)現(xiàn)自己被綠了两曼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡玻驻,死狀恐怖悼凑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情璧瞬,我是刑警寧澤户辫,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站嗤锉,受9級特大地震影響渔欢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜档冬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一膘茎、第九天 我趴在偏房一處隱蔽的房頂上張望桃纯。 院中可真熱鬧,春花似錦披坏、人聲如沸态坦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伞梯。三九已至,卻和暖如春帚屉,著一層夾襖步出監(jiān)牢的瞬間谜诫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工攻旦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喻旷,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓牢屋,卻偏偏與公主長得像且预,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子烙无,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345