【Vue】笔记六:webpack底层深入讲解,从初识到精通,真正实现从0到1的过程

前言:

Webpack 是一个非常强大的打包工具,广泛用于前端项目的构建。Webpack 的功能十分强大,但也十分复杂,光是配置就有一堆参数。本篇文章将从基础部分到深入层次逐步讲解 webpack 的应用,帮助您了解 webpack 配置文件和各个组成部分的作用,以及如何优化 webpack 性能。

1. 初识Webpack

Webpack 是一个模块化打包工具,具有将多个模块打包成可用的函数或库的功能,可以将项目中的所有文件或模块打包成一个或多个文件。Webpack 可以将多种资源打包成一个或多个资源。Webpack 在开发过程中提供了很多便捷的功能和插件,可以帮助我们进行配置和优化,使我们的项目开发变得更容易。

(1)Webpack是什么?

Webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)。在Webpack看来,前端开发中所有的资源——HTML、CSS、JavaScript、图片等都是模块。

(2)Webpack的核心概念

Webpack的核心概念包括模块(module)、入口(entry)、出口(output)、插件(plugins)、loader等。

  • 模块(module): Webpack将所有资源都作为模块来处理,每个模块都有自己的依赖。
  • 入口(entry): Webpack会从入口模块开始,分析整个应用程序的依赖关系图。
  • 出口(output): Webpack会根据入口模块和整个依赖关系图,把应用程序打包成一个或多个文件,输出到磁盘上。
  • 插件(plugins): Webpack的插件机制使其具有可扩展性,并且可以应用于各种场景。
  • **loader:**是指用来降一段代码转换成另一端代码的 webpack加载器 , 通过loader,Webpack可以处理各种类型的文件,例如CSS、图片等。

(3)Webpack的基本用法

我们可以使用Webpack CLI来安装和配置Webpack。例如,我们可以通过Webpack CLI创建一个新项目,安装Webpack和相关的依赖,以及编写一个简单的Webpack配置文件。

在新建项目之后,我们可以在项目中创建一个名为webpack.config.js的文件,用于配置Webpack。

下面是一个示例的Webpack配置文件:

const path = require('path');

module.exports = {
  entry: './src/index.js', // 入口文件
  output: { // 打包至文件设置
    filename: 'bundle.js', // 输出文件名
    path: path.resolve(__dirname, 'dist') // 输出文件路径
  },
  module: { // loader规则规定
    rules: [
      {
        test: /\.css$/, // test规则满足文件匹配
        use: [
          'style-loader',
          'css-loader'
        ]
      }
    ]
  }
};

在上面的配置文件中,我们指定了一个入口文件(src/index.js),以及一个输出文件名(bundle.js),同时使用了一个CSS loader,来处理CSS文件。

2. Webpack的核心原理

在了解了Webpack的基础概念和基本用法之后,我们需要深入了解Webpack的核心原理。

(1)Webpack的打包流程

Webpack的打包流程主要分为三个阶段:初始化阶段、编译阶段和输出阶段。

  • 初始化阶段: Webpack首先读取和解析Webpack配置文件,以及处理命令行参数传递的参数(--watch,--config 等等)。
  • 编译阶段: 当初始化阶段处理完毕,Webpack首先会创建一个Compilation对象,它代表着一次新的编译过程。然后通过入口(entry)来读取应用程序依赖的所有模块,并将其构建成依赖关系图。在这个过程中,Webpack会通过loader将不同类型的文件(例如CSS,图片等)转换成模块,并生成对应的依赖关系。
    接下来,Webpack会对所有的模块进行解析、转换和优化等处理,最终生成一个或多个输出文件。在生成输出文件的过程中,Webpack会将所有的模块打包成若干个chunk,每个chunk对应着一个输出文件。在chunk的生成过程中,Webpack会将相同类型的模块打包在一起,从而尽可能地减小输出文件的大小
  • 输出阶段: Webpack会将生成的chunk输出到磁盘上,完成应用程序的打包过程。

在整个打包流程中,Webpack会不断地触发各种生命周期钩子函数,例如compilercompilation的事件,以及插件中定义的钩子函数。

(2)Webpack的模块原理

Webpack中,每个模块都被看作一个JavaScript对象,并且会对模块进行一些特殊处理,例如将每个模块包裹在一个函数中,这个函数可以保护模块内部的变量不受外界影响,同时也可以提高模块的可维护性和可重用性。

除此之外,Webpack还会对模块进行一些其他处理,例如模块解析、模块缓存等,以提高模块的加载效率。

(3)Webpack的loader原理

在Webpack中,loader可以帮助我们处理各种类型的文件,例如CSS、图片等,从而让我们可以在JavaScript文件中引入这些资源文件

loader的实现原理非常简单,就是一个JavaScript函数,这个函数用于对指定的文件进行转换和处理。在Webpack编译过程中,当Webpack遇到一个需要处理的文件时,会调用对应的loader函数对文件进行处理,最后将处理后的结果返回给Webpack,从而继续进行后续的编译流程。

(4)Webpack的插件原理

在Webpack中,插件机制是非常重要的一个部分,它可以使Webpack具有更高的可扩展性,并且可以应用于各种场景。

插件的实现原理也非常简单,就是一个JavaScript对象,它包含了一个或多个钩子函数。在Webpack编译过程中,当Webpack触发指定的钩子函数时,插件就会被调用,从而可以对编译过程进行一些定制化的处理。

3. 安装Webpack

安装Webpack 有两种方式:

3.1 全局安装

在你的终端输入以下命令可以全局安装Webpack:

npm install webpack -g

3.2 局部安装

在项目中,使用以下命令安装Webpack:

npm install webpack --save-dev

安装完成后,在命令行中输入 webpack -v 检查是否成功安装。

4. 基本配置

Webpack 的基本配置包括输入和输出,即指定从哪里获取源文件并输出到哪里。在 Webpack 中,输入和输出通常由两个重要的属性组成:entryoutputentry 用于指定入口文件,即告诉 Webpack 从哪里获取源文件,而 output 则指定了 Webpack 将生成输出文件的位置和名称。

在 package.json 中添加以下代码:

{
    "name": "My App",
    "version": "1.0.0",
    "scripts": {
        "build": "webpack"
    },
    "devDependencies": {
        "webpack": "^3.6.0"
    }
}

执行 npm run build 命令构建项目,Webpack 会查找入口文件,并将所有资源打包输出到输出文件夹中

5. Loaders 和 Plugins 的配置

LoadersPlugins 是 Webpack 中两个重要的概念,也是实现 Webpack 高级功能的核心。在 Webpack 中,通过 Loaders 可以让 Webpack 处理并加载非 JavaScript 模块,而通过 Plugins 可以扩展、优化和修改 Webpack 的功能。

5.1 Loaders

在 Webpack 中,Loaders 可以让 Webpack 处理和加载各种类型的文件,包括 CSS、JS、字体、图片等。例如,通过使用 CSS-loader,Webpack 可以将 CSS 文件转换为 JavaScript 模块,在 JavaScript 中引用 CSS 文件。

在 Webpack 配置文件中,加载程序可以通过 module.rules 属性进行定义。例如,以下代码演示如何在 Webpack 中使用 CSS-loader。

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
  }
};

这使得 Webpack 可以识别所有 CSS 文件,并在开发模式下使用 style-loadercss-loader 加载 CSS 文件。

5.2 Plugins

Plugins 可以扩展 Webpack 的功能、优化某些操作和修改 Webpack 输出的文件,是 Webpack 的核心组件之一。Plugin 主要有 apply(), compilation(), and after-compile() 三种方法:

  • apply() 方法是必须的,用于 Webpack 启动时传入给插件的参数。
  • compilation() 方法被触发时,Webapck 正在编译资源,
  • after-compile() 方法被触发时,Webpack 正在执行用于生成最终资源的插件。

以下是如何在 webpack 配置文件中添加插件的示例:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports = {
  // ...其他配置项
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new webpack.ProgressPlugin(),
    new CleanWebpackPlugin(),
  ]
};

在上面的示例中,我们使用了 HtmlWebpackPluginclean-webpack-pluginwebpack.ProgressPlugin 三个插件。解释一下这三个插件的作用:

  • HtmlWebpackPlugin:用于将 HTML 文件作为模板,可以自动为你生成一个HTML 文件,并将所有的打包后的模块自动注入到HTML文件中。配置中的 template 属性用于指定 HTML 源模板。
  • clean-webpack-plugin:为了在每次打包发布时自动清理掉dist目录中的旧文件,可以安装配置这个插件,能帮助我们自动清理dist目录下的旧文件。配置完成后,下次再重新编译打包时,会自动删除dist中的旧文件,再重新生成。
  • webpack.ProgressPlugin(): 用于在控制台中打印编译进度条。

6. 高级配置

6.1 高级配置的必要性

对于大型项目和 Webpack 的高级功能,我们需要进行更深入的配置。在实际工作中,我们可能需要对源代码进行处理,将多个模块分离成多个文件,以便充分利用浏览器缓存和加载资源时的并行性。我们还需要对 Webpack 进行优化,以便编译速度更快、构建文件更小,以及更好地利用浏览器的缓存。

6.2 多页面应用配置

多页面应用程序表示一个应用程序包含多个 HTML 页面,每个 HTML 页面具有不同的入口点。在这种情况下,我们需要为每个模块和页面生成单独的打包文件。

以下是一个多页面应用的示例:

module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js',
    contact: './src/contact.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Home Page',
      template: './src/home.html',
      filename: 'home.html',
      chunks: ['home']
    }),
    new HtmlWebpackPlugin({
      title: 'About Page',
      template: './src/about.html',
      filename: 'about.html',
      chunks: ['about']
    }),
    new HtmlWebpackPlugin({
      title: 'Contact Page',
      template: './src/contact.html',
      filename: 'contact.html',
      chunks: ['contact']
    })
  ]
};

在上面的示例中,我们为每个页面分别定义了一个入口文件,并且使用 HtmlWebpackPlugin 插件为每个页面生成单独的 HTML 文件。

注意:在设置 HtmlWebpackPlugin 插件时,我们使用了一个 chunks 属性,用于在 HTML 文件中引入与该页面相关的模块。

6.3 优化构建速度

Webpack 可以通过一些优化来加快构建速度,例如修改 resolve.modules 属性,只编译必要的代码块,使用 HappyPack 等等。以下是一些简单的例子:

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: __dirname + '/dist'
  },
  resolve: {
    modules: [path.resolve(__dirname, 'node_modules')]
  },
  optimization: {
    splitChunks: {
      minSize: 0,
      cacheGroups: {
        commons: {
          name: 'commons',
          chunks: 'initial',
          minChunks: 2
        },
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  },
  plugins: [
    new HappyPack({
      id: 'js',
      threads: 4,
      loaders: ['babel-loader']
    })
  ]
};

在上面的示例中,我们使用了以下优化:

  • 修改 resolve.modules 属性,以便告诉 Webpack 在哪里查找模块依赖。
  • 使用 optimization.splitChunks 属性,仅编译必要的代码块,并同时将共享块提取为单独的文件。
  • 使用 HappyPack 插件,将 JS 文件编译成多个线程进行加速。

6.4 优化构建输出文件

在 Webpack 构建输出文件时,我们可以使用一些插件进行优化,例如 MiniCssExtractPlugin,可以将 CSS 代码分离成单独的文件,以便浏览器并行加载,从而提高页面加载速度。

以下是如何在 Webpack 配置文件中使用 MiniCssExtractPlugin 插件的示例:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  output: {
    filename: '[name].[contenthash].js',
    path: __dirname + '/dist'
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css'
    })
  ]
};

在上面的示例中,我们使用了 MiniCssExtractPlugin 插件,将 CSS 代码分离成单独的文件,以便浏览器并行加载。

7. Webpack的优化策略

在深入了解Webpack原理的基础上,我们需要掌握如何实现Webpack的优化。

Webpack的优化策略有很多,这里我们只介绍几个比较重要的优化策略:

(1)模块分离

在模块分离优化策略中,Webpack会将公共模块提取出来,打包成单独的文件,从而避免重复打包,减小输出文件的体积。

(2)Tree Shaking

Tree Shaking是一种常用的代码优化技术,它实现的原理是在编译过程中,找出未被使用的代码,将其从编译结果中去除,从而减小输出文件的体积。

(3)Scope Hoisting

Scope Hoisting是一种代码优化技术,它可以将模块之间的依赖关系图转化为一个简单的函数调用关系,从而减少模块加载时间和体积。

(4)缓存优化

Webpack还提供了缓存优化功能,可以缓存已经处理过的模块,避免重复处理和打包已经处理过的文件,从而提高编译速度。

(5)异步模块加载

在大型应用程序中,存在很多不必要的模块,这些模块可能只在某些特定的场景下才会被使用。异步模块加载可以帮助应用程序在需要这些模块时才去加载,从而提高应用程序的启动速度。

8. 总结

经过上面的讲解,我们应该对 Webpack 有了更深入的了解。Webpack 提供了很多便捷的功能和插件,可以帮助我们进行配置和优化,使我们的项目开发变得更容易。当然,在实际工作中,我们还可以根据项目需求和实际情况,灵活地配置和优化 Webpack,达到更好的性能和更高的开发效率。希望本篇文章能够对您加深对 Webpack 的理解,也为您的工作提供一些帮助。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值