基於 Egg + Vue + Webpack 框架搭建


基於 Egg + Vue + Webpack 服務端渲染開發指南

1. 項目初始化

1.1 easywebpack-cli 腳手架初始化項目

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

  2. 命令行運行 easywebpack init

  3. 選擇 egg+vue server side render boilerplate 初始化骨架項目

  4. 安裝依賴 npm install

1.2 GitHub 倉庫代碼初始化項目

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

初始化的項目提供多頁面和SPA(vue-router/axios)服務端渲染實例,可以直接運行。

1.3 vscode 插件初始化項目

https://marketplace.visualstudio.com/items?itemName=hubcarl.vscode-easy-plugin#overview

2. 項目運行

2.1 本地運行

 
Bash
npm run dev // egg-bin dev

npm run dev 做了如下三件事情

  • 啟動 egg 應用

  • 啟動 Webpack 構建, 文件不落地磁盤,構建的文件都在內存里面(只在本地啟動, 發布模式是提前構建好文件到磁盤)

  • 構建會同時啟動兩個 Webpack 構建服務, 客戶端js構建端口9000, 服務端端口9001

  • 構建完成,Egg應用正式可用,自動打開瀏覽器

2.2 發布模式

  • 構建文件落地磁盤
 
Bash
npm run build 或 easy build prod
  1. 啟動 Webpack 構建,文件落地磁盤

  2. 服務端構建的文件放到 app/view 目錄

  3. 前端構建的文件放到 public 目錄

  4. 生成的 manifest.json 放到 config 目錄

  5. 構建的文件都是 gitignore 的,部署時請注意把這些文件打包進去

  • 運行

非 egg-scripts start 方式啟動時, 啟動應用前, 請設置 EGG_SERVER_ENV 環境變量,測試環境設置 test, 正式環境設置 prod

 
Bash
npm start // egg-scripts start

3. 項目構建

  • 通過 easywebpack-cli 統一構建,支持 dev,test,prod 模式構建

  • easywebpack-cli 通過項目根目錄下的 webpack.config.js 配置文件構造出 Webpack 實際的配置文件,配置項請見 webpack.config.js

  • 獲取 Webpack 實際的配置文件, egg-webpack 會使用到該功能。構建會根據 webpackConfigList.length 啟動對應個數的 Webpack 編譯實例,這里會同時啟動兩個 Webpack 構建服務, 客戶端jsbundle構建,端口9000, 服務端jsbundle構建端口9001。默認端口為9000, 端口依次遞增。

 
Javascript
// config/config.local.js 本地 npm start 使用 const EasyWebpack = require('easywebpack-vue'); exports.webpack = { webpackConfigList:EasyWebpack.getWebpackConfig() };
  • 該項目中,app/web/page 目錄中所有 .vue 文件當作 Webpack 構建入口是采用 app/web/framework/vue/entry 的 client-loader.js 和 *server-loader.js *模板實現的,這個需要結合 webpack.config.js 下的 entry.loader 使用。 骨架最新版本已被下面 node-glob 模式所替換。 這種方式可以自定義 entry 初始化模板。
 
Javascript
entry: { include: ['app/web/page'], exclude: ['app/web/page/[a-z]+/component', 'app/web/page/app'], loader: { // 如果沒有配置loader模板,默認使用 .js 文件作為構建入口 client: 'app/web/framework/vue/entry/client-loader.js', server: 'app/web/framework/vue/entry/server-loader.js', } }
  • 使用 node-glob 遍歷文件。下面配置會自動遍歷 app/web/page 目錄的所有 vue 文件作為 entry 入口,排除 component|components|view|views 目錄下的文件。 這個是 egg vue ssr 項目默認配置, 同時使用 vue-entry-loader 作為模板入口 。easywebpack@4.8.0 開始支持,因為有了默認配置,所以最新的骨架項目中,webpack.config.js 文件為非必須配置。
 
Javascript
// webpack.config.js module.exports = { // 注意 只有 entry 文件是 .vue 文件(非.js)時,才會自動使用 vue-entry-loader 模板 entry: 'app/web/page/**!(component|components|view|views)/*.vue' }

4. 項目規范

  • 遵循 egg 開發規范

  • Vue 項目代碼放到 app/web 目錄,頁面入口目錄為 page,該目錄的 所有 vue 文件默認會作為 Webpack 的 entry 構建入口。建議每個頁面目錄的只保留一個vue文件,vue關聯的組件可以放到widget 或者 compnent目錄。如果非要放到當前目錄,請配置 webpack.config.js entry.exclude 排除 vue文件。

 

 

5. 項目開發

支持多頁面/單頁面服務端渲染, 前端渲染, 靜態頁面三種方式.

5.1 多頁面服務端渲染實現

5.1.1 多頁面前端頁面實現

在app/web/page 目錄下面創建home目錄, home.vue 文件, Webpack自動根據.vue文件創建entry入口, 具體實現請見webpack.config.js

  • home.vue 編寫界面邏輯, 根元素為layout(自定義組件, 全局注冊, 統一的html, meta, header, body, 你可以自定義 title,description,keywords SEO信息,更多信息請擴展layout).
 
Html
<template> <layout title="egg vue ssr" 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 多頁面后端渲染實現, 通過 egg-view-vue-ssr 插件 render 方法實現

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

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

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

5.2 HTML靜態頁面前端渲染

  • 直接有easywebpack構建出靜態HTML文件, 請見 webpack.config.js 配置和 app/web/page/html代碼實現

  • 通過 egg-static 靜態文件訪問HTML文件

5.3 單頁面服務器渲染同構實現

5.3.1 單頁面前端實現

在app/web/page 目錄下面創建app目錄, app.vue, app.js 文件.

  • app.vue 編寫界面邏輯, 根元素為layout(自定義組件, 全局注冊, 統一的html, meta, header, body)
 
Html
<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 頁面調用入口
 
Javascript
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 單頁面后端實現

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

6. 項目部署

  • 正式環境部署,請設置 EGG_SERVER_ENV=prod 環境變量, 更多請見運行環境

  • 構建的 app/view 目錄, public 目錄以及 buildConfig.json 和 manifest.json等文件, 都是 gitignore 的,部署時請注意把這些文件打包進去。

7. 構建目錄

  • Webpack構建服務端(Node) JSBundle運行文件, 構建的服務端渲染模板文件位置 ${app_root}/app/view

  • Webpack構建瀏覽器JSBundle運行文件, 構建的前端資源(js/css/image)文件位置 ${app_root}/public

  • Webpack構建的 manifest.json 文件位置 ${app_root}/config 目錄

  • easywebpack-cli 構建配置文件 webpack.config.js 放到項目根目錄${app_root}/webpack.config.js

  • Vue代碼文件${app_root}/app/web 下面, 主要包括 assetcomponentframeworkpagestoreview 等目錄

 
 
├── asset
│   ├── css
│   │   ├── normalize.css
│   │   └── style.css
│   ├── images
│   │   ├── favicon.ico
│   │   ├── loading.gif
│   │   └── logo.png
├── component
│   ├── app
│   │   ├── detail.vue
│   │   ├── list.vue
│   │   └── router.js
│   ├── layout
│   │   ├── app
│   │   │   ├── content
│   │   │   │   ├── content.css
│   │   │   │   └── content.vue
│   │   │   ├── footer
│   │   │   │   ├── footer.css
│   │   │   │   └── footer.vue
│   │   │   ├── header
│   │   │   │   ├── header.css
│   │   │   │   └── header.vue
│   │   │   ├── index.js
│   │   │   └── main.vue
├── framework
│   ├── inject
│   │   ├── global.css
│   │   ├── inline.js
│   │   └── pack-inline.js
│   └── vue
│       ├── app.js
│       ├── component
│       │   └── index.js
│       ├── directive
│       │   └── index.js
│       └── filter
│           └── index.js
├── page
│   ├── app
│   │   ├── app.js
│   │   └── app.vue
│   ├── index
│   │   ├── index.css
│   │   ├── index.js
│   │   └── index.vue
├── store
│   └── app
│       ├── actions.js
│       ├── getters.js
│       ├── index.js
│       ├── mutation-type.js
│       └── mutations.js
└── view
    └── layout.html

二. 項目結構和基本規范

 
 
├── app
│   ├── controller
│   │   ├── test
│   │   │   └── test.js
│   ├── extend
│   ├── lib
│   ├── middleware
│   ├── mocks
│   ├── proxy
│   ├── router.js
│   ├── view
│   │   ├── about                         // 服務器編譯的jsbundle文件
│   │   │   └── about.js
│   │   ├── home
│   │   │     └── home.js                 // 服務器編譯的jsbundle文件
│   │   └── layout.js                     // 編譯的layout文件
│   └── web                               // 前端工程目錄
│       ├── asset                         // 存放公共js,css資源
│       ├── framework                     // 前端公共庫和第三方庫
│       │   └── entry                          
│       │       ├── loader.js              // 根據jsx文件自動生成entry入口文件loader
│       ├── page                           // 前端頁面和webpack構建目錄, 也就是webpack打包配置entryDir
│       │   ├── home                       // 每個頁面遵循目錄名, js文件名, scss文件名, jsx文件名相同
│       │   │   ├── home.scss
│       │   │   ├── home.jsx
│       │   └── hello                      // 每個頁面遵循目錄名, js文件名, scss文件名, jsx文件名相同
│       │       ├── test.css               // 服務器render渲染時, 傳入 render('test/test.js', data)
│       │       └── test.jsx
│       ├── store                             
│       │   ├── app
│       │   │   ├── actions.js
│       │   │   ├── getters.js
│       │   │   ├── index.js
│       │   │   ├── mutation-type.js
│       │   │   └── mutations.js
│       │   └── store.js
│       └── component                         // 公共業務組件, 比如loading, toast等, 遵循目錄名, js文件名, scss文件名, jsx文件名相同
│           ├── loading
│           │   ├── loading.scss
│           │   └── loading.jsx
│           ├── test
│           │   ├── test.jsx
│           │   └── test.scss
│           └── toast
│               ├── toast.scss
│               └── toast.jsx
├── config
│   ├── config.default.js
│   ├── config.local.js
│   ├── config.prod.js
│   ├── config.test.js
│   └── plugin.js
├── doc
├── index.js
├── webpack.config.js                      // easywebpack-cli 構建配置
├── public                                 // webpack編譯目錄結構, render文件查找目錄
│   ├── static
│   │   ├── css
│   │   │   ├── home
│   │   │   │   ├── home.07012d33.css
│   │   │   └── test
│   │   │       ├── test.4bbb32ce.css
│   │   ├── img
│   │   │   ├── change_top.4735c57.png
│   │   │   └── intro.0e66266.png
│   ├── test
│   │   └── test.js
│   └── vendor.js                         // 生成的公共打包庫

8. 項目和插件


From: easyjs
Author: sky
Link: https://easyjs.cn/egg-vue/init/
本文章著作權歸作者所有,任何形式的轉載都請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM