vue、rollup、sass、requirejs組成的vueManager

小龍女先生發表於2017-05-15

近段時間本人一直在思考如何基於vue搭建一箇中後端管理系統的通用基礎前端解決方案。思考的主要問題點如下:

  • 如何使各個子業務模組的按需載入
  • css預處理方案的選擇
  • 如何引入現代的前端工程思想,也就是工程化解決方案。

多餘的話不說,本人按照效果圖介紹下自己的拙建,強烈希望各位給予建議和指正。

說明:

  1. 標題:一個普通的vue元件,利用requirejs載入完成。
  2. 二級選單:測試vue-route動態注入路由的能力
  3. 業務元件:測試和模組rollup編譯後vue實現的子系統的接入(按需載入)。
  4. 原始碼:github地址,需要切換為framework分支。

一、css預處理方案

這塊沒什麼好說的,由於本人只對sass比較熟悉,就引入了sass和compass。以及引入了gulp構建工具作為整體構建流程的控制。

二、前端工程化與按需載入

1. 前端打包工具

前端打包工具的選擇上,最終我選擇了rollup,而沒有選擇webpack的原因有如下幾點:

  1. rollup實現了tree-shaking,他可以根據函式的引用自動最少引入第三方依賴,這點看上去有點牽強,因為webpack2也引入了tree-shanking概念。
  2. rollup打包的模式更豐富,打包後的檔案結構也更為清晰
  3. rollup可以按需排除一些第三方引入庫,這讓我做requirejs按需載入時控制第三方庫的版本更為有效。如:多個子業務模組都引用了vue,但我們必須得保證所有引入的vue版本是一致的。
  4. rollup配置簡單

2. 按需載入

按需載入庫我選擇requirejs的理由如下:

  1. 按需載入的庫很多,如seajs、mod.js等,選擇requirejs由於我比較熟悉他。
  2. webpack也有按需拆包和載入的能力,但考慮到後期元件的增加,會讓webpack的編譯壓力更大,暫緩之。

三、根據程式碼說事

1. app資料夾

  • modules檔案:自定義模組化的vue元件
    此檔案儲存為多個獨立的vue元件,此類元件由一個js檔案和一個html檔案組成。此類元件的載入是由requirejs獲取檔案和組合實現(此方法在app.js中實現)。title元件程式碼如下:
    html:
<div>{{title}}</div>

      Js

define([],function(){
    return {
        name: 'ctitle',
        data: function(){
            return {
                title: '這是一個標題'
            }
        },
        beforeMount:function(){
            this.$store.dispatch('childs',[]);
        }
    };
});

注意:

  1. name的值必須為小寫。
  2. layout/default元件實現了整體介面的佈局,以及路由的跳轉(後期會優化)
var _event = event, self = this;
var chooseItem = function(item){
    router.push(item.href);
    self.$store.dispatch('selectRootItem', item);
}

self.$store.dispatch('childs',[]);

if(item.thridpart && !_cahce[item.id]){
    _app.acquire(item.path).done(function(arg){
        arg[0].install(_app.createContext());
        _cahce[item.id] = true;
        chooseItem(item);
    });
}else{
    chooseItem(item);
}

此部分為路由跳轉方法的原始碼,特別點在於第三方業務模組的載入,我需要require完成後才會執行路由的跳轉。

  • app.js 此類為requirejs和vue結合的核心檔案,主要提供瞭如下方法:
    1. createVue: vue例項的建立(注入vuex、vue-router等和三方元件)。
    2. createComponent: modules型別的元件載入。
    3. createContext: 建立提供給第三方業務元件的下文。
      在實現的過程中,大量的使用了promise,所以引入了jquery(後期會替換為直接的promise類庫)。
  • main.js和index.html 系統的入口檔案為index.html,其中匯入了requirejs和main.js的引用,main.js作為整個前端系統的入口,會載入全域性的vue元件,和建立一個vue例項。程式碼如下:
require(['./app'],function(app){
    var _app = app.createApp();
    _app.registerGlobalComponents(['title', 'route', 'layout/default']).done(function(){
        var vue = _app.createVue();
        vue.$mount('#app');
    });
});
  • chart.js和test.js
    這兩個檔案都是用於測試對vue元件的動態註冊,以及vue-router(路由)的動態元件,以及對store的操作。這兩個惟一不同的地方在於,chart.js是手動寫的,而test.js是通過rollup打包生成的(也就是src/master模擬的業務模組)。

2. assets資料夾

skin(皮膚樣式)的sass原始碼,皮膚的編譯是通過gulp任務完成的。

3. build資料夾

提供rollup打包的配置。配置檔案如下:

var VueLoader = require('rollup-plugin-vue');
var Resolve = require('rollup-plugin-node-resolve');
var Commonjs = require("rollup-plugin-commonjs");
var path = require('path');
var babel = require('rollup-plugin-babel');

module.exports = {
    entry: path.resolve(__dirname, '../src/master/index.js'),
    external: ['vue'],
    plugins: [VueLoader(), babel(), Resolve(), Commonjs()]
}

rollup打包呼叫:

var masterConfig = require('./rollup.dev.conf');
var rollup = require('rollup');
var path = require('path');
rollup.rollup(masterConfig).then(function(bundle){
    bundle.write({
        format: 'amd',
        dest: path.resolve(__dirname, '../dest/test.js')
    });
});

注意:

  1. external節點用於排除不需要打包的模組,可以第三方的,也可以是本地的。
  2. rollup的呼叫,是通過對nodejs提供的api實現的,所以我們打包是應該是輸入:node ./build/runtime-server.js

4. src資料夾

業務模組的原始碼目錄,此目錄下的程式碼需要通過rollup編譯後,才可使用。master模組是一個示例模組。

5. .babelrc和gulpfile.js

  1. .babelrc是babel的配置檔案,因為rollup不支援把babel作為配置引數節點傳入。
  2. gulpfile.js作為gulp構建任務的入口,實現了sass的編譯、dev模式任務。

6. 其他

  1. lib資料夾儲存的為requirejs需要引入的第三方庫,這裡就包含vue、vue-route、vuex、requirejs、text.js、css.js等。
  2. dest:暫時儲存rollup打包編譯生成的結果檔案。
  3. skin:css樣式檔案儲存的位置

相關文章