# webpack搭建本地服务器

目前我们开发的代码,为了运行需要有两个操作:

  • 操作一:npm run build,编译相关的代码;
  • 操作二:通过live server或者直接通过浏览器,打开index.html代码,查看效果;

这个过程经常操作会影响我们的开发效率,我们希望可以做到,当文件发生变化时,可以自动的完成 编译 和 展示;

  • 为了完成自动编译,webpack提供了几种可选的方式:
    1. webpack watch mode;
    2. webpack-dev-server(常用);
    3. 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参数配置

  1. host设置主机地址

    • 默认值是localhost;通常情况下会被解析成127.0.0.1;:是个回环地址(Loop Back Address)
    • 如果希望其他地方也可以访问,可以设置为 0.0.0.0;在同一个网段下的主机中,通过ip地址是可以访问的
  2. port open compress

    • port端口
    • open:默认值是false,设置为true会打开浏览器;
    • compress:是否为静态文件开启gzip compression:默认false
  3. 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' 
}

跨域配置

最后更新: 1/21/2024, 4:03:34 PM