gulp構建之mock data(模擬數據、轉發請求)

分割線如下是原來寫的,其實mock的原理很是簡單,就是攔截請求「轉發」到本地文件,所謂轉發,其實就是讀取本地mock文件,並以json或者script等格式返回給瀏覽器。以前的實現方式有一個問題,由於mock文件是require進來的,因此每當修改mock文件後,須要重啓服務,其實換個思路,咱們從文件裏面讀數據不久行了麼?javascript

//mockAPI.js

var fs = require('fs');
var path = require('path');

var mockbase = path.join(__dirname, 'mock');

var mockApi = function(res, pathname, paramObj, next) {
    switch (pathname) {
        case '/api/vote':
            var data = fs.readFileSync(path.join(mockbase, 'vote.json'), 'utf-8');

            // res.setHeader('Content-Type', 'application/json');
            res.setHeader('Content-type', 'application/javascript');
            res.end(paramObj.callback + '(' + data + ')');
            return ;

        case '/api/getUserInfo':
            var data = fs.readFileSync(path.join(mockbase, 'getUserInfo.json'), 'utf-8');
            res.setHeader('Content-type', 'application/javascript');
            res.end(paramObj.callback + '(' + data + ')');
            return ;
        case '/api/apply':
            var data = fs.readFileSync(path.join(mockbase, 'apply.json'), 'utf-8');
            res.setHeader('Content-type', 'application/javascript');
            res.end(paramObj.callback + '(' + data + ')');
            return ;
        default:
            ;
    }
    next();
};

module.exports = mockApi;
//gulpfile.js
var mockApi = require('./mockApi');
...
gulp.task('webserver', function() {
    gulp.src('./app')
        .pipe(webserver({
            ...
            middleware: function(req, res, next) {
                var urlObj = url.parse(req.url, true),
                    method = req.method,
                    paramObj = urlObj.query;
                // mock數據
                mockApi(res, urlObj.pathname, paramObj, next);
            }
        }));
});

知道了原理後,不管是ajax仍是jsonp,你想怎麼mock就怎麼mock。另外能夠利用webserver的proxies選項把請求代理到線上(經過代理解決跨域),這樣就不用本地的mock文件,而是直接請求線上或beta環境的接口了。前端


最近在使用gulp構建前端項目,這個基於node流並崇尚「編程而非配置」的工具立馬讓我愛上了它。由於以前使用公司的fekit,因此在使用gulp時就會想和fekit去比較,看看fekit的功能用gulp如何實現。fekit在先後端分離上作得很是好,基本能讓前端開發人員脫離後端環境進行開發,其中很重要的一個功能就是接口數據的mock。簡單地講,就是轉發ajax請求到本地的json(或mockjson)文件,這樣咱們在代碼裏寫真實的url(而不是寫一個本地的json文件地址),而後藉由fekit轉發到本地的json文件,這樣就輕鬆實現了接口的mock。 java

在此次項目中,我一樣有這樣的需求,舉個例子,我須要把/api/orders轉發到/mock/orders.json,前一個是我實際請求後端的地址(一個restful接口),後一個是我本地的json文件。 node

在使用gulp的時候,有一個叫gulp-mock的模塊,惋惜它是把mockjson轉化爲json的,不能實現反向代理式的轉發。另外一個模塊,proxy-middleware,能夠實現反向代理,但就我使用來看,是目錄級別的,好比配置/api/orders轉發到/mock/orders.json,它會說/mock/orders.json/不是一個目錄。 git

在幾番折騰各類搜索外加中途放棄的狀況下,我看了下gulp-webserver(我在gulp中使用的webserver模塊)的源碼,發現它開放了一個middleware,經過這個middleware咱們能夠攔截請求並處理(這個過程其實就是node http模塊作的事情)。由於gulp-webserver的文檔並無介紹這個參數的使用,因此以前我雖然知道但並無去嘗試,後來閱讀源碼發現gulp-webserver使用的實際上是connect這個模塊,而這個模塊有關於middleware的使用說明。到這裏,問題算是暫時性解決了。github

gulpfile.jsweb

gulp.task('webserver', function() {
    gulp.src('./market')
        .pipe(webserver({
            livereload: true,
            directoryListing: {
                enable:true,
                path: 'market'
            },
            port: 8000,
            // 這裏是關鍵!
            middleware: function(req, res, next) {
                var urlObj = url.parse(req.url, true),
                    method = req.method;
                switch (urlObj.pathname) {
                    case '/api/orders':
                        var data = {
                            "status": 0,
                            "errmsg": "", 
                            "data": [{}]
                        };
                        res.setHeader('Content-Type', 'application/json');
                        res.end(JSON.stringify(data));
                        return;
                    case '/api/goods':
                        // ...
                        return;
                    case '/api/images':
                        // ...
                        return;
                    default:
                        ;
                }
                next();
            }
        }));
});

這裏還只是簡單的把返回的數據寫在了gulpfile.js裏,實際上咱們也能夠把數據放在文件裏,而後require進來,此外咱們也能經過method區分處理不一樣請求。 ajax

這個也許不是惟一的解決辦法,但此次探索給了我很多啓示,這也是我在前面寫那麼多「廢話」的緣由。做爲一個成熟的開發人員,在遇到問題特別是經過搜索手段(包括詢問他人、看github的issue等)仍難以獲取有效信息的狀況時,咱們須要深刻問題自己(好比看源碼、探究實現原理),作探索問題的先驅者。編程

相關文章
相關標籤/搜索