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("----------开发环境----------");
}

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

相关推荐
m0_7482550226 分钟前
前端常用算法集合
前端·算法
真的很上进40 分钟前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203981 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2341 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1232 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~3 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语3 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport3 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg3 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全
胡西风_foxww3 小时前
【es6复习笔记】rest参数(7)
前端·笔记·es6·参数·rest