天天看點

Vue或React的多頁應用腳手架

前言

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

本套架構在項目上使用感覺還不錯(已跑在上百個頁面的項目上),是以決定開源出來給大家

閱讀完本文能實作在項目中使用es6(7)+元件化(.vue | .jsx)開發多頁應用

(其實我是想把它做為大家多頁應用的腳手架)

目錄結構介紹

tips:任何的項目的架構都和目錄結構有關,是以這部分非常重要,請仔細耐心閱讀

我們先宏觀的看下結構

|--- public // 生産環境下所需的檔案 

    |--- static 

        |--- css 

        |--- es6 

        |--- fonts 

        |--- images 

    |--- views 

|--- src 

    |--- assets 

    |--- components 

    |--- js 

    |--- sass 

    |--- views  

src裡的assets,components,js,sass裡的檔案最後都會生成到src/static下,這個作為我們dev中引用的資源檔案。而public不用說,是線上通路的檔案。

我們展開介紹下具體的頁面應該如何對應它的資源。拿js和views為例

|--- 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檔案也需要命名一一對應。

當然,我們還有第三方的js庫是不需要編譯的,是以我們專門用一個lib檔案夾來存放他們。(包括你自己編寫的指令或者filter等,不需要編譯的,也直接放在lib下引入即可)

另外,你還有許多自己寫的需要編譯的工具庫直接放在js目錄下即可(如,tools.js,common.js)

我們的sass也是同理

|--- sass 

    |--- home 

        |--- index.scss 

    |--- shopping 

        |--- buy.scss 

        ...  

他們編譯在static下的檔案将為

|--- static 

    |--- css // scss 編譯後的 

        |--- home 

            |--- index.css 

        |--- shopping 

            |--- buy.css 

    |--- js // babel處理後的js 

            |--- index.js 

            |--- buy.js  

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

... 

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

<script src="../../static/es6/lib/vue(react).js"></script> 

<script src="../../static/es6/lib/react.dom.js"></script> 

<script src="../../static/es6/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一樣。具體元件那就有所不同。

我們分為幾種類型的元件

一、目前頁面使用的元件

二、目前業務子產品下的公用元件

三、所有業務子產品的通用元件

目前頁面元件的命名,我們約定為 [頁面]-[元件].vue(jsx)

如下

        |--- index-info.vue(jsx)  

這個 index-info 的元件就僅僅隻有在home/index.html頁面下使用,當你修改了這個元件後,會自動編譯home/index.js路口js檔案并重新整理頁面。

目前業務子產品下的公用元件,我們約定為 [業務子產品]-[元件].vue(jsx)

    |--- common 

        |--- loading.vue(jsx)  

這個home-header元件就屬于home業務子產品下的公用元件,當你修改了這個元件後,會自動編譯home業務子產品下所有的js檔案并重新整理頁面。

剩下的就是所有業務子產品下的通用元件,我們約定全放在components/common目錄下,不需要具體命名約定

這個loading元件就屬于所有業務子產品下的公用元件,當你修改了這個元件後,會自動編譯所有業務子產品下的js檔案并重新整理頁面。

編譯元件的原理以及為什麼約定命名的原因是:

我會根據元件更改變動,去讀取檔案夾名,元件名,并編譯對應名的路口js

至此,我們就把元件的問題也解決了

由于我采用的是主gulp輔webpack,webpack僅僅隻編譯用,是以編譯基本達到秒編譯。比單純利用webpack做建構快得多。如果單純采用webpack做建構,需要去配置entry,配置htmlplugin。是以會慢得多,然而我這一套并不需要如此繁瑣。

圖檔&&字型檔案

這其實是一個大坑

我們的實作目标是元件能相對路徑引入圖檔或字型檔案

// 如 在html标簽裡這樣 

<template> 

    <figure> 

        <img src="../../assets/images/home/logo.jpg" alt="頭像"> 

    </figure> 

</template> 

// 在style裡這樣 

<style rel="stylesheet/scss" lang="sass"> 

    @import "../../sass/home/index-info"; 

    // 甚至可能在這@import面引入相對路徑,這都會算是在元件裡引入相對路徑 

    #bg h3 { 

        background: url("../../assets/images/holmes.jpg"); 

        color: #fff; 

    } 

</style>  

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

直接給大家看最後實作是怎樣的。

dev 的路徑是這樣,頁面可以顯示圖檔或字型。

Vue或React的多頁應用腳手架

build 後的路徑是這樣

Vue或React的多頁應用腳手架

這樣就達到了開發和釋出後的資源統一,摸索這一步真是挺累的 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);  

這樣就解決了我們不同環境下不同配置的問題,我預設配置了dev和production,大家可以自行拓展。比如

假設你需要在 開發中 配置測試,你可以寫一條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直接放在背景目錄下也沒有問題。

寫vue和react都沒問題,我把示例demo都寫好了,下面是分别兩個的repo位址。

todo

[ ] 項目的unit test

[ ] 項目cli腳手架

後話

本來是想寫成vue-cli或者是create-react-app這種cli腳手架的,但是!本人真是太懶又沒有時間了! 各位看官可以先嘗試clone把玩把玩,如果有足夠多人喜歡,我就把他寫成cli,釋出npm :)

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

最後給大家看下我們的某項目結構。

總覽

Vue或React的多頁應用腳手架

js部分

Vue或React的多頁應用腳手架

sass部分

Vue或React的多頁應用腳手架

元件和頁面

Vue或React的多頁應用腳手架

作者:二哲

來源:51cto

繼續閱讀