webpack中是如何让项目开发调试,变得更加高效的?

前面几篇文章,详细介绍过webpack的核心配置项,入口起点、出口文件加载器loader插件plugin,感兴趣的可以前往查看

项目开发,一般都是在本地起一个服务,进行代码的运行和调试。前面几篇文章介绍到了,webpack 对项目进行编译打包,方便在浏览器上运行。

那么问题来了,怎么样让打包好的项目文件,在浏览器上运行起来呢?

webpack中提供的开发环境工具 devServer,让打包的项目在浏览器上运行,通过配置devServer的属性,使开发过程更加高效地进行调试和测试

webpack-dev-server (简写: dev-server),用于快速开发应用程序。

devServer 的主要作用包括:

  1. 提供本地服务器:devServer 启动一个本地服务器,使得你可以在本地环境中访问和测试你的 Webpack 项目。
  2. 实时重新加载:devServer 能够实时监测你的代码更改,并在保存文件时自动重新加载页面,以便你能够立即看到更改的效果。
  3. 热模块替换(HMR):devServer 支持热模块替换功能,使得在不刷新整个页面的情况下,更新已加载的模块。
  4. 自动打开浏览器:devServer 可以自动打开浏览器并显示你的项目页面,方便你直接进行开发和调试。
  5. 提供开发工具:devServer 提供了一些开发工具,如控制台输出、错误提示、模块热替换等,帮助你在开发过程中更好地调试和监控项目的状态。

如何启动服务 webpack-dev-server

1、安装webpack-dev-server命令

js 复制代码
npm install -D webpack-dev-server
yarn add webpack-dev-server -D

2、package.json文件下scripts配置如下代码

js 复制代码
// package.json
{
  "name": "01",
  "version": "1.0.0",
  "description": "- 入口 - 出口 - 装载器loader - 插件plugin",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve",  // 执行命令 npm start 
    "dev": "webpack serve",// 命令npm run dev ,执行的命令其实是webpack serve
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "html-webpack-plugin": "^5.3.1",
    "webpack": "^5.24.4",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  }
}

3、使用命令(npm start or npm run dev)启动你的项目服务

js 复制代码
devServer: {
    // 配置webpack-dev-server 开发使用
    port: 8081, // 配置web服务器端口,端口不能相同
    open: true, // 启动成功之后自动打开浏览器
    progress: true, // 进度
    contentBase: "./dist", // 指定web服务的根目录,服务一打开就直接去dist文件夹下找index.html文件,有就直接打开
  },

devServer 中的配置项很多,下面介绍一下常用的,想知道完整的配置,前往官网查看

devServer

devServer.https (使用 HTTPS 提供服务)

默认情况下,开发服务器将通过 HTTP 提供服务,也可以选择使用 HTTPS 提供服务

js 复制代码
module.exports = {
  //...
  devServer: {
    https: true,
  },
};

devServer.port(指定监听请求的端口号)

js 复制代码
module.exports = {
  //...
  devServer: {
    port: 8080,
  },
};

port 配置项不能设置为 null 或者空字符串,要想自动使用一个可用端口请使用 port: 'auto'

js 复制代码
module.exports = {
  //...
  devServer: {
    port: 'auto',
  },
};

devServer.open (打开你的默认浏览器)

告诉 dev-server 在服务器已经启动后打开浏览器。设置其为 true 以打开你的默认浏览器。

js 复制代码
module.exports = {
  //...
  devServer: {
    open: true,
  },
};

在浏览器中打开指定页面

js 复制代码
module.exports = {
  //...
  devServer: {
    open: ['/my-page'],
  },
};

在浏览器中打开多个指定页面

js 复制代码
module.exports = {
  //...
  devServer: {
    open: ['/my-page', '/another-page'],
  },
};

devServer.proxy(设置代理服务器的配置)

代理服务器是一种中间服务器,它接收客户端的请求,并将请求转发到实际的目标服务器。在开发环境中,使用代理服务器可以解决跨域问题和模拟不同环境

js 复制代码
module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'https://other-server.example.com', 
        // 指定目标服务器的地址,即请求应该被转发到的实际服务器
        ws: false, 
        // 指定是否启用 WebSocket 支持
        changeOrigin: true 
        //是否启用 CORS(跨域资源共享)支持,如果设置为 `true`,则在转发请求时会添加 `Origin` 请求头,以解决跨域问题。
      },
    },
  },
};

也可以将配置文件写在.env文件中,便于管理、复用

js 复制代码
module.exports = {
  //...
  devServer: {
    proxy: {
      [process.env.VUE_APP_AIFORCE_PATH]: {
        target: process.env.VUE_APP_BASIC_DATA_SERVICE_API_URL, // 代理的目标地址
        changOrigin: true // 支持跨域
      },
      [process.env.VUE_APP_WS_TEXT_PATH]: {
        target: process.env.VUE_APP_BASIC_WS_SERVICE_API_URL, 
        ws: true, // 是否启用websockets
        changOrigin: true
      },
    },
  },
};

devServer.overlay(当出现编译器错误或警告时,在浏览器中显示)

js 复制代码
module.exports = {
  //...
  devServer: {
    // 当出现编译器错误或警告时,在浏览器中显示
    overlay: {
      warnings: true, // 显示警告
      errors: true // 显示错误
    },
  },
};

devServer.headers (为所有响应添加 headers)

js 复制代码
module.exports = {
  devServer: {
    // 对象写法
    headers: {
      'X-Custom': 'foo',
      'Y-Custom': 'bar'
    },
    
    // 数组写法
    headers: [
      {
        key: 'X-Custom',
        value: 'foo',
      },
      {
        key: 'Y-Custom',
        value: 'bar',
      },
    ],
    
    // 函数写法
    headers: () => {
      return { 'X-Bar': ['key1=value1', 'key2=value2'] };
    },
  },
};

devServer.client(指定开发服务器与浏览器之间的通信方式)

js 复制代码
module.exports = {
  //...
  devServer: {
    client: {
      logging: 'info', // 指定开发服务器的日志级别。可以是 `silent`、`error`、`warn`、`info` 或 `verbose`。默认为 `info`
      progress:true, // 是否显示进度条
      overlay: { // 显示错误信息
        errors: true,
        warnings: false,
      },
      publicPath: '/', //指定静态资源的公共路径
      socketPath: 'auto', // 指定使用 WebSocket 协议时的 socket 路径。默认为 `auto`,表示自动选择合适的路径。
      host:'localhost', // 指定开发服务器的主机名。默认为 `localhost`。
    },
  },
};

devServer.hot(是否开启热更新)

js 复制代码
module.exports = {
  //...
  devServer: {
    hot: true, // 开启热更新
  },
};

在项目中运用

js 复制代码
// vue.config.js
const path = require('path');
const webpack = require('webpack');
let HtmlWebpackPlugin = require("html-webpack-plugin");
const styleLoader = { loader: 'style-loader' };
function resolve(dir) {
  return path.join(__dirname, dir);
}
const isBuildProduction = process.env.NODE_ENV === 'production';

module.exports = {
    // 是否将包,进行映射
    productionSourceMap: false,
    // 资源在浏览器中的访问路径
    publicPath: '/', // 指定构建后的资源的根路径,默认为"/" 
    outputDir: 'dist', // 指定构建后的资源的输出目录,默认为"dist"
    mode: 'development', // 开发模式和生产环境,都有不同的内置优化
    configureWebpack: {
        publicPath: isBuildProduction ? "/" : "./",
        // 控制是否生成 映射文件
        devtool: isBuildProduction 
            ? 'nosources-source-map' 
            : 'eval-cheap-module-source-map',
        // 插件,对打包文件做处理
        plugins: [
          new HtmlWebpackPlugin(),
          new webpack.ContextReplacementPlugin( //内置插件
            /moment[\\/]locale$/,
            /^\.\/(zh-cn)$/
          )
        ],
        // 排除第三方依赖
        externals: /^(jquery|$)$/i,
        // 优化
        optimization: {
          splitChunks: { // 控制代码分割
            // 有效值为 `all`,`async` 和 `initial`
            chunks: 'all', // 对所有的块进行分割
            name: true, // 表示为每个块生成一个唯一的名称
            minSize: 1, // 表示最小分割块的大小为 1 字节
            minChunks: 1, // 表示如果一个块被多个模块引用,它将被分割
            cacheGroups: { // 定义了多个缓存组,用于根据不同的规则对代码进行分割
              default: false, // 禁用任何默认缓存组
              defaultVendors: { // 缓存组适用于 node_modules 目录下的所有模块
                name: 'common', // 缓存组的名称,用于在缓存中标识
                chunks: 'initial', // initial 表示应用程序的入口模块
                minChunks: 1, // 最小的 chunk 数量,只有在满足最小 chunk 数量时才会创建缓存
                enforce: true, // 是否强制使用缓存。如果为 `true`,则在满足条件时必须使用缓存,否则将抛出错误。
                test: /node_modules/, // 一个正则表达式,用于匹配要缓存的模块
                reuseExistingChunk: true // -   -   是否重用现有的 chunk。如果为 `true`,则如果已经存在匹配的缓存,则直接使用,而不是创建新的缓存。
              },
              vuePhotoPreviewVenodr: {
                test: /(vue-photo-preview)/, // 表示匹配 `vue-photo-preview` 模块
                priority: 103, // 缓存的优先级。优先级越高,越先被使用。
                name: 'vuePhotoPreviewVenodr', 
                chunks: 'async' // `async`表示适用于异步加载的 chunks
              },
              'async-commons': { // 这个缓存组适用于其他异步加载的包
                // 其余异步加载包
                chunks: 'async',
                minChunks: 2,
                name: 'async-commons',
                priority: 90
              },
              commons: { // 这个缓存组适用于其他同步加载的包
                // 其余同步加载包
                chunks: 'all',
                minChunks: 2,
                name: 'commons',
                priority: 80
              },
              styles: { // 这个缓存组适用于所有的样式文件
                name: 'common',
                chunks: 'initial',
                minChunks: 1,
                test: /\.(css|less|scss|stylus)$/,
                enforce: true,
                priority: 50
              }
            }
          }
        }
    },
    chainWebpack: (config) => {
        // 别名,使用@web,就是在使用'./src'地址
        config.resolve.alias.set('@web', path.resolve('./src')),
        // 删除 prefetch 插件
        config.plugins.delete('prefetch')
        // 清空名为 `app` 的入口点
        config.entry('app').clear();
        // 向名为 `app` 的入口点添加一个新的入口文件
        config.entry('app').add('./packages/index.js');
        // 使用 babel-loader 加载器,转换 ts 代码
        config.module.rule('ts').test(/\.ts$/).use('babel-loader').loader('babel-loader').end();
    },
    // 配置webpack-dev-server
    devServer: {
        port: 8083, //配置web服务端口
        open: true, //自动打开浏览器
        progress: true, //进度
        contentBase: './dist', //指定web服务器的根目录
        overlay: { // 当出现编译器错误或警告时,在浏览器中显示 
            warnings: true, // 显示警告
            errors: true // 显示错误
        },
        // 设置代理服务器的配置
        proxy: {
          [process.env.VUE_APP_AIFORCE_PATH]: {
            // 指定目标服务器的地址,即请求应该被转发到的实际服务器
            target: process.env.VUE_APP_BASIC_DATA_SERVICE_API_URL, 
            changOrigin: true // 是否支持跨域
          },
          [process.env.VUE_APP_WS_TEXT_PATH]: {
            target: process.env.VUE_APP_BASIC_WS_SERVICE_API_URL, // 测试服
            ws: true, // 是否启用websockets
            changOrigin: true
          },
       },
       // 请求头
       headers: {
        'X-Custom-Bar': 'bar',
        'X-Custom-Foo': 'foo',
        }
    },
    css: {
     loaderOptions: {
      sass: {
        // 覆盖原来的 loader user 配置
        // 全局引入 scss,便于引用函数和变量
        data: '@import "~@main/styles/variable.scss"; @import "~@main/styles/cloud-variable.scss";',
        // 生产环境不需要 styleLoader
        use: (isBuildProduction ? [] : [styleLoader]).concat([
          'css-loader',
          'postcss-loader', // `postcss-loader` 用于处理 PostCSS 转换
          {
            loader: 'sass-loader',
            options: {
              implementation: require('sass') // 用于指定要使用的 Sass 实现库
            }
          }
        ]),
        postcss: false // 默认添加的 postcss 位置不对, 应当按上面列出的顺序
      }
    },
    sourceMap: false // 控制是否生成 CSS 文件的源映射
  },
}

多环境配置

js 复制代码
const env = process.env.NODE_ENV;//当前环境
if (env === 'production') { 
    // 生产环境
    module.exports = {} // 可以在这里写入生产环境的配置,也可以写在其他文件,在这里引入
}else if (env === 'test') { 
    // 测试环境    
    console.log("----------测试环境----------"); 
} else { 
    // 开发环境    
    console.log("----------开发环境----------");
}

配置项多而乱,根据要实现的需求,使用对应的配置项,完成配置,实现效果。

相关推荐
崔庆才丨静觅1 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60612 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了2 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅2 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅3 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅3 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment3 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅3 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊3 小时前
jwt介绍
前端
爱敲代码的小鱼4 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax