# webpack搭建本地服务器
目前我们开发的代码,为了运行需要有两个操作:
- 操作一:npm run build,编译相关的代码;
- 操作二:通过live server或者直接通过浏览器,打开index.html代码,查看效果;
这个过程经常操作会影响我们的开发效率,我们希望可以做到,当文件发生变化时,可以自动的完成 编译 和 展示;
- 为了完成自动编译,webpack提供了几种可选的方式:
- webpack watch mode;
- webpack-dev-server(常用);
- webpack-dev-middleware;
# webpack watch
webpack给我们提供了watch模式:
- 在该模式下,webpack依赖图中的所有文件,只要有一个发生了更新,那么代码将被重新编译;
- 我们不需要手动去运行 npm run build指令了;
如何开启watch呢?两种方式:
- 方式一:在导出的配置中,添加 watch: true;
- 方式二:在启动webpack的命令中,添加 --watch的标识;
# webpackDevServer webpack-dev-server
webpack-dev-server在早期版本项目是在这里启动的,但是后来有了webpack-cli就可以不需要从这里启动了
cnpm i webpack-dev-server -D
# 自动打包和刷新
- 方法一
......
"scripts": {
"watch": "webpack --watch"
},
......
运行:npm run watch(不能启动一个服务,如果有ajax请求,则无法使用)&如果没有类似vscode安装live server可能还需要手动刷新
- 方法二
"scripts": {
"build": "webpack",
"serve": "webpack serve"
}
命令行:npm run serve =>发现有serve这个参数,webpack-cli就会读取之后调用到webpack-dev-server启动服务
- contentBase:用途=> 一些较大的资源,不想在dev模式时通过CopyWebpackPlugin复制到dist目录耗时,可以通过配置contentBase,当在dev模式下找不到对应的文件,就会去查找contentBase对应的目录去读取。而生产环境再去通过CopyWebpackPlugin复制对应的文件。(也可以本地测试的代码和模块,不想线上也可以使用时采用)
const path = require("path");
module.exports = {
target: "web",
mode: "development",
devtool: "source-map",
devServer: {
// contentBase: "./public",// webpack5新版本移除了,取而代之的使用static
static: { // static: ['assets']
directory: path.join(__dirname, 'src')
},
hot: true,
host: "0.0.0.0",
port: 7777,
open: true,
// compress: true,
proxy: {
"/api": {
target: "http://localhost:8888",
pathRewrite: {
"^/api": ""
},
secure: false,
changeOrigin: true
}
}
},
resolve: {
extensions: [".js", ".json", ".mjs", ".vue", ".ts", ".jsx", ".tsx"],
alias: {
"@": path.resolve(__dirname, "./src"),
"js": path.resolve(__dirname, "./src/js")
}
},
};
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓相对老版本写法↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
devServer: {
contentBase: "./public",//W5废弃,转为static
hot: true,
host: "0.0.0.0",
port: 7777,
open: true,
// compress: true,
proxy: {
"/api": {
target: "http://localhost:8888",
pathRewrite: {
"^/api": ""
},
secure: false,
changeOrigin: true
}
}
}
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓老版本写法↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
cnpm i --save-dev webpack-dev-server
......
"scripts": {
"start":"webpack-dev-server"//启动一个服务
},
......
//webpack.config.js
......
devServer:{
contentBase:'./zip',
open:true//自动打开浏览器,如果不开启,可手动输入
},
......
webpack-dev-server
webpack-dev-server:一个服务器插件,相当于webpack+apache,启动一个web服务并实时更新修改 启动webpack-dev-server后,在目标文件夹中是看不到编译后的文件的,实时编译后的文件都保存到了内存当中。
- webpack不会实时更新修改,就只是一个打包工具,webpack-dev-server会实时自动更新修改
- webpack打包输出路径,output字段为path,webpack-dev-server打包输出路径,output字段为publicPath(此值为空时默认是项目根目录)
- webpack打包输出的文件,是真的存在于物理地址path中,而webpack-dev-server打包输出的文件,是保存在内存中的,在项目目录中是找不到的。
- 方法三 自己手动写一个node服务,监听变化,进行重新打包
步骤:使用webpack-dev-server 和 express框架来实现
# webpackDevServer实现请求转发
//proxy的配置
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true,
hotOnly: true,
proxy: {
'/react/api': {
target: 'https://www.dell-lee.com',
secure: false,//https的配置
pathRewrite: {
'header.json': 'demo.json'
},
changeOrigin: true,//突破代理转发的限制
headers: {
host: 'www.dell-lee.com',
}
}
}
},
# 单页面应用路由配置
//historyApiFallback: true,可配置其他的选项如果需要的话
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true,
hotOnly: true,
historyApiFallback: true,
proxy: {
'/react/api': {
target: 'https://www.dell-lee.com',
secure: false,
pathRewrite: {
'header.json': 'demo.json'
},
changeOrigin: true,
headers: {
host: 'www.dell-lee.com',
}
}
}
},
# devserver参数配置
host设置主机地址
- 默认值是localhost;通常情况下会被解析成127.0.0.1;:是个回环地址(Loop Back Address)
- 如果希望其他地方也可以访问,可以设置为 0.0.0.0;在同一个网段下的主机中,通过ip地址是可以访问的
port open compress- port端口
- open:默认值是false,设置为true会打开浏览器;
compress:是否为静态文件开启gzip compression:默认false
proxy跨域代理
- target:表示的是代理到的目标地址,比如 /api-hy/moment会被代理到 http://localhost:8888/apihy/moment;
- pathRewrite:默认情况下,我们的 /api-hy 也会被写入到URL中,如果希望删除,可以使用pathRewrite;
- secure:默认情况下不接收转发到https的服务器上,如果希望支持,可以设置为false;
- changeOrigin:它表示是否更新代理后请求的headers中host地址;
devServer: {
contentBase: "./public",
hot: true,
host: "0.0.0.0",
port: 7777,
open: true,
proxy: {
"/api": {
target: "http://localhost:8888",
pathRewrite: {
"^/api": "" //删除/api,换成空,因为真正的请求并没有/api这个,除非正好取的名字是一样的,那就不需要去除这个路径了
},
secure: false,
changeOrigin: true
}
}
},
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
},
devServer: {
// 运行代码的目录
contentBase: resolve(__dirname, 'build'),
// 监视 contentBase 目录下的所有文件,一旦文件变化就会 reload
watchContentBase: true,
watchOptions: {
// 忽略文件
ignored: /node_modules/
},
// 启动gzip压缩
compress: true,
// 端口号
port: 5000,
// 域名
host: 'localhost',
// 自动打开浏览器
open: true,
// 开启HMR功能
hot: true,
// 不要显示启动服务器日志信息
clientLogLevel: 'none',
// 除了一些基本启动信息以外,其他内容都不要显示
quiet: true,
// 如果出错了,不要全屏提示~
overlay: false,
// 服务器代理 --> 解决开发环境跨域问题
proxy: {
// 一旦devServer(5000)服务器接受到 /api/xxx 的请求,就会把请求转发到另外一个服务器(3000)
'/api': {
target: 'http://localhost:3000',
// 发送请求时,请求路径重写:将 /api/xxx --> /xxx (去掉/api)
pathRewrite: {
'^/api': ''
}
}
}
}
};
webpack中的devserver,可以模拟请求和跨域代理等操作
# devserver模拟请求
使用开发服务器配置before选项,可以编写接口,提供模拟数据。
devServer:{
before(app) {
app.get('/api/courses', (req, res) => {
res.json([
{ name: 'web全栈', price: 8999 },
{ name: 'web高级', price: 8999 }
])
})
}
}
调用:
import axios from 'axios'
export function getCourses() {
return axios.get('/api/courses').then(res => res.data)
}
# devserver跨域
devServer: {
proxy: 'http://localhost:3000'
}
← Entry&&Output 模块热更新 →