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使用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/