字节青训前端笔记 | Webpack入门

news2024/11/14 17:37:06

本节课将重点围绕「 Webpack 」这一核心话题展开。简述前端工程化的常用工具webpack 的原理和使用

webpack的作用

webpack的作用是把很多文件打包整合到一起, 缩小项目体积, 提高加载速度,常用的场景是:

  • 代码压缩

将JS、CSS代码混淆压缩,让代码体积更小,加载更快

  • 编译语法

编写CSS时使用Less、Sass,编写 JS 时使用ES6、TypeScript等,这些标准目前都无法被浏览器兼容,因此需要构建工具编译,例如使用Babel编译ES6语法。

  • 处理模块化:

CSS 和 JS 的模块化语法,目前都无法被浏览器兼容。因此开发环境可以使用既定的模块化语法,但是需要构建工具将模块化语法编译为浏览器可识别形式。

开始使用 webpack

首先需要使用 node 安装 webpack

npm install webpack
npm install webpack-cli

我们可以通过 webpack 命令将一个文件进行打包,webpack 会根据模块的依赖关系进行静态分析,相互依赖的各个模块都会被包含到 bundle.js 文件中。Webpack 会给每个模块分配一个唯一的 id 并通过这个 id 索引和访问模块。

npx webpack a.js bundle.js

之后创建一个 webpack 的配置文件 webpack.config.js ,在其中我们可以进行打包的配置,webpack 命令执行后,会默认载入当前目录的 webpack.config.js 文件。以下是常用的配置说明:

// webpack 中引入其他的模块要使用commonJS模块化require导入,因为webpack是nodeJS 开发的,不能使用 import导入
var webpack = require('webpack');
const { resolve } = require('path');
module.exports = {
    //entry可以是个字符串或数组或者是对象。当entry是个字符串的时候,用来定义入口文件
    entry: './js/app.js',
    //output参数是个对象,用于定义构建后的文件的输出。其中包含path和filename
    output: {
        path: './build',
        filename: 'bundle.js'
    },
    //基础目录,绝对路径,用于从配置中解析入口点(entry point)和 加载器(loader)。默认使用当前目录,但是推荐在配置中传入一个值
    context:resolve(__dirname, './'),
    //关于模块的加载相关,我们就定义在module.loaders中。这里通过正则表达式去匹配不同后缀的文件名,然后给它们定义不同的加载器
  	module: {
       {
        // 正则: 匹配所有以css结尾的文件
        test: /\.css$/,
        // 使用的加载器,加载器处理顺序:从右往左
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../',
            },
          }, 
          'css-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../',
            },
          }, 
          'css-loader', 
          'less-loader'
        ]
      },
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            //配置项目
            options: {
              limit: 8 * 1024,
              // 配置输出的文件名
              name: '[name].[ext]',
              // 配置静态资源的引用路径
              publicPath: "../images/",
              // 配置输出的文件目录
              outputPath: "images/"
            }
          }
        ]
      },
      // (4) 配置对于高版本js的兼容性处理
      {
        test: /\.js$/,
        // 配置排除项
        exclude: /(node_modules)/,
        use: [
        {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      ]
 	},
    //Webpack社区提供了一个便捷的本地开发工具webpack-dev-server,在webpack.config.js文件添加devServer对象,是专门用于存放webpack-dev-server配置的,当webpack-dev-server发现工程源文件进行了更新操作就会自动刷新浏览器,展示更新后的内容
    devServer: {
    	hot: true,
    	// 自动打开浏览器
    	open: true
    }
    //webpack在构建包的时候会按目录的进行文件的查找,resolve属性中的extensions数组中用于配置程序可以自行补全哪些文件后缀,如下的配置我们想要加载一个js文件时,只要require(‘common’)就可以加载common.js文件了。
    resolve:{
        extensions:['','.js','.json']
    },
    //插件,用于完成一些 loader 不能完成的工作
    plugins: [
        new webpack.NoErrorsPlugin()
    ]mode: 'development', //生产环境
     // mode:'production,'//开发环境
};

webpack的运行流程

webpack是运行流程如下:

  1. 入口处理:从编写的 entry 开始,启动我们的编译流程
  2. 依赖解析:根据文件的 require 和 import 的情况,找到文件依赖的资源
  3. 资源解析:根据module的配置,将资源用不同的解析器进行处理,转成标准的内容
  4. 资源合并:将转译后的内容合并打包并且在我们 output 指定的文件中输出

使用webpack的详解

webpack的使用就是书写配置文件,使用我们要详细的去学如何去配置我们的 webpack.config.js 文件,他有多种的属性:
请添加图片描述

  • entry 和 output

entry 用于定于一次打包的入口文件,也就是从哪个文件开始打包

output 参数是个对象,用于定义构建后的文件的输出。其中包含path和filename,代表了输出路径和输出文件名称

	entry: './js/app.js',
    output: {
        path: './build',
        filename: 'bundle.js'
    },
  • module

webpack只能匹配优先类型的前端文件,比如 .css 。如果我们需要引入其他类型的文件,比如 .less 文件,我们需要通过加载器来处理它们,module就是做这个事情的,它通过rules定义一个对象数组,每一项通过 test 定义正则表达式去匹配不同后缀的文件名,然后通过 use 给它们定义不同的加载器,部分加载器可能需要你配置参数,你可以在 options 字段进行配置,exclude 则可以排除指定目录下的文件,使得他们不使用加载器进行加载,以下的例子是几种常见的配置,css 的解析,less 的解析,图片的解析,babel的配置:

  	module: {
       {
        // 正则: 匹配所有以css结尾的文件
        test: /\.css$/,
        // 使用的加载器,加载器处理顺序:从右往左
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../',
            },
          }, 
          'css-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../',
            },
          }, 
          'css-loader', 
          'less-loader'
        ]
      },
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            //配置项目
            options: {
              limit: 8 * 1024,
              // 配置输出的文件名
              name: '[name].[ext]',
              // 配置静态资源的引用路径
              publicPath: "../images/",
              // 配置输出的文件目录
              outputPath: "images/"
            }
          }
        ]
      },
      //  配置对于高版本js的兼容性处理
      {
        test: /\.js$/,
        // 配置排除项
        exclude: /(node_modules)/,
        use: [
        {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      ]
 	},
  • plugins

有一些 loader 不能完成的工作,我们需要导入一些插件来完成这些工作,比如自动生成一个html 文件,需要一个插件,我们这样导入

//在顶部引入
const HTMLWebpackPlugin = require('html-webpack-plugin')
//....省略代码
module.exports = {
    //....
	plugins: [
        new HTMLWebpackPlugin()
 	]}
  • devServer

devServer 是一个本地开发服务器,会自动监听变化,自动打包构建,自动更新刷新浏览器,你只需要下载相关的库,并且配置devServer 项就可以使用它,其中的 hot 是否开启热更新,就是就是你修改代码保存之后,浏览器不会刷新,只会修改你更改过的依赖代码。

    devServer: {
        //热更新
    	hot: true,
    	// 自动打开浏览器
    	open: true
    }

当然当你配置了热更新之后,你需要使用不一样的命令来执行打包

npx webpack server
  • watch

这个属性说明了是否开启 webpack 的监听功能,设置为 true 后,每次按保存键,webpack自动为我们打包,我们可以通过 watchOptions 来进行 watch 的配置

    watch:true
	watchOptions:{
    	poll:1000,//监测修改的时间(ms)
    	aggregeateTimeout:500, //防止重复按键,500毫米内算按键一次
    	ignored:/node_modules/,//不监测
	}
  • devtool

配置webpack的调试工具,一共有20多种可以选择,具体可以查看官网的文档,https://webpack.js.org/

合理的配置可以有效的实现Source Map

    devtool:"eval-source-map"
  • mode

提供 mode 配置选项,告知 webpack 使用相应模式的内置优化。

  1. development,会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
  2. 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin

区别简单的来说就是:production 会移除一些没有依赖的方法、变量和文件,并且代码会进行压缩,比development的文件小。

  • optimization

optimization主要用来自定义一些优化打包策略,主要有这些常用的值:

splitChunks:设置这个值会自动提取所有公共模块到单独bundle中去

minimize:表示是不是压缩模块

minimizer:属性存放一个数组,数组里可以存放用于代码压缩的插件

usedExports: 表示是不是只导出那些外部使用了的那些成员

concatenateModules:表示是不是合并模块,因为打包默认会把很多模块放进一个单独的函数中,如果模块很多的话,那么输出文件就会有很多这种模块函数

sideEffect:这个新特性可以让我们来标识我们的代码有没有副作用。但是有些模块的导入虽然没有使用,但是外部可能会继承自他们,或者有有些简介的联系,sideEffects 就可以标记这些模块,告诉javascript哪些没有副作用,可以去掉,哪些有副作用不可以去掉

optimization: {
    splitChunks: {
      // 自动提取所有公共模块到单独 bundle
      chunks: 'all'
    },
    // 表示只导出那些外部使用了的那些成员
    usedExports: true,
    // 压缩模块
    minimize:true,
    minimizer:[
   		 new TerserPlugin(),
   		 new OptimizeCssAssetsWebpackPlugin()
    ],
    concatenateModules:true,
    sideEffect: true
},

理解 Loader

loader 主要的作用的内容转换,因为 webpack 只认识 js 代码,loader要做的就是把非 js 的资源转换成 js 的资源,css 是链式调用的,比如 less 的解析需要用到如下三个 loader,他们是按照顺序分别执行的:

请添加图片描述

loader 的执行分为 pitch 和 normol 两个阶段,前者是从数组第一个向后执行,而后者是从最后一个向前执行,loader 会先执行 pitch,然后获取资源再执行 normal loader,但是如果 pitch 有返回值时,就不会走之后的 loader,并将返回值返回给之前的 loader。

因此,数组的第一个 loader 要返回 js 脚本,也就是最后要输出给webpack的内容;每个 loader 只做一件事,为了使 loader 在更多的场景中链式调用;每一个 loader 都是一个模块;每个 loader 都是无状态的,确保 loader 在不同的模块转换之间保存状态。
如果想要学会自己写一个 loader 可以查看 https://mp.weixin.qq.com/s/TPWcB4MfVrTgFtVxsShNFA

以下是常见的 loader:
请添加图片描述

理解插件

插件架构可以提升工具的拓展性:webpack的原理和底层是非常复杂的,新人需要了解整个流程成本很高,迭代成本很高,牵一发动全身,并且作为开源项目缺乏成长性,参与它很难。插件的精髓是,对外开放拓展,对修改封闭,我只实现核心的功能,其他的功能都由插件生态来共建和实现

webpack的实现原理是:Webpack 编译阶段会为各个编译对象初始化不同的 Hook ,开发者可以在自己编写的 Plugin 中监听到这些 Hook ,在打包的某个特定时间段触发对应 Hook 注入特定的逻辑从而实现自己的行为。

webpack上有两个很重要的对象:

  1. compiler 对象中保存着完整的 Webpack 环境配置,它通过 CLI 或 者 Node API传递的所有选项创建出一个 compilation 实例。这个对象会在首次启动 Webpack 时创建,我们可以通过 compiler 对象上访问到 Webapck 的主环境配置,比如 loader 、 plugin 等等配置信息
  2. compilation 对象代表一次资源的构建,compilation 实例能够访问所有的模块和它们的依赖,在 compilation 对象中我们可以获取/操作本次编译当前模块资源、编译生成资源、变化的文件以及被跟踪的状态信息,同样 compilation 也基于 tapable 拓展了不同时机的 Hook 回调

Plugin 的原型对象上需要存在一个 apply 方法,当 webpack 创建 compiler 对象时会调用各个插件实例上的 apply 方法并且传入 compiler 对象作为参数。同时需要指定一个绑定在 compiler 对象上的 Hook , 在 Hook 的回调中处理插件自身的逻辑,根据 Hook 的种类,在完成逻辑后通知 webpack 继续进行

Webpack Plugin 的核心机制就是基于 tapable 产生的发布订阅者模式,在不同的周期触发不同的 Hook 从而影响最终的打包结果。

想要详细了解的自行查阅一些资料,比如:

https://blog.csdn.net/gogo2027/article/details/127750064?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-127750064-blog-125101031.pc_relevant_3mothn_strategy_recovery&spm=1001.2101.3001.4242.1&utm_relevant_index=3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

25. 迭代器和生成器的详解

1. 迭代器 (1) 迭代是Python最强大的功能之一,是访问集合元素的一种方式。 (2) 迭代器是一个可以记住遍历的位置的对象。 (3) 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 (4) 迭代器有两个基本的方法…

Tkinter的Canvas控件

Canvas控件是Tkinter界面设计的一个画图工具,也可以用它导入外部图案到界面中 创建画布 import tkinter as tk roottk.Tk() #创建界面 root.title(Canvas) #界面命名 root.geometry(500x300) #设置界面大小 canvastk.Canvas(root) …

03_class创建device创建_kobject_uevent发送

总结 根据之前的kobject知道 /sys/目录下的每个文件夹都是一个 kobject的对象 使用class_create() 创建 /sys/class/xxx目录 同时返回class对象 使用device_create() 创建/sys/class/xxx/yyy目录 和创建/dev/yyy的文件节点 同时返回device对象 class和device 都间接继承于kobj…

【老卫搞机】135期:华为开发者联盟社区2022年牛人之星奖品开箱!

首先祝大家兔年大吉,身体安康,钱兔似锦!今天咱们来开箱一件特殊的奖品,来自华为开发者联盟社区的新年祝福——2022年牛人之星。 华为有钱!惯例用的是顺丰快递,各位看一下这里面是有很多件的 有这两件。第一…

三、TCP/IP---ARP和ICMP协议

ARP协议 简介:号称TCP/IP中最不安全的协议,安全工具,黑客工具大多数基于ARP协议。它是地址解析协议,用于实现从IP到MAC地址的映射,即询问目标Ip对应的MAC地址是多少,局域网通信不仅需要源目地址封装&#…

学习率衰减、局部最优、Batch归一化、Softmax回归

目录1.学习率衰减(Learning rate decay)在训练初期,梯度下降的步伐大一点,开始收敛的时候,小一些的学习率能让步伐小一些。1 epoch 遍历一遍训练集学习率衰减公式:例:假设衰减率decayrate 1,0.2epochNumα…

蓝桥杯-刷题-补基础

十道入门题 题目来源,题目,简单解析,代码,输入输出 目录 前言 一,汉诺塔 二,判断闰年 三,大写变小写 四,破译密码 五,反向数相加 六,Excel表中的列号 七,饮料兑换 八,角谷猜想 九,数字统计…

小喵2022年的年度总结,啊滴妈呀,开了眼了。

宝子,你不点个赞吗?不评个论吗?不收个藏吗? 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重…

Qt扫盲- QUdpSocket 类理论总结

QUdpSocket 类理论总结一、概述二、使用流程三、QNetworkDatagram 简述一、概述 UDP (User Datagram Protocol)是一种轻量级的、不可靠的、面向数据报的、无连接的协议。当可靠性不重要时,可以使用它。QUdpSocket是QAbstractSocket的子类,允许发送和接收…

SpringBoot+Vue--token,vue导航守卫,axios拦截器-笔记3

自己学习记录,写的不详细,没有误导,不想误导 大概的登录逻辑,前后端完整实现: 1.用户名,密码验证成功后,后端签发token返回给前端 2.前端把token保存到本地存储 3.每次请求前,通过axios请求拦截器,统一发送token 4.通过Vue导航守卫,和axios响应拦截器,统一保护页面 新建个…

【华为上机真题 2023】事件推送

🎈 作者:Linux猿 🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊! &…

机制设计原理与应用(四)预算可行的拍卖机制

文章目录4 预算可行的拍卖机制4.1 特征4.2 使用案例4.3 拍卖设计问题4.4 单调次模函数(Monotone Submodular Function)4.4.1 分配算法4.4.2 关键支付计划4.4.3 特性4.5 在线预算可行的拍卖机制4.5.1 Secretary Problem(A Optimal Stopping Problem)4.5.2…

如何与他人交流-第5期

上期我们讲了打破预期,顺应主体这期我们来讲讲如何建立亲和关系(关系侧)我的别人交流,只有在不把别人当成对象(工具人),而是把对方当成主体的情况下(让别人感受到尊重),这是相互尊重的终极本质,也是唯一方法.把别人当人看.认同对方,对方也会认同你.自信从何而来自信本意为相信自…

信息论复习—连续信源、信道及容量

目录 连续信源的熵: 连续信源离散化后的概率空间: 连续信源离散化后的熵: 连续信源的绝对熵: 连续信源的相对熵: 连续信源的条件熵: 连续信源的相对条件熵: 连续信源相对熵的最大化&#…

李宏毅ML-卷积神经网络CNN

李宏毅ML-卷积神经网络CNN 文章目录李宏毅ML-卷积神经网络CNNImage ClassificationConvolutional Layer1. Neural Version StoryReceptive FieldParameter Sharing2. Filter Version StoryFilterParameter Sharing3. Summary of Two VersionsPooling LayerThe Whole CNNDrawbac…

Hyperbolic geometry (双曲几何简介)

ContentsManifolds: A Gentle IntroductionManifoldsTangent SpacesMetric TensorRiemannian Manifolds (黎曼流形)Hyperbolic Geometry and Poincar EmbeddingsCurvature (曲率)Euclidean and Non-Euclidean GeometriesHyperbolic SpaceMinkowski SpaceHyperboloid (双曲面)Th…

树和森林(快来瞧)

森林的定义 森林是由多颗互不相交的树所构成的树的集合,即森林包含多棵树,每一棵树都有自己的根结点。一棵树也可以看成森林。 树的表示及基本操作 1.树(一般树)的表示方法 1.1树的双亲表示法 树的双亲表示法是将树的各个节点…

现场工程师出手-PCAPHub与云SSH隧道稳妥实现异地LAN工业联测

在去年,因为众所周知的因素影响,项目的甲方主动提出延缓设备的交付。作为乙方,尽管项目延缓是甲方提出的,但依旧希望按期交付,这样才能回款,熬过一年。其实,2022年初,几类传感器、压…

S7-1200PLC与ABB机器人进行PROFINET通信的具体方法和步骤详解

S7-1200PLC与ABB机器人进行PROFINET通信的具体方法和步骤详解 1. TIA博途一侧的配置: 当我们安装好RobotStudio软件后,可以在以下的目录中C:\ProgramData\ABB Industrial IT\Robotics IT\DistributionPackages\ABB.RobotWare-6.08.0134\RobotPackages\RobotWare_RPK_6.08.013…

【JavaWeb】JavaScript基础语法(上)

✨哈喽,进来的小伙伴们,你们好耶!✨ 🛰️🛰️系列专栏:【JavaWeb】 ✈️✈️本篇内容:JavaScript基础语法(上)! 🚀🚀代码托管平台github:JavaWeb代码存放仓库&#xff01…