使用webpack-dev-server設置反向代理解決前端跨域問題

webpack-dev-server是一個小型的Node.js Express服務器,它使用webpack-dev-middleware來服務於webpack的包,除此自外,它還有一個經過Sock.js來鏈接到服務器的微型運行時.javascript

咱們來看一下下面的配置文件(webpack.config.js)css

var path = require("path");
module.exports = {
    entry:{
    app:["./app/main.js"]
    },
    output:{
    path:path.resolve(__dirname,"build"),
    publicPath:"/assets/",
    filename:"bundle.js"
}
}

  

這裏你將你的源文件放在app文件夾下,並經過webpack將其打包到build文件夾下的bundle.js中.html

注意:webpack-dev-server是一個獨立的NPM包,你能夠經過npm install webpack-dev-server來安裝它.java

基本目錄

webpack-dev-server默認會以當前目錄爲基本目錄,除非你制定它.node

webpack-dev-server --content-base build/

  

上述命令是在命令行中執行的,它將build目錄做爲根目錄.有一點須要注意的是:webpack-dev-server生成的包並無放在你的真實目錄中,而是放在了內存中.react

咱們在基本目錄下新建一個index.html文件,而後在瀏覽器中輸入http://localhost:8080訪問.jquery

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <script src="assets/bundle.js"></script>
</body>
</html>

  

webpack-dev-server啓動proxy代理

代理配置

webpack-dev-server使用http-proxy-middleware去把請求代理到一個外部的服務器,配置的樣例以下:webpack

//配置服務器
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        contentBase: "./app",
        port: 8090,
        proxy: {
            "/api": {
              target: 'http://localhost:8888',
              pathRewrite: {'^/api' : ''},
              changeOrigin: true
            }
        },
       
    },

  

這種代理在不少狀況下是很重要的,好比你能夠把一些靜態文件經過本地的服務器加載,而一些API請求所有經過一個遠程的服務器來完成。還有一個情景就是在兩個獨立的服務器之間進行請求分割,如一個服務器負責受權而另一個服務應用自己。web

pathRewrite: 對於代理的請求能夠經過提供一個函數來重寫,這個函數能夠查看或者改變http請求。下面的例子就會重寫HTTP請求,其主要做用就是移除URL前面的/api部分。npm

繞開代理

經過一個函數的返回值能夠視狀況的繞開一個代理。這個函數能夠查看http請求和響應以及一些代理的選項。它必須返回要麼是false要麼是一個URL的path,這個path將會用於處理請求而不是使用原來代理的方式完成。下面的例子的配置將會忽略來自於瀏覽器的HTTP請求,他和historyApiFallback配置相似。瀏覽器請求能夠像往常同樣接收到HTML文件,可是API請求將會被代理到另外的服務器:

proxy: {
  '/some/path': {
    target: 'https://other-server.example.com',
    secure: false,
    bypass: function(req, res, proxyOptions) {
      if (req.headers.accept.indexOf('html') !== -1) {
        console.log('Skipping proxy for browser request.');
        return '/index.html';
    }
  }
 }
}

 

代理本地虛擬主機

http-proxy-middleware會預解析本地hostname成爲localhost,你可使用下面的配置來修改這種默認行爲:

var server = new webpackDevServer(compiler, {
  quiet: false,
  stats: { colors: true },
  proxy: {
    "/api": {
      "target": {
        "host": "action-js.dev",
        "protocol": 'http:',
        "port": 80
      },
      ignorePath: true,
      changeOrigin: true,
      secure: false
    }
  }
});
server.listen(8080);

  

貼入我本身項目的webpack.config.js配置:

var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin'); //抽取CSS文件插件
var OpenBrowserPlugin = require('open-browser-webpack-plugin'); //自動打開瀏覽器插件
var ROOT_PATH = path.resolve(__dirname);
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');
var APP_PATH = path.resolve(ROOT_PATH, 'app');

module.exports = {
    //配置服務器
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        contentBase: "./app",
        port: 8090,
        proxy: {
            "/api": {
              target: 'http://localhost:8888',
              pathRewrite: {'^/api' : ''},
              changeOrigin: true
            }
        },
       
    },

    //配置入口, 支持多入口
    entry: {
        page: ROOT_PATH + '/app/src/router/router.jsx',
        vendors: ['react', 'react-dom', 'react-router', 'mobx']  //第三方庫和框架
    },

    output: {
        // path: "dist",
        publicPath: 'dist',
        filename: 'js/bundle.js'
    },

    module: {
        loaders: [
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })//此處不用loader,改成use
            },
            {
                test: /\.less$/,
                loader: ExtractTextPlugin.extract('css-loader!less-loader')
            },
            {
                test: /\.js[x]?$/,
                exclude: /node_modules/,
                loader: 'babel-loader'
            },
            { 
                test: /\.(png|jpg)$/,
                loader: 'url-loader?limit=8192&name=img/[name].[ext]'
            },
            { 
                test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
                loader: 'url-loader'
            }
        ]
    },

    resolve: {
        extensions: [' ', '.js', '.jsx']
    },

    plugins: [
        new webpack.optimize.CommonsChunkPlugin({ 'name': 'vendors', 'filename': 'js/vendors.js' }),
        new ExtractTextPlugin("css/bundle.css"),
        // 如需jquery請解鎖
        // new webpack.ProvidePlugin({ $: "jquery" }),
        new webpack.HotModuleReplacementPlugin(),
        new OpenBrowserPlugin({ url: 'http://localhost:8090/gallery' })
    ]
}

  

總結: 若有疑問請參考官方文檔 https://doc.webpack-china.org/concepts/

相關文章
相關標籤/搜索