Webpack(二十一):比mock模擬數(shù)據(jù)更簡(jiǎn)單的方式

### 目錄結(jié)構(gòu)如下:
demo1                                       # 工程名
|   |--- dist                               # 打包后生成的目錄文件             
|   |--- node_modules                       # 所有的依賴包
|   |--- app
|   | |---index
|   | | |-- views                           # 存放所有vue頁(yè)面文件
|   | | | |-- parent.vue                    # 父組件
|   | | | |-- child.vue                     # 子組件
|   | | | |-- index.vue
|   | | |-- components                      # 存放vue公用的組件
|   | | |-- js                              # 存放js文件的
|   | | |-- store                           # store倉(cāng)庫(kù)
|   | | | |--- actions.js
|   | | | |--- mutations.js
|   | | | |--- state.js
|   | | | |--- mutations-types.js
|   | | | |--- index.js
|   | | |-- app.js                          # vue入口配置文件
|   | | |-- router.js                       # 路由配置文件
|   |--- views
|   | |-- index.html                        # html文件
|   |--- json                               # 存放所有模擬數(shù)據(jù)
|   | |-- parent_getPower.json
|   | |-- parent_reConfig.json
|   | |-- parent_reconlist.json
|   | |-- parent_reGroup.json 
|   |--- mock.js                            # mock 數(shù)據(jù)的所有調(diào)用方法
|   |--- webpack.config.js                  # webpack配置文件 
|   |--- .gitignore  
|   |--- README.md
|   |--- package.json
|   |--- .babelrc                           # babel轉(zhuǎn)碼文件

項(xiàng)目的結(jié)構(gòu)如上所示:其中 json 文件夾內(nèi)會(huì)存放所有模擬的數(shù)據(jù),比如和開(kāi)發(fā)后臺(tái)約定好的數(shù)據(jù),我可以直接把數(shù)據(jù)復(fù)制到j(luò)son文件內(nèi)盆赤,比如我們簡(jiǎn)單的看下 parent_reConfig.json 數(shù)據(jù)代碼如下(假如開(kāi)發(fā)接口返回的數(shù)據(jù)是這樣的):

{
  "data": [{
      "bTableName": "reconfig",
      "businessCode": "reconfig",
      "businessImportImpl": "reconfig",
      "businessImportMethod": "reconfig",
      "businessName": "reconfig"
    }
  ],
  "code": 0
}

其他的json文件也是類似的數(shù)據(jù)霉祸,這里不一一貼代碼哦脐湾,有興趣的話乳乌,可以到下面的github上查看demo捧韵。

json文件命名方式:比如我上面json下的叫 parent_reConfig.json, 因?yàn)関ue頁(yè)面叫 parent.vue, 所以前綴就是頁(yè)面的名稱,然后下劃線(_) + reConfig + 'json', 其中reConfig 是接口的最后一個(gè)名字汉操,這樣命名的話再来,我一眼就可以知道是那個(gè)頁(yè)面下的接口,接口是做什么使用的磷瘤。方便以后接口很多更容易區(qū)分芒篷。

2. 在項(xiàng)目的根目錄下 mock.js 代碼是如下所示:

const getPower = require('./json/parent_getPower.json');
const reConfig = require('./json/parent_reConfig.json');
const reConList = require('./json/parent_reconlist.json');
const reGroup = require('./json/parent_reGroup.json');

function Mock(app) {
  app.get('/xxxx/yyy', function(req, res) {
    console.log('getPower111');
    res.json(getPower);
  });
  app.post('/reconfig', function(req, res) {
    console.log('reConfig111');
    res.json(reConfig);
  });
  app.post('/conlist', function(req, res) {
    console.log('reConList111');
    res.json(reConList);
  });
  app.post('/regroup', function(req, res) {
    console.log('reGroup111');
    res.json(reGroup);
  });
}

module.exports = Mock;

如上代碼首先是把 json文件夾下的所有的json文件 require進(jìn)來(lái),然后定義一個(gè)函數(shù)采缚,里面寫所有的(get或post)方法针炉,然后使用 res.json 方式就可以把上面的json數(shù)據(jù)模擬返回回來(lái)。如上的app參數(shù)是從webpack.config.js 配置傳進(jìn)來(lái)的扳抽。

3. webpack.config.js 配置方式如下:

// 引入mock.js
const Mock = require('./mock.js');

module.exports = {
  devServer: {
    port: 8082,
    host: '0.0.0.0',
    headers: {
      'X-foo': '112233'
    },
    inline: true,
    overlay: true,
    stats: 'errors-only',
    before: function(app) {
      console.log(app);
      if (process.env.NODE_ENV === 'mock') {
        Mock(app);
      }
    }
  },
  plugins: [
    // 設(shè)置環(huán)境變量信息
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV)
      }
    })
  ]
}

如上配置代碼篡帕,首先引入 mock.js 進(jìn)來(lái),上面的mock.js對(duì)外返回函數(shù)贸呢,因此在devServer.before中配置調(diào)用下Mock函數(shù)镰烧,傳入?yún)?shù)是app,并且環(huán)境變量也判斷了下楞陷,如果是 mock環(huán)境怔鳖,就執(zhí)行mock函數(shù)代碼的數(shù)據(jù),否則不是mock命令的話固蛾,就不會(huì)執(zhí)行mock數(shù)據(jù)结执,而是執(zhí)行真正環(huán)境的數(shù)據(jù)。下面我們來(lái)看下 上面 before函數(shù)打印的app是什么東西魏铅,如下所示:

{ [EventEmitter: app]
  domain: undefined,
  _events: { mount: [Function: onmount] },
  _maxListeners: undefined,
  setMaxListeners: [Function: setMaxListeners],
  getMaxListeners: [Function: getMaxListeners],
  emit: [Function: emit],
  addListener: [Function: addListener],
  on: [Function: addListener],
  prependListener: [Function: prependListener],
  once: [Function: once],
  prependOnceListener: [Function: prependOnceListener],
  removeListener: [Function: removeListener],
  removeAllListeners: [Function: removeAllListeners],
  listeners: [Function: listeners],
  listenerCount: [Function: listenerCount],
  eventNames: [Function: eventNames],
  init: [Function: init],
  defaultConfiguration: [Function: defaultConfiguration],
  lazyrouter: [Function: lazyrouter],
  handle: [Function: handle],
  use: [Function: use],
  route: [Function: route],
  engine: [Function: engine],
  param: [Function: param],
  set: [Function: set],
  path: [Function: path],
  enabled: [Function: enabled],
  disabled: [Function: disabled],
  enable: [Function: enable],
  disable: [Function: disable],
  acl: [Function],
  bind: [Function],
  checkout: [Function],
  connect: [Function],
  copy: [Function],
  delete: [Function],
  get: [Function],
  head: [Function],
  link: [Function],
  lock: [Function],
  'm-search': [Function],
  merge: [Function],
  mkactivity: [Function],
  mkcalendar: [Function],
  mkcol: [Function],
  move: [Function],
  notify: [Function],
  options: [Function],
  patch: [Function],
  post: [Function],
  propfind: [Function],
  proppatch: [Function],
  purge: [Function],
  put: [Function],
  rebind: [Function],
  report: [Function],
  search: [Function],
  subscribe: [Function],
  trace: [Function],
  unbind: [Function],
  unlink: [Function],
  unlock: [Function],
  unsubscribe: [Function],
  all: [Function: all],
  del: [Function],
  render: [Function: render],
  listen: [Function: listen],
  request: IncomingMessage { app: [Circular] },
  response: ServerResponse { app: [Circular] },
  cache: {},
  engines: {},
  settings: {},
  _eventsCount: 1,
  locals: 
   { settings: {}},
  mountpath: '/',
  _router: {} 
}

更多關(guān)于 devServer.before可以看官網(wǎng)(https://webpack.js.org/configuration/dev-server/#devserver-before)昌犹。

4. package.json 配置如下:

{
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --progress --colors --devtool cheap-module-eval-source-map --hot --inline",
    "build": "cross-env NODE_ENV=production webpack --progress --colors --devtool cheap-module-source-map",
    "build:dll": "webpack --config webpack.dll.config.js",
    "start": "webpack-dev-server --progress --colors --devtool cheap-module-eval-source-map --hot --inline",
    "mock": "cross-env NODE_ENV=mock npm run start"
  },
}

5. app/index/views/parent.vue 代碼如下所示:

<template>
  <div>
  </div>
</template>
<script type="text/javascript">
  import { mapActions } from 'vuex';
  export default {
    data() {
      return {
      }
    },
    created() {
      this.testMock();
    },
    methods: {
      testMock() {
        const obj = {
          'xx': 11
        };
        // 請(qǐng)求的地址是 '//xxx.abc.com/xxxx/yyy'
        Promise.all([this.commonActionGet(['getPower', obj])]).then((res) => {
          console.log('getPower');
          console.log(typeof res);
          console.log(res);
        });

        Promise.all([this.commonActionPost(['reConfig', obj])]).then((res) => {
          console.log('reConfig');
          console.log(res);
        });

        Promise.all([this.commonActionPost(['reConList', obj])]).then((res) => {
          console.log('reConList');
          console.log(res);
        });

        Promise.all([this.commonActionPost(['reGroup', obj])]).then((res) => {
          console.log('reGroup');
          console.log(res);
        });
      },
      ...mapActions(['commonActionGet', 'commonActionGetJSON', 'commonActionPost', 'commonActionPostJSON'])
    },
    mounted() {

    }
  }
</script>

如上代碼,當(dāng)我執(zhí)行打包命令 npm run mock 時(shí)览芳,就會(huì)調(diào)用webpack中的 devServer.before函數(shù)斜姥,該函數(shù)會(huì)判斷當(dāng)前的環(huán)境是否是mock命令,如果是mock命令就執(zhí)行 mock.js中的Mock函數(shù)沧竟,然后會(huì)請(qǐng)求數(shù)據(jù)铸敏。

注意:上面的請(qǐng)求數(shù)據(jù)是:'//0.0.0.0:8082/reconfig' 這樣的,這樣就可以把 json/parent_reConfig.json請(qǐng)求的數(shù)據(jù)返回回來(lái)悟泵,但是我們真正的接口的前綴可能是 '//xxx.abc.com', 因此我們?cè)谂渲盟械慕涌诿Q的時(shí)候杈笔,接口域名的前綴我們可以定義一個(gè)變量,然后傳遞進(jìn)去糕非。比如我下面是這樣定義的:

// const prefix = '//xxx.abc.com'; // 真正的域名接口先注釋掉
const prefix = '//0.0.0.0:8082';

我們可以簡(jiǎn)單的判斷下:

let prefix;
if (process.env.NODE_ENV === 'mock') {
  prefix = '//0.0.0.0:8082'; // 測(cè)試域名
} else {
  prefix = '//xxx.abc.com'; // 正式域名
}

const url = prefix + '/reconfig';

類似上面這中形式蒙具,因此當(dāng)我們?cè)陧?yè)面上請(qǐng)求 this.$http.get(url);的時(shí)候球榆,實(shí)際上在mock數(shù)據(jù)下請(qǐng)求的是 '//0.0.0.0:8082/reconfig' 這樣的,因此會(huì)直接被 devServer.before中攔截到禁筏,因此會(huì)返回我們的模擬上的數(shù)據(jù)持钉,但是在我們使用 npm run dev 或 npm run build 的時(shí)候,我們需要把 //xxx.abc.com 這個(gè)真正的接口域名前綴打開(kāi)篱昔,'//0.0.0.0:8082' 需要被注釋掉每强。就可以了,其他的vue中的代碼不需要做任何改動(dòng)州刽,以前該怎么寫空执,現(xiàn)在也還是就那么寫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末穗椅,一起剝皮案震驚了整個(gè)濱河市辨绊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌房待,老刑警劉巖邢羔,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異桑孩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)框冀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門流椒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人明也,你說(shuō)我怎么就攤上這事宣虾。” “怎么了温数?”我有些...
    開(kāi)封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵绣硝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我撑刺,道長(zhǎng)鹉胖,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任够傍,我火速辦了婚禮甫菠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冕屯。我一直安慰自己寂诱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布安聘。 她就那樣靜靜地躺著痰洒,像睡著了一般瓢棒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丘喻,一...
    開(kāi)封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天脯宿,我揣著相機(jī)與錄音,去河邊找鬼仓犬。 笑死嗅绰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搀继。 我是一名探鬼主播窘面,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叽躯!你這毒婦竟也來(lái)了财边?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤点骑,失蹤者是張志新(化名)和其女友劉穎酣难,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黑滴,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡憨募,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了袁辈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菜谣。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖晚缩,靈堂內(nèi)的尸體忽然破棺而出尾膊,到底是詐尸還是另有隱情,我是刑警寧澤荞彼,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布冈敛,位于F島的核電站,受9級(jí)特大地震影響鸣皂,放射性物質(zhì)發(fā)生泄漏抓谴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一签夭、第九天 我趴在偏房一處隱蔽的房頂上張望齐邦。 院中可真熱鬧,春花似錦第租、人聲如沸措拇。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丐吓。三九已至浅悉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間券犁,已是汗流浹背术健。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粘衬,地道東北人荞估。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像稚新,于是被迫代替她去往敵國(guó)和親勘伺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355