首页/文章/webpack

webpack构建流程、基础配置、打包性能优化、热更新、和Vite区别

2025-03-05
446715 分钟
...

一、webpack构建流程

四个阶段:

初始化阶段:读取配置文件、创建complier实例
编译阶段:解析入口点、模块加载(loader)
打包阶段:模块合并与优化、代码分割
输出阶段:生成输出文件

1.配置文件解析:

Webpack读取并解析webpack.config.js文件,获取构建所需的配置信息。

2.入口处理:

Webpack从入口文件开始,构建模块依赖图。

3.模块加载与转换:

使用加载器处理不同类型的模块,如CSS、图片等,将它们转换为JavaScript模块。

4.插件执行:

插件在特定的生命周期钩子上运行,执行诸如优化、资源管理等任务。

5.打包优化:

代码分割、Tree Shaking等优化手段被应用,以减少文件大小并提高性能。

6.生成输出文件:

打包后的文件根据配置输出到指定目录。

二、webpack基础配置

Webpack是一个强大的模块打包工具,它可以通过配置来实现代码压缩、代码分割、模块热替换等多种功能。以下是一些Webpack的常用配置项:

1. entry

  • 作用:指定Webpack的入口文件。

  • 示例

    entry: './src/index.js',

2. output

  • 作用:定义输出文件的配置,包括输出文件的名称、路径等。

  • 示例

    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },

3. mode

  • 作用:设置Webpack的运行模式,可以是development(开发模式)或production(生产模式)。

  • 示例

    mode: 'production',
  • development模式:提供开发时的必要功能,如source map、错误提示等。

4. module

  • 作用:配置模块的加载器和转换规则,用于处理不同类型的文件。

  • module.rules:配置各类文件的处理规则,test属性用户匹配文件路径,use属性指定使用的loader;

  • 示例

    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: 'babel-loader',
        },
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader'],
        },
      ],
    },

5. resolve

  • 作用:配置模块解析规则,可以设置别名、扩展名等,方便引入模块。

  • 示例

    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
      extensions: ['.js', '.json'],
    },

6. plugins

  • 作用:使用插件来增强Webpack功能,例如压缩代码、拷贝文件等。

  • 示例

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.html',
      }),
      new MiniCssExtractPlugin({
        filename: '[name].css',
      }),
    ],

7.devServer

Webpack DevServer 是一个开发工具,它可以提供一个简单的 web 服务器,并且能够实时重新加载
contentBase:告诉服务器从哪里提供内容,默认情况下,服务器会使用当前执行目录。
compress:告诉服务器启用 gzip 压缩。
port:指定要监听请求的端口号。
open:告诉服务器自动打开浏览器。
hot:启用模块热替换(Hot Module Replacement)。

8. optimization:代码分割、压缩

  • 作用:控制构建过程中的优化行为,如代码分割、压缩等。

  • 示例

    optimization: {
      splitChunks: {
        chunks: 'all',
      },
      minimize: true,
    },

    在 Webpack 中,optimization 配置用于控制构建过程中的优化行为。它可以帮助你实现代码分割、代码压缩、树摇(tree shaking)等功能,从而减小输出文件的大小和提高应用程序的性能。

    以下是一些常用的 optimization 配置选项:

    1. splitChunks
      splitChunks 用于将公共代码(如第三方库、公共组件等)提取到单独的文件中,以实现代码分割和缓存复用。
    optimization: {
      splitChunks: {
        chunks: 'all', 
        minSize: 20000, 
        maxSize: 0, 
        minChunks: 1, 
        maxAsyncRequests: 30, 
        maxInitialRequests: 30, 
        automaticNameDelimiter: '~', 
        name: true, 
        cacheGroups: {
          
          vendors: {
            test: /[\\/]node_modules[\\/]/, 
            priority: -10, 
            filename: 'vendors.[contenthash].js', 
          },
          default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true, 
            filename: 'common.[contenthash].js', 
          },
        },
      },
    },
    1. runtimeChunk
      runtimeChunk 用于将 Webpack 的运行时代码提取到一个单独的文件中,以实现运行时代码的复用。
    optimization: {
      runtimeChunk: 'single', 
    },
    1. minimize
      minimize 用于控制是否压缩输出文件。当设置为 true 时,Webpack 会使用默认的压缩插件(如 TerserPlugin)来压缩 JavaScript 代码。
    optimization: {
      minimize: true, 
    },
    1. minimizer
      minimizer 用于自定义压缩插件。你可以在这里添加自定义的压缩插件,如 TerserPlugin(用于压缩 JavaScript 代码)、CssMinimizerPlugin(用于压缩 CSS 代码)等。
    const TerserPlugin = require('terser-webpack-plugin');
    const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
    
    optimization: {
      minimize: true,
      minimizer: [
        new TerserPlugin({
          
        }),
        new CssMinimizerPlugin({
          
        }),
      ],
    },
    1. moduleIdschunkIds
      moduleIdschunkIds 用于控制模块和 chunk 的 ID 生成方式。这可以帮助你优化输出文件的大小和提高构建速度。
    optimization: {
      moduleIds: 'hashed', 
      chunkIds: 'named', 
    },

    通过合理地配置 optimization 选项,你可以优化 Webpack 的构建过程,提高应用程序的性能。

通过合理地配置这些选项,你可以优化Webpack的构建过程,提高应用程序的性能和可维护性。

三、loader和plugin

loader

loader:用于转换模块的工具。主要用于文件内容的转换。

  • babel-loader处理js文件,将es6+代码转换为es5,通常与@babel/preset-env一起使用;

  • css-loadersaas-loader处理css和sass文件,miniCssExtractPlugin.loader将css提取为单独文件;

  • style-loader将css插入到dom的<style>标签中去;

  • file-loader处理文件(如图片、字体),并返回文件的url;

  • url-loader处理图片文件,8kb以下的图片转为base64,大于8kb的图片则拷贝到输出目录;

  • 自定义loader:实质上是一个函数,接受源文件内容作为输入,并输出处理后的内容。可以通过this.callbak返回结果;

    module.exports = function(source){	
        const result = source.replace(/my/g,'我的');
        return rusult;
    }

plugin

插件系统的实现:Plugin 是一个具有 apply 方法的对象,当 Webpack 启动构建时,会调用所有 Plugin 的 apply 方法,并将 compiler 对象作为参数传入。在 apply 方法中,Plugin 可以监听事件钩子,并执行自定义的操作。

plugin:用于扩展webpack功能的工具,可以在webpack构建过程中执行更复杂的任务,如打包优化、资源管理、环境变量注入等。Plugin主要用于处理构建过程中的各种任务。

  • CleanWebpackPlugin在每次打包前清理输出目录,防止旧文件残留;

  • HtmlWebpackPlugin根据模板生成Html文件,并自动注入打包后的js文件等;

  • MiniCssExtractPlugin将Css提取到单独的文件中;

  • DefinePlugin创建全局变量,在编译时进行替换;

  • TerserPlugin用于压缩js代码,主要在生产环境中使用;

  • 自定义Plugin:plugin是一个类,包含apply方法,apply接受一个complier对象,通过这个对象可以钩入webpack的各个构建阶段;

    class MyPlugin{		
        apply(compiler){
            compiler.hooks.done.tap('MyPlugin',(stats)=>{
                console.log('编译完成!')
            })
        }
    }

loader 和 plugin 的区别

  • loader 是文件加载器,操作的是文件,将文件A通过loader转换成文件B,是一个单纯的文件转化过程;能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
  • plugin即为插件,是一个扩展器,丰富webpack本身,增强功能 ,针对的是在loader结束之后,webpack打包的整个过程,他并不直接操作文件,而是基于事件机制工作,监听webpack打包过程中的某些节点,执行广泛的任务。 插件赋予了 webpack 各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 loader 无法实现的其他事
  • loader 运行在打包文件之前
  • plugins 在整个编译周期都起作用

四、打包性能优化

1、按需引入组件

例如引入 element-ui ,用到哪些组件就引哪些

import {Button,Dialog} from 'element-ui';
Vue.use(Button); 
Vue.use(Dialog);

2、externals 属性

webpack的externals属性,将公共的或不常改动的第三方包名称,配置在属性中,打包时会自动忽略当中的包。具体实现如下:

在 build/webpack.base.conf.js文件中:

module.exports = {
    externals: {
        Vue: 'Vue',
        Axios: 'axios'
    }
}

需要在根目录,index.html 中引入一下

<script src="https://unpkg.com/vue@2.6.11/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios@0.19.2/dist/axios.min.js"></script>

3、给定文件匹配范围

include 规定需要处理的文件有哪些

enclude 排除不需要处理的文件夹

{	test: /\.js$/,
    loader: 'babel-loader',
    include: [resolve('src')],
    exclude: /node_modules/
}

4、noParse 属性:过滤掉不需要解析的文件

{	module: {
        noParse: /jquery/,
        rule: [
            ...
        ]
    }
}

5、cacheDirectory 缓存属性

babel-loader提供了cacheDirectory选项参数,默认为false。

设置空或true时,会利用系统的临时文件夹缓存经过 babel 处理好的模块,对于 rebuild js 有着非常大的性能提升。

{	test: /\.js$/,
    loader: 'babel-loader?cacheDirectory',
    include: [resolve('src')],
    exclude: /node_modules/
}

6、happyPack 多个子进程并行

webpack 在打包过程中,loader 转化js、css、img等文件是同步进行的,一个一个的转换。

happyPack 的原理是,将这些任务分解到多个子进程中,并行执行,执行完成后把结果发送到主进程,从而减少整体的打包时间。

7、压缩文件

  1. 压缩JS文件
  • Webpack 4.x以上版本内置了uglifyjs-webpack-plugin 插件,会对JS文件自动压缩,不需要做其它的任何操作。也可以手动安装这个插件,设置一些另外的参数,比如开启并行压缩,加快打包的速度。
  • 使用 TerserWebpackPlugin 来压缩 JavaScript 代码。
  1. 压缩CSS文件和图片
    css-minimizer-webpack-plugin minicssExtraPlugin用于压缩 CSS 文件
    ImageMinimizerWebpaxkPlugin进行压缩图片压缩

  2. 压缩HTML文件
    HtmlWebpackPlugin 插件除了可以帮助我们简化 HTML 文件的创建,也可以压缩 HTML 文件。

    首先,需要先安装 HtmlWebpackPlugin 插件:npm install --save-dev html-webpack-plugin

    const HtmlWebpackPlugin = require("html-webpack-plugin");
    module.exports = {
     plugins: [new HtmlWebpackPlugin()],
    };

    如果不添加任何配置的话,会生成一个默认 index.html 文件,并自动注入所有的 chunk 和压缩。

    也可以通过自定义配置参数,以下几个是常见的参数:

    template:模板的路径,默认会去寻找 src/index.ejs 是否存在。
    filename:输出文件的名称,默认为 index.html。
    inject:是否将资源注入到模版中,默认为 true。
    minify压缩参数。在生产模式下(production),默认为 true;否则,默认为false。
    如果 minify 为 true,生成的 HTML 将使用 html-minifier-terser 和以下选项进行压缩:

    {
      collapseWhitespace: true,
      keepClosingSlash: true,
      removeComments: true,
      removeRedundantAttributes: true,
      removeScriptTypeAttributes: true,
      removeStyleLinkTypeAttributes: true,
      useShortDoctype: true
    }

五、Webpack和Vite区别

1、Webpack:是一个强大的静态模块打包工具,它可以将各种类型的文件,如JavaScript、CSS、图片等,作为模块进行打包,并生成最终的静态资源文件。Webpack使用各种loader和plugin来处理不同类型的文件,还可以进行代码分割、懒加载、压缩等优化操作。

2、Vite:是一个基于ES模块的快速开发工具,它利用浏览器原生的ES模块机制,将每个模块作为一个独立的请求来加载,而不是像Webpack那样把所有模块打包成一个文件。这样可以在开发过程中实现快速的热模块替换,减少构建时间,提高开发效率

Vite的设计初衷是为了解决传统打包工具的一些问题,传统的打包工具在开发过程中会将所有的模块打包成一个或多个最终的捆绑文件,然后在浏览器环境中执行。这种方式在大型项目中可能会导致开发服务器启动慢,因为需要将所有的模块进行打包。Vite通过利用ES模块的特性,在开发过程中仅对需要的模块进行编译和构建,从而提升了开发服务器的启动速度。Vite还支持热模块替换。

总结

Webpack是一个成熟和功能强大的前端构建工具,提供了丰富的功能和配置选项。而Vite是一个新兴的前端构建工具,通过利用ES模块和HMR等特性,提供了更快的开发体验。两者都在前端项目中发挥着重要的作用,开发者可以根据项目需求选择适合的工具。Vite在开发阶段更加轻量级和高效,因为它不需要进行复杂的打包过程,只需简单地使用浏览器原生支持的ES模块加载机制。但是在生产环境下,还是需要使用类似Webpack这样的构建工具来进行打包和优化

六、热更新

Webpack 配置中的 hot: truewebpack-dev-server 的一个选项,用于启用热更新(Hot Module Replacement,简称 HMR)。当设置为 true 时,webpack-dev-server 将尝试使用 HMR 更新应用程序,而不是刷新整个页面。

仅仅设置 hot: true 是不够的。为了使 HMR 正常工作,您还需要执行以下操作:

  1. 安装 webpack-dev-server:确保已经通过 npm 或 yarn 安装了 webpack-dev-server

    npm install webpack-dev-server --save-dev
  2. 配置 webpack.config.js:在 webpack.config.js 文件中,确保已经正确配置了 devServer 选项,并将 hot 设置为 true

    module.exports = {
      
      devServer: {
        hot: true,
        
      },
      
    };
  3. 添加 HotModuleReplacementPlugin 插件:在 webpack.config.js 文件的 plugins 数组中,添加 new webpack.HotModuleReplacementPlugin()

    const webpack = require('webpack');
    
    module.exports = {
      
      plugins: [
        new webpack.HotModuleReplacementPlugin(),
        
      ],
      
    };
  4. 处理模块更新:在项目的入口文件(如 index.js)中,添加以下代码以处理模块更新。(需要热更新的文件)

    if (module.hot) {
      module.hot.accept();
    }

只有完成以上步骤,HMR 才能在项目中正常工作。

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
webpack2025-03-04
深入解析 Webpack 的构建流程
1\. 初始化阶段:准备启动引擎 当你启动 时,它就像一个超级工厂的启动按钮,开始准备好一切——加载配置文件、初始化插件,并准备好开始生产。 实例:准备你的工厂配置 解释: 入口文件(Entry) :Webpack 从这里开始它的构建任务,像一个工厂的生产线入口。 输出路径(Output) :Webpack 会把构建好的产品放在这里。 就是每个产品的唯一标识,确保浏览器不会缓存过时的文件。 模块加载(Loaders) :当 Webpac...
学习面试
webpack2024-04-07
Webpack 和 Rollup:您应该知道的一些事情
本文只做 Webpack 和 Rollup 的对比总结,不参入 esbuild、Vite 或其他工具的讨论 Webpack 和 Rollup 都是现在前端领域比较流行的打包工具,它们的相似之处在于可以帮助我们 把多个 JavaScript 文件打包成一个可以在浏览器中加载并在生产中使用的文件。 &nbsp; &nbsp; 打包成单个文件的好处是可以减少网络请求、提高网站性能等目的。 这篇文章主要想通过对比的方式讲讲这两种打包工具的差异...
学习面试
nuxt2025-10-22
Nuxt SSR 与 Next.js SSR
🧭 引言 在现代前端生态中, Nuxt(Vue) 与 Next.js(React) 是最成熟的两大全栈框架。 它们都具备 SSR(Server Side Rendering) 能力,但实现原理与运行机制差异巨大。 如果你在使用 Nuxt 构建 SSR 项目,却发现“路由跳转后不再 SSR”, 而在 Next.js 中同样操作却会重新发起服务端渲染——这不是 bug,而是 理念差异 。 本文将详细对比这两种框架的 SSR 行为,帮助你彻...
学习面试
vue2025-10-22
shallowRef 与 ref 的区别、场景与坑位
结论先行: 会 深度 地把你放进去的对象转成响应式(递归代理),因此"对象内部的改动"也会触发视图更新。 只在 顶层 做依赖追踪: 更换 才触发更新 ;若你只是"在原对象上改属性",不会触发,除非手动 。 1\. 快速对比 维度 追踪粒度 深度(递归) 仅顶层 对象内部属性变更 会触发更新 不会 触发(除非 或重新赋值) 性能 有递归 & 依赖跟踪开销 更轻量,适合大对象/第三方实例 适用对象 普通标量、普通对象、数组 第三方实例(图表...
学习面试
vue2025-10-20
Vue 3 中的 setup执行时机与异步逻辑详解
Vue 3 中的 执行时机与异步逻辑详解 本文详细介绍 Vue 3 组合式 API 的核心函数 :它在组件生命周期中的执行时机、异步行为( 的影响)、常见用法和最佳实践。 一、 的执行时机 是 Vue 3 组件实例创建后、渲染前执行的函数。 它相当于 Vue 2 中的 和 的合体。 执行流程: 也就是说: 所有响应式数据( 、 、 )都在这里定义; 所有生命周期钩子( 、 等)都在这里注册; 模板渲染会等待 执行完成(或异步返回的 Pr...
学习面试
八股文2025-10-13
cookie跨域介绍
Cookie 跨域问题详解 在 Web 开发中, Cookie 是最常见的客户端存储机制之一,用于记录用户登录状态、偏好设置、会话信息等。然而,当涉及到 跨域请求 时,Cookie 的行为往往变得复杂,尤其在现代浏览器的安全策略下,跨域 Cookie 的传递和写入都有严格的限制。 本文将从基础概念开始,逐步讲解 Cookie 的跨域机制、SameSite 属性、CORS 配置及常见问题解决方案。 一、Cookie 的基础概念 Cooki...
学习面试

评论

请登录后发表评论

去登录
加载评论中...

目录