Vue多頁應用腳手架

前言

一直以來都在研究多頁應用如何能有一套像SPA同樣優雅的開發模式css

本套架構在項目上使用感受還不錯(已跑在上百個頁面的項目上),因此決定開源出來給你們html

閱讀完本文能實如今項目中使用ES6(7)+組件化(.vue | .jsx)開發多頁應用前端

若是你不須要SEO,須要先後端分離,項目是多頁應用,選擇我就對了vue

(其實我是想把它作爲你們多頁應用的腳手架)react

目錄結構介紹

TIPS:任何的項目的架構都和目錄結構有關,因此這部分很是重要,請仔細耐心閱讀webpack

咱們先宏觀的看下結構git

|--- public // 生產環境下所需的文件
    |--- components
    |--- css
    |--- fonts
    |--- images
    |--- js
    |--- sass
    |--- views
|--- src
    |--- components
    |--- css
    |--- fonts
    |--- images
    |--- js
    |--- sass
    |--- views複製代碼

咱們展開介紹下具體的頁面應該如何對應它的資源。拿jsviews爲例github

|--- views
    |--- home // 官網介紹 業務模塊
        |--- index.html
        ...
    |--- shopping // 購物業務模塊
        |--- buy.html
        ...
|--- js
    |--- lib
        |--- vue.js
        |--- react.js
        |--- react.dom.js
        ...
    |--- home // 官網介紹業務模塊的js
        |--- index.js
        ...
    |--- shopping // 購物業務模塊的js
        |--- buy.js
        ...
    tools.js
    common.js複製代碼

在多頁應用中,每每咱們的頁面以業務模塊劃分,業務模塊由許多的頁面組成。
home,shopping,可能就分別爲官網介紹和購物的業務模塊。在這業務模塊下,分別有許多個頁面,那咱們的js文件也須要命名一一對應。web

固然,咱們還有第三方的js庫是不須要編譯的,因此咱們專門用一個lib文件夾來存放他們。(包括你本身編寫的指令或者filter等,不須要編譯的,也直接放在lib下引入便可)ajax

另外,你還有許多本身寫的須要編譯的工具庫直接放在js目錄下便可(如,tools.js,common.js)


咱們的sass也是同理

|--- sass
    |--- home
        |--- index.scss
        ...
    |--- shopping
        |--- buy.scss
        ...複製代碼

他們會分別編譯在cssjs下的文件將爲

|--- css // scss 編譯後的
    |--- home
        |--- index.css
    |--- shopping
        |--- buy.css
|--- js // babel處理後的js
    |--- home
        |--- index.js
    |--- shopping
        |--- buy.js複製代碼

頁面引用的路徑就爲(home/index.html爲例)

...
<link rel="stylesheet" href="../../js/css/home/index.css">

...

<script src="../../js/lib/vue(react).js"></script>
<script src="../../js/lib/react.dom.js"></script>
<script src="../../js/home/index.js"></script>
...複製代碼

js和sass搞定了後,咱們的難點是編寫組件的過程當中,如何知道應該編譯哪一個入口js文件呢?
因此咱們須要對咱們的組件名進行一些約定,這也就是約定大於配置的前提。

|--- components
    |--- home // home 業務模塊
        |--- home-header.vue(jsx)
        |--- index-info.vue(jsx)
        ...
    |--- shopping  // shopping 業務模塊
        |--- buy-list.vue(jsx)
        ...複製代碼

咱們components下的業務模塊名和以前的sass,js同樣。具體組件那就有所不一樣。

咱們分爲幾種類型的組件

  • 1、當前頁面使用的組件
  • 2、當前業務模塊下的公用組件
  • 3、全部業務模塊的通用組件

當前頁面組件的命名,咱們約定爲 [頁面]-[組件].vue(jsx)

以下

|--- components
    |--- home
        |--- index-info.vue(jsx)複製代碼

這個index-info的組件就僅僅只有在home/index.html頁面下使用,當你修改了這個組件後,會自動編譯home/index.js路口js文件並刷新頁面。

當前業務模塊下的公用組件,咱們約定爲 [業務模塊]-[組件].vue(jsx)

以下

|--- components
    |--- home
        |--- home-header.vue(jsx)複製代碼

這個home-header組件就屬於home業務模塊下的公用組件,當你修改了這個組件後,會自動編譯home業務模塊下全部的js文件並刷新頁面。

剩下的就是全部業務模塊下的通用組件,咱們約定全放在components/common目錄下,不須要具體命名約定

|--- components
    |--- common
        |--- loading.vue(jsx)複製代碼

這個loading組件就屬於全部業務模塊下的公用組件,當你修改了這個組件後,會自動編譯全部業務模塊下的js文件並刷新頁面。

編譯組件的原理以及爲何約定命名的緣由是:

我會根據組件更改變更,去讀取文件夾名,組件名,並編譯對應名的路口js

至此,咱們就把組件的問題也解決了

因爲我採用的是主gulp輔webpack,webpack僅僅只編譯用,因此編譯基本達到秒編譯。比單純利用webpack作構建快得多。若是單純採用webpack作構建,須要去配置entry,配置HTMLPlugin。因此會慢得多,然而我這一套並不須要如此繁瑣。

圖片&&字體文件

這實際上是一個大坑

咱們的實現目標是組件能相對路徑引入圖片或字體文件

// 如 在html標籤裏這樣
<template>
    <figure>
        <img src="../../images/home/logo.jpg" alt="頭像">
    </figure>
</template>

// 在style裏這樣
<style rel="stylesheet/scss" lang="sass">
    @import "../../sass/home/index-info";
    // 甚至可能在這@import面引入相對路徑,這都會算是在組件裏引入相對路徑
    #bg h3 {
        background: url("../../images/holmes.jpg");
        color: #fff;
    }
</style>複製代碼

這個坑,真是不可描述,我我的嘗試了各類體位,才把這個坑配置好。

直接給你們看最後實現是怎樣的。

dev 的路徑是這樣,頁面能夠顯示圖片或字體。

build 後的路徑是這樣

這樣就達到了開發和發佈後的資源統一,摸索這一步真是挺累的 T.T,有興趣的本身看源碼吧。

環境變量的配置

咱們在webpack中常常會碰見不一樣環境下不一樣配置的問題

首先可在package.json裏配置一條script

// package.json
"scripts": {
    "build": "NODE_ENV=production gulp build",
    "dev": "NODE_ENV=dev gulp reload"
},複製代碼

假設咱們須要爲不一樣環境配置不一樣的api請求地址,就能夠利用咱們在package.json設置的NODE_ENV來識別當前環境(這部分我在gulpfile中處理了,因此在文件裏可直接識別NODE_ENV,以下)

// src/js/ajaxurl.js

const server1 = 'https://production.server.com';
const server2 = 'https://dev.server.com';

let useServer = null;
if(NODE_ENV === 'production') {
    useServer = server1;
} else if(NODE_ENV === 'dev') {
    useServer = server2;
}

export default useServer;複製代碼
// src/js/home/index.js

import url from '../ajaxurl';
console.log(url);複製代碼

這樣就解決了咱們不一樣環境下不一樣配置的問題,我默認配置了devproduction,你們能夠自行拓展。好比

假設你須要在 開發中 配置測試,你能夠寫一條NODE_ENV=test gulp reload

若是須要 預發佈打包 測試,就能夠另外一條NODE_ENV=preproduction gulp build

總之就是打包使用gulp build,開發使用gulp reload

注意事項

開發:執行命令 npm run dev
發佈:執行命令 npm run build (BTW,別忘了去gulpfile.js裏替換你的CDN連接,進入gulp文件修改 const CDN = 'yourCDNLink'這裏的變量便可)

命名必定要按約定來!
命名必定要按約定來!
命名必定要按約定來!

不然不知道要編譯誰!!!

gulp配置很簡單,你們能夠看一下針對各自項目進行修改,不懂得能夠直接問我。

若是大家不徹底的先後端分離,把這個src直接放在後臺目錄下也沒有問題。

TODO

  • [ ] 項目的Unit test
  • [ ] 項目Cli腳手架

後話

原本是想寫成vue-cli或者是create-react-app這種cli腳手架的,可是!本人真是太懶又沒有時間了! 各位看官能夠先嚐試clone把玩把玩,若是有足夠多人喜歡,我就把他寫成cli,發佈npm :)

我是用mac下開發完成的,用了半天多時間專門去給window寫了兼容,window還可能會有bug,不是我說!window就是辣雞!

最後給你們看下咱們的某項目結構。


總覽

總覽

js部分

js部分

images

images

組件

組件和頁面

大家可能在總覽的圖會發現多了apismock文件夾,這個是咱們promise封裝接口層和前端本地mock層,因爲每一個團隊的作法都不一樣,我就沒有放在此次的腳手架裏

vue-multpage 通用版: github.com/MeCKodo/vue…

這個是咱們內部的版本


Have a nice day

相關文章
相關標籤/搜索