webpack-dev-server是一个小型的Node.js Express服务器,它使用webpack-dev-middleware来服务于webpack的包,除此自外,它还有一个通过Sock.js来连接到服务器的微型运行时.
我们来看一下下面的配置文件(webpack.config.js)
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中。
注意:webpack-dev-server是一个独立的NPM包,你可以通过npm install webpack-dev-server来安装它。
webpack-dev-server默认会以当前目录为基本目录,除非你制定它。
webpack-dev-server --content-base build/
上述命令是在命令行中执行的,它将build目录作为根目录.有一点需要注意的是:webpack-dev-server生成的包并没有放在你的真实目录中,而是放在了内存中.
我们在基本目录下新建一个index.html文件,然后在浏览器中输入http://localhost:8080访问.
Document
代理配置
webpack-dev-server使用http-proxy-middleware去把请求代理到一个外部的服务器,配置的样例如下:
//配置服务器
devServer: {
historyApiFallback: true,
hot: true,
inline: true,
contentBase: "./app",
port: 8090,
proxy: {
"/api": {
target: 'http://localhost:8888',
pathRewrite: {'^/api' : ''},
changeOrigin: true
}
},
},
这种代理在很多情况下是很重要的,比如你可以把一些静态文件通过本地的服务器加载,而一些API请求全部通过一个远程的服务器来完成。还有一个情景就是在两个独立的服务器之间进行请求分割,如一个服务器负责授权而另外一个服务应用本身。
pathRewrite: 对于代理的请求可以通过提供一个函数来重写,这个函数可以查看或者改变http请求。下面的例子就会重写HTTP请求,其主要作用就是移除URL前面的/api部分。
绕开代理
通过一个函数的返回值可以视情况的绕开一个代理。这个函数可以查看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' })
]
}