在工作過程中,逐步搭建的前後端分離方案和工具

quanxiaoxiao發表於2019-01-22

git repo github.com/quanxiaoxia…

在我目前工作環境下,服務端給個介面,我再根據介面所需要傳入的引數和返回的資料格式,來調整前端業務邏輯,有時候碰到服務端跑不起來,手頭上的工作就沒法再繼續了,所以我要有個mock server,首先想到的是json-server,但是我們服務端介面並不是標準的REST API,而且生成自己想要的資料還是太麻煩,也找不到別的更好的工具了,所以自己動手就寫個吧。

我的思路是這樣的,啟動一個服務,然後會讀取相關的配置檔案,能夠根據配置檔案上的url,能夠有這些處理:

  • 根據url關聯到相應的json檔案,比如請求路徑/aaa,返回./data/aaa.json檔案裡的資料
  • 有代理功能,比如請求路徑/bbb?name=aa&age=11,能夠代理到xxxx.com/aaa?name=aa…
  • 能夠結合mockjs,faker等這樣的工具
  • 可以根據請求引數,做出特定的響應
  • 對請求引數有校驗功能,如果請求引數不匹配,能夠通知到客戶端
  • 能夠結合webpack,這樣每次新建專案的時候就不用再寫webpack server了
  • 可以自定義外掛(中介軟體功能)
  • 能夠熱載入
  • 能夠建立webSocket,並能手動推送訊息到客戶端

有了需求後,接下來就是實現了
啟動專案的時候總有個命令名吧,那就叫norice好了,所以配置檔案叫norice.config.js

根據url關聯到相應的json檔案

module.exports = {
    paths: {
        '/aaa': './data/.json',    
    },
};複製程式碼

代理功能

module.exports = {
    paths: {
        '/aaa': 'http://proxy-path.com',
    },
};複製程式碼

可以對特定的路徑做出相應的代理,並能夠自定義header

module.exports = {
    paths: {
        '/aaa/*': {
            options: {
                pathRewrite: {
                    '^/aaa': '',
                },
                headers: {
                    Cookie: 'JSESSIONID=2342342DE234234',
                },
            },
            success: 'http://propx-path.com',
        },
    },  
};複製程式碼

這樣可以把http://localhost:3000/aaa/111/222,代理到http://proxy-path.com/111/222


結合mockjs,faker

const mock = require('mock');
const faker = require('faker');
const _ = require('lodash');
module.exports = {
    paths: {
        '/faker': ({ json }) => json(_.times(faker.random.number({ min:10, max: 20 }), i => ({
            index: i,
            name: faker.name.findName(),  
        }))),
        '/mockjs': ({ json }) => json(mock.mock({
            'list|1-10': [{
                'id|+1': 1,
            }],
        })),
    },
};複製程式碼

可以自定義狀態碼

module.exports = {
    paths: {
        '/aaa': {
            status: 400,
            success: {
                msg: 'params error',
            },
        },
    },
};複製程式碼

根據請求引數,做出特定的響應

module.exports = {
    paths: {
        '/aaa': ({ json, file, proxy, req }) => {
            const { name } = req.query;
            if (name === 'aaa') {
                json({ name: 'aaa' });
            } else if (name === 'bbb') {
                const convertor = d => ({ ...d, age: 11 });
                file('./data/file.json', convertor);
            } else if (name === 'ccc') {
                const convertor = d => ({ ...d, age: 22 });
                proxy('http://proxy-path.com/some/path', convertor);
            } else {
                throw new Error('no handle');
            }
        },
    },
};複製程式碼

對請求引數有校驗的功能

module.exports = {
    paths: {
        '/aaa': {
            validate: {
                name: Proptypes.oneOf(['quan', 'rice', 'foo']).isRequired,
                age: Proptypes.number,
                phone: Proptypes.match(/^1\d{10}$/),
                birthday: Proptypes.date('YYYY-MM-DD'), // 格式參考 http://momentjs.com/docs/#/parsing/string-format/
                address: Proptypes.isRequired,
            },
            success: { msg: 'success' },
            error: { msg: 'invalidate' },
        },
    },
};複製程式碼

結合webpack

module.exports = {
    webpack: './webpack.config.development.js', // webpack配置參考 https://github.com/glenjamin/webpack-hot-middleware 和 https://github.com/webpack/webpack-dev-middleware
    paths: {},
};複製程式碼

建立webSocket,並能手動推送訊息到客戶端

socket
socket


熱載入

hot load
hot load


自定義外掛(中介軟體功能)

const express = require('express');
const compression = rquire('compression');
module.exports = {
    middlewares: [
        compression(),
        express.static(path.resolve(__dirname, 'dist')),
    ],
    paths: {
        '/': './dist/index.html',
        '/quan': './dist/index.html',
        '/rice': {
            success: {
                name: 'rice',
            },
        },
    },
};複製程式碼

相關文章