2017年4月19日 星期三

[Vue.js] 使用 webpack / webpack-dev-server 之 Proxy 架構與後端 api 開發整合

使用 Vue.js 開發前端大概是今年的策略,一開始請同事試著把 embedded web interface 重構,碰到的第一個問題是,如何在桌機開發又能向 embedded device 發 request。如此一來,就是可以專心用 vue.js 開發網頁端,而 api 端也可以交給其他人開發,大家有一個共同整合測試的方式。這個在 server site 就是很直觀的 proxy 架構了,很幸運的,webpack 的彈性可以做到。

舉個例來說,我想讓 /json 這個 path 被包裝成回傳某筆資料,在此就用 ipinfo.io 來頂替一下。

https://webpack.js.org/configuration/dev-server/#devserver-proxy

module.exports = {
  entry: {
    app: './src/main.js'
  },
  devServer: {
    proxy: {
       '/json': {
          target: 'https://ipinfo.io/',
          secure: false
       },
    },
  },
...


然而,不知是不是因為我用 vue-cli 的關係:

$ vue init webpack my-project
$ npm list --depth=0
├── autoprefixer@6.7.7
├── babel-core@6.24.1
├── babel-loader@6.4.1
├── babel-plugin-transform-runtime@6.23.0
├── babel-preset-env@1.4.0
├── babel-preset-stage-2@6.24.1
├── babel-register@6.24.1
├── chalk@1.1.3
├── connect-history-api-fallback@1.3.0
├── copy-webpack-plugin@4.0.1
├── css-loader@0.26.4
├── eventsource-polyfill@0.9.6
├── express@4.15.2
├── extract-text-webpack-plugin@2.1.0
├── file-loader@0.10.1
├── friendly-errors-webpack-plugin@1.6.1
├── html-webpack-plugin@2.28.0
├── http-proxy-middleware@0.17.4
├── opn@4.0.2
├── optimize-css-assets-webpack-plugin@1.3.1
├── ora@1.2.0
├── rimraf@2.6.1
├── semver@5.3.0
├── shelljs@0.7.7
├── url-loader@0.5.8
├── vue@2.2.6
├── vue-loader@11.3.4
├── vue-style-loader@2.0.5
├── vue-template-compiler@2.2.6
├── webpack@2.4.1
├── webpack-bundle-analyzer@2.4.0
├── webpack-dev-middleware@1.10.1
├── webpack-hot-middleware@2.18.0
└── webpack-merge@2.6.1


搞了一陣子仍沒成功,且裡頭的確沒 webpack-dev-server :p 最後試了一些招術筆記一下,也看了很多大家再猜來猜去的論點。

總之,筆記兩種解法:

1.原先用 npm run dev 的方式啟動,乾脆改成用 webpack-dev-server 啟動方式,可以確定 devServer.proxy 的 設定有吃到

$ npm install webpack-dev-server --save-dev
$ node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config build/webpack.v.conf.js


2.直接上code! 依照原理實作

$ vim build/dev-server.js
var httpProxy = require("http-proxy");
var apiProxy = httpProxy.createProxyServer();
app.use("/json", function(req, res) {
  //console.log(req);
  req.url = req.baseUrl;
  apiProxy.web(req, res, {
    target: {
      port: 80,
      host: 'ipinfo.io'
    }
  });
});
$ npm run dev


如此一來,都可以解決 :p 可以用 curl -I http://localhost:8080/json 來驗證。

其實改 code 的方式就是不想多測試他的 config 倒底是文件寫錯,還是被改壞,直接靠原理硬解。