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

一、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, // 生成 chunk 的最小体积(以字节为单位)
        maxSize: 0, // 生成 chunk 的最大体积(以字节为单位),0 表示不限制
        minChunks: 1, // 模块被引用的最小次数
        maxAsyncRequests: 30, // 按需加载时的最大并行请求数
        maxInitialRequests: 30, // 入口点的最大并行请求数
        automaticNameDelimiter: '~', // 文件名的连接符
        name: true, // 是否根据模块和缓存组的名称自动生成文件名
        cacheGroups: {
          // 定义缓存组,用于控制代码分割的规则
          vendors: {
            test: /[\\/]node_modules[\\/]/, // 匹配 node_modules 中的模块
            priority: -10, // 优先级,值越大优先级越高
            filename: 'vendors.[contenthash].js', // 输出文件名
          },
          default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则将复用它,而不是生成新的模块
            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({
          // TerserPlugin 的配置选项
        }),
        new CssMinimizerPlugin({
          // CssMinimizerPlugin 的配置选项
        }),
      ],
    },
    
    1. moduleIdschunkIds
      moduleIdschunkIds 用于控制模块和 chunk 的 ID 生成方式。这可以帮助你优化输出文件的大小和提高构建速度。
    optimization: {
      moduleIds: 'hashed', // 使用模块内容的哈希值作为模块 ID
      chunkIds: 'named', // 使用模块名称作为 chunk ID
    },
    

    通过合理地配置 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){	//自定义loader:将文件内容中的‘my’替换为‘我的’
        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'
	}
}
// 其中的 key--对应 import Axios名称,value--对应原始方法名称

需要在根目录,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

    // webpack.config.js
    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 才能在项目中正常工作。

### Webpack Vite 的主要区别 #### 实现方式 Webpack 是基于模块打包的概念设计而成,通过配置文件定义入口起点并解析依赖图谱来处理各种资源。而 Vite 则利用现代浏览器原生 ES 模块的支持,在开发阶段采用按需编译的方式即时转换源码中的 import 语句,从而提供更快的冷启动速度热更新效率[^1]。 #### 开发体验 由于采用了不同的工作原理,两者给开发者带来的实际感受也有所不同。Vite 凭借其快速刷新特性以及几乎零等待时间的首次加载表现,显著提升了开发过程中的响应性流畅度;相比之下,尽管 Webpack 提供了丰富的功能选项,但在大型项目中可能会遇到较长的构建时间较慢的增量编译性能下降问题。 #### 插件生态系统 Webpack 拥有庞大的社区支持完善成熟的插件体系,能够满足几乎所有类型的前端工程需求。无论是针对特定语言特性的预处理器还是优化生产环境下的输出质量都有相应的解决方案可供选择。然而,虽然 Vite 正在快速发展壮大自己的生态圈,并且已经具备了一定规模的基础库覆盖范围,但就整体而言仍然无法与 Webpack 广泛兼容性强的特点相媲美[^2][^4]。 #### 文件类型支持程度 作为一款全面型工具,Webpack 可以轻松集成多种静态资产类型(如 CSS、图片、字体等),并通过自定义 loader 来扩展更多可能性。相反,Vite 更专注于现代化 JavaScript 应用程序架构下核心逻辑部分的高效执行,对于非 JS 资产则推荐借助第三方工具链完成相应任务[^3]。 #### 生产环境下表现 当涉及到最终部署环节时,两个框架都提供了可靠的代码压缩混淆机制以减小体积提高运行效能。不过值得注意的是,当前版本 Vite 默认选用 Rollup 处理正式版发布流程,这主要是考虑到 esbuild 在某些方面尚存局限性——比如对样式表管理动态导入策略上的欠缺[^4]。 综上所述,如果追求极致的速度优势并且愿意接受相对年轻的技术栈,则可以选择尝试使用 Vite 构建下一代应用;而对于那些更看重稳定可靠性完备的功能集的传统企业级项目来说,Webpack 显然是更为稳妥的选择。 ```javascript // 示例:简单的 Webpack 配置片段 module.exports = { entry: './src/index.js', output: { filename: 'bundle.[contenthash].js' }, }; ``` ```bash # 使用 Vite 启动本地服务器命令 npm run dev --host ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值