实际开发过程中,跨域问题是一个老生常谈的问题了,从webpack角度出发可提供以下三种解决方案。话不多说,直接上干货
proxy代理
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'development',
devServer: {
port: 3000,
hot: true,
open: true,
contentBase: path.join(__dirname, 'dist'),
compress: true,
proxy: {
'/api': {
target: 'http://localhost:8888',
pathRewrite: { '^/api': '' },
},
},
},
entry: './src/index.js',
output: {
filename: '[name][hash:8].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
},
],
},
resolve: {
extensions: ['.jsx', '.mjs', '.js', '.json'],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
}),
new CleanWebpackPlugin(),
],
}
如上配置,所有客户端“/api”的请求都会呗代理到“http://localhost:8888”,并且通过pathRewrite替换掉“/api”
Tips:
- 多个代理目标可以使用context: [];
- 隐藏主机头信息,changeOrigin: true;
- 默认情况下不会代理对 root 的请求,有需要时把 devServer.index 选项指定为虚假值''
devServer mock
使用devServer.before拦截所有请求,前端模拟服务端返回
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'development',
devServer: {
port: 3000,
hot: true,
open: true,
contentBase: path.join(__dirname, 'dist'),
compress: true,
before(app) {
app.get('/api/user', function(req, res) {
res.json({text: 'aibfk'})
res.end()
})
}
},
entry: './src/index.js',
output: {
filename: '[name][hash:8].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
},
],
},
resolve: {
extensions: ['.jsx', '.mjs', '.js', '.json'],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
}),
new CleanWebpackPlugin(),
],
}
before在所有中间件之前执行,参数app相当于express的app
服务端执行webpack
服务端拿到webpack配置,进行编译执行,此时相当于前端和服务端部署在同一个服务器上,且端口同服务端端口,webpack不用再关心devServer
要实现服务端执行webpack,需要借助webpack-dev-middleware
$ yarn add webpack-dev-middleware -D
server.js
const express = require('express')
const webpack = require('webpack')
const devMiddleWare = require('webpack-dev-middleware')
const app = express()
const config = require('./webpack.config.js')
const compiler = webpack(config)
app.use(devMiddleWare(compiler))
app.get('/user', (req, res) => {
res.json({name: 'user', age: 2000})
res.end()
})
app.listen(8888)
console.log('server running 8888');
然后启动服务,http://localhost:8888 可以访问到前端应用,并且不存在跨域问题,相当于绕开了前后端跨域的问题
除了webpack,还有很多解决跨域的方法,如nginx/docker中间代理,jsonp,cors等,有兴趣可以一起讨论!!!