Vue或React多頁應用腳手架

yuren2013 8年前發布 | 37K 次閱讀 React CSS 前端技術 gulp

Vue或React多頁應用腳手架

前言

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

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

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

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

目錄結構介紹

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

我們先宏觀的看下結構

|--- public // 生產環境下所需的文件
    |--- static
        |--- css
        |--- es6
        |--- fonts
        |--- images
    |--- views
|--- src
    |--- assets
        |--- fonts
        |--- images
    |--- components
    |--- js
    |--- sass
    |--- static
        |--- css
        |--- es6
        |--- fonts
        |--- images
    |--- 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
        |--- home
            |--- index.js
        |--- shopping
            |--- 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)

如下

|--- 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="../../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 的路徑是這樣,頁面可以顯示圖片或字體。

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);

這樣就解決了我們不同環境下不同配置的問題,我默認配置了 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地址。

vue-multpage : https://github.com/MeCKodo/vue-multipage

react-multpage : https://github.com/MeCKodo/react-multipage

TODO

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

后話

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

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

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

總覽

js部分

sass部分

組件和頁面

Have a nice day

 

來自:http://div.io/topic/1819

 

 本文由用戶 yuren2013 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!