04-Webpack

前言

本文章来源于王红元老师(coderwhy)的 Vue3 + Ts 课程
附上链接:https://ke.qq.com/course/3453141
谁能拒绝一个100%好评还加课的老师呢

目录

前言

认识webpack

脚手架依赖webpack

Webpack到底是什么呢?

Vue项目加载的文件有哪些呢?

Webpack的使用

Webpack的使用前提

Webpack的安装

Webpack的默认打包

创建局部的webpack

Webpack配置

Webpack配置文件

指定配置文件

Webpack的依赖

编写案例代码

loader的使用

css-loader的使用

Loader配置方式

Loader的配置代码

style-loader

配置style-loader

如何处理less文件?

Less工具处理

less-loader处理

认识PostCSS工具

命令行使用postcss

插件autoprefixer

postcss-loader

单独的postcss配置文件

postcss-preset-env

加载图片案例准备

file-loader

文件命名规则

设置文件名称

设置文件的存放路径

url-loader

url-loader的limit

 url-loader的limit效果

认识asset module type

asset module type的使用

加载字体文件

字体的打包

认识Plugin

CleanWebpackPlugin

HtmlWebpackPlugin

生成 index.html分析

自定义HTML模板

自定义模板数据填充

DefinePlugin的介绍

DefinePlugin的使用

CopyWebpackPlugin

Mode配置

Mode配置列表


认识webpack

  • 事实上随着前端的快速发展,目前前端的开发已经变的越来越复杂了:

    • 比如开发过程中我们需要通过模块化的方式来开发;

    • 比如也会使用一些高级的特性来加快我们的开发效率或者安全性,比如通过ES6+、TypeScript开发脚本逻辑, 通过sass、less等方式来编写css样式代码;

    • 比如开发过程中,我们还希望实时的监听文件的变化来并且反映到浏览器上,提高开发的效率;

    • 比如开发完成后我们还需要将代码进行压缩、合并以及其他相关的优化;

    • 等等….

  • 但是对于很多的前端开发者来说,并不需要思考这些问题,日常的开发中根本就没有面临这些问题:

    • 这是因为目前前端开发我们通常都会直接使用三大框架来开发:Vue、React、Angular;

    • 但是事实上,这三大框架的创建过程我们都是借助于脚手架(CLI)的;

    • 事实上Vue-CLI、create-react-app、Angular-CLI都是基于webpack来帮助我们支持模块化、less、 TypeScript、打包优化等的;

脚手架依赖webpack

Webpack到底是什么呢?

  • 我们先来看一下官方的解释:

  • webpack是一个静态的模块化打包工具,为现代的JavaScript应用程序;

  • 我们来对上面的解释进行拆解:

    • 打包bundler:webpack可以将帮助我们进行打包,所以它是一个打包工具

    • 静态的static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器);

    • 模块化module:webpack默认支持各种模块化开发,ES Module、CommonJS、AMD等;

    • 现代的modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了webpack的出现和发展

Vue项目加载的文件有哪些呢?

  • JavaScript的打包:

    • 将ES6转换成ES5的语法;

    • TypeScript的处理,将其转换成JavaScript;

  • Css的处理:

    • CSS文件模块的加载、提取;

    • Less、Sass等预处理器的处理;

  • 资源文件img、font:

    • 图片img文件的加载;

    • 字体font文件的加载;

  • HTML资源的处理:

    • 打包HTML资源文件;

  • 处理vue项目的SFC文件.vue文件

Webpack的使用

Webpack的使用前提

  • webpack的官方文档是webpack

    • webpack的中文官方文档是webpack

    • DOCUMENTATION:文档详情,也是我们最关注的

  • Webpack的运行是依赖Node环境的,所以我们电脑上必须有Node环境

    • 所以我们需要先安装Node.js,并且同时会安装npm;

    • 我当前电脑上的node版本是v14.15.5,npm版本是6.14.11(你也可以使用nvm或者n来管理Node版本)

    • Node官方网站:Node.js

Webpack的安装

  • webpack的安装目前分为两个:webpack、webpack-cli

  • 那么它们是什么关系呢?

    • 执行webpack命令,会执行node_modules下的.bin目录下的webpack;

    • webpack在执行时是依赖webpack-cli的,如果没有安装就会报错;

    • 而webpack-cli中代码执行时,才是真正利用webpack进行编译和打包的过程;

    • 所以在安装webpack时,我们需要同时安装webpack-cli(第三方的脚手架事实上是没有使用webpack-cli的,而是类似于自 己的vue-service-cli的东西)

Webpack的默认打包

  • 我们可以通过webpack进行打包,之后运行打包之后的代码

    • 在目录下直接执行 webpack 命令

       webpack
  • 生成一个dist文件夹,里面存放一个main.js的文件,就是我们打包之后的文件:

    • 这个文件中的代码被压缩和丑化了;

    • 另外我们发现代码中依然存在ES6的语法,比如箭头函数、const等,这是因为默认情况下webpack并不清楚我们打包后的文 件是否需要转成ES5之前的语法,后续我们需要通过babel来进行转换和设置;

  • 我们发现是可以正常进行打包的,但是有一个问题,webpack是如何确定我们的入口的呢?

    • 事实上,当我们运行webpack时,webpack会查找当前目录下的 src/index.js作为入口;

    • 所以,如果当前项目中没有存在src/index.js文件,那么会报错;

  • 当然,我们也可以通过配置来指定入口和出口

     npx webpack --entry ./src/main.js --output-path ./build

创建局部的webpack

  • 前面我们直接执行webpack命令使用的是全局的webpack,如果希望使用局部的可以按照下面的步骤来操作。

  • 第一步:创建package.json文件,用于管理项目的信息、库依赖等

     npm init
  • 第二步:安装局部的webpack

     npm init webpack webpack cli -D
  • 第三步:使用局部的webpack

     npx webpack

  • 第四步:在package.json中创建scripts脚本,执行脚本打包即可

     npm run build

Webpack配置

Webpack配置文件

  • 在通常情况下,webpack需要打包的项目是非常复杂的,并且我们需要一系列的配置来满足要求,默认配置必然 是不可以的。

  • 我们可以在根目录下创建一个webpack.config.js文件,来作为webpack的配置文件:

  •  

  • 继续执行webpack命令,依然可以正常打包

     npm run build

指定配置文件

  • 但是如果我们的配置文件并不是webpack.config.js的名字,而是其他的名字呢?

    • 比如我们将webpack.config.js修改成了 wk.config.js;

    • 这个时候我们可以通过 --config 来指定对应的配置文件;

       webpack --config wk.config.js
  • 但是每次这样执行命令来对源码进行编译,会非常繁琐,所以我们可以在package.json中增加一个新的脚本:

  •  

  • 之后我们执行 npm run build来打包即可。

Webpack的依赖

  • webpack到底是如何对我们的项目进行打包的呢?

    • 事实上webpack在处理应用程序时,它会根据命令或者配置文件找到入口文件;

    • 从入口开始,会生成一个 依赖关系图,这个依赖关系图会包含应用程序中所需的所有模块(比如.js文件、css文件、图片、字 体等);

    • 然后遍历图结构,打包一个个模块(根据文件的不同使用不同的loader来解析);

    •  

编写案例代码

  • 我们创建一个component.js

    • 通过JavaScript创建了一个元素,并且希望给它设置一些样式;

    •  

    • 继续编译命令npm run build

    •  

loader的使用

css-loader的使用

  • 上面的错误信息告诉我们需要一个loader来加载这个css文件,但是loader是什么呢?

    • loader 可以用于对模块的源代码进行转换;

    • 我们可以将css文件也看成是一个模块,我们是通过import来加载这个模块的;

    • 在加载这个模块时,webpack其实并不知道如何对其进行加载,我们必须制定对应的loader来完成这个功能;

  • 那么我们需要一个什么样的loader呢?

    • 对于加载css文件来说,我们需要一个可以读取css文件的loader;

    • 这个loader最常用的是css-loader;

    • css-loader的安装:

       npm install css-loader -D
  • 如何使用这个loader来加载css文件呢?有三种方式:

    • 内联方式;

    • CLI方式(webpack5中不再使用);

    • 配置方式;

  • 内联方式:内联方式使用较少,因为不方便管理;

    • 在引入的样式前加上使用的loader,并且使用 ! 分割;

       import "css-loader!../css/style.css"
  • CLI方式

    • 在webpack5的文档中已经没有了--module-bind;

    • 实际应用中也比较少使用,因为不方便管理;

Loader配置方式

  • 配置方式表示的意思是在我们的webpack.config.js文件中写明配置信息:

    • module.rules中允许我们配置多个loader(因为我们也会继续使用其他的loader,来完成其他文件的加载);

    • 这种方式可以更好的表示loader的配置,也方便后期的维护,同时也让你对各个Loader有一个全局的概览;

  • module.rules的配置如下:

  • rules属性对应的值是一个数组:[Rule]

  • 数组中存放的是一个个的Rule,Rule是一个对象,对象中可以设置多个属性:

    • test属性:用于对 resource(资源)进行匹配的,通常会设置成正则表达式;

    • use属性:对应的值时一个数组:[UseEntry]

      • UseEntry是一个对象,可以通过对象的属性来设置一些其他属性

        • loader:必须有一个 loader属性,对应的值是一个字符串;

        • options:可选的属性,值是一个字符串或者对象,值会被传入到loader中;

        • query:目前已经使用options来替代;

      • 传递字符串(如:use: [ 'style-loader' ])是 loader 属性的简写方式(如:use: [ { loader: 'style-loader'} ]);

    • loader属性: Rule.use: [ { loader } ] 的简写

Loader的配置代码

 

style-loader

  • 我们已经可以通过css-loader来加载css文件了

    • 但是你会发现这个css在我们的代码中并没有生效(页面没有效果)。

  • 这是为什么呢?

    • 因为css-loader只是负责将.css文件进行解析,并不会将解析之后的css插入到页面中;

    • 如果我们希望再完成插入style的操作,那么我们还需要另外一个loader,就是style-loader;

  • 安装style-loader:

     npm install style-loader -D

配置style-loader

  • 那么我们应该如何使用style-loader:

    • 在配置文件中,添加style-loader;

    • 注意:因为loader的执行顺序是从右向左(或者说从下到上,或者说从后到前的),所以我们需要将style-loader写到css-loader的前面;

  • 重新执行编译npm run build,可以发现打包后的css已经生效了:

    • 当前目前我们的css是通过页内样式的方式添加进来的;

    • 后续我们也会讲如何将css抽取到单独的文件中,并且进行压缩等操作;

如何处理less文件?

  • 在我们开发中,我们可能会使用less、sass、stylus的预处理器来编写css样式,效率会更高。

  • 那么,如何可以让我们的环境支持这些预处理器呢?

  • 首先我们需要确定,less、sass等编写的css需要通过工具转换成普通的css;

  • 比如我们编写如下的less样式:

Less工具处理

  • 我们可以使用less工具来完成它的编译转换:

     npm install less -D
  • 执行如下命令:

     npm install less -D npx lessc ./src/css/title.less title.css

less-loader处理

  • 但是在项目中我们会编写大量的css,它们如何可以自动转换呢?

    • 这个时候我们就可以使用less-loader,来自动使用less工具转换less到css;

     npm install less-loader -D
  • 配置webpack.config.js

  • 执行npm run build less就可以自动转换成css,并且页面也会生效了

认识PostCSS工具

  • 什么是PostCSS呢?

    • PostCSS是一个通过JavaScript来转换样式的工具;

    • 这个工具可以帮助我们进行一些CSS的转换和适配,比如自动添加浏览器前缀、css样式的重置; p但是实现这些功能,我们需要借助于PostCSS对应的插件;

  • 如何使用PostCSS呢?主要就是两个步骤:

    • 第一步:查找PostCSS在构建工具中的扩展,比如webpack中的postcss-loader;

    • 第二步:选择可以添加你需要的PostCSS相关的插件;

命令行使用postcss

  • 当然,我们能不能也直接在终端使用PostCSS呢?

    • 也是可以的,但是我们需要单独安装一个工具postcss-cli;

  • 我们可以安装一下它们:postcss、postcss-cli

     npm install postcss postcss-cli -D
  • 我们编写一个需要添加前缀的css:

插件autoprefixer

  • 因为我们需要添加前缀,所以要安装autoprefixer:

     npm install autoprefixer -D
  • 直接使用使用postcss工具,并且制定使用autoprefixer

     npx postcss --use autoprefixer -o end.css ./src/css/style.css
  • 转化之后的css样式如下:

postcss-loader

  • 真实开发中我们必然不会直接使用命令行工具来对css进行处理,而是可以借助于构建工具:

    • 在webpack中使用postcss就是使用postcss-loader来处理的;

  • 我们来安装postcss-loader:

     npm install postcss-loader -D
  • 我们修改加载css的loader:(配置文件已经过多,给出一部分了)

    • 注意:因为postcss需要有对应的插件才会起效果,所以我们需要配置它的plugin;

单独的postcss配置文件

  • 当然,我们也可以将这些配置信息放到一个单独的文件中进行管理:

    • 在根目录下创建postcss.config.js

postcss-preset-env

  • 事实上,在配置postcss-loader时,我们配置插件并不需要使用autoprefixer。

  • 我们可以使用另外一个插件:postcss-preset-env

    • postcss-preset-env也是一个postcss的插件;

    • 它可以帮助我们将一些现代的CSS特性,转成大多数浏览器认识的CSS,并且会根据目标浏览器或者运行时环境 添加所需的polyfill;

    • 也包括会自动帮助我们添加autoprefixer(所以相当于已经内置了autoprefixer);

  • 首先,我们需要安装postcss-preset-env:

    npm install postcss-preset-env -D
  • 之后,我们直接修改掉之前的autoprefixer即可:

  • 注意:我们在使用某些postcss插件时,也可以直接传入字符串

加载图片案例准备

  • 为了演示我们项目中可以加载图片,我们需要在项目中使用图片,比较常见的使用图片的方式是两种:

    • img元素,设置src属性;

    • 其他元素(比如div),设置background-image的css属性;

    • 这个时候,打包会报错

file-loader

  • 要处理jpg、png等格式的图片,我们也需要有对应的loader:file-loader

    • file-loader的作用就是帮助我们处理import/require()方式引入的一个文件资源,并且会将它放到我们输出的文件夹中;

    • 当然我们待会儿可以学习如何修改它的名字和所在文件夹;

  • 安装file-loader:

     npm install file-loader -D
  • 配置处理图片的Rule:

文件命名规则

  • 有时候我们处理后的文件名称按照一定的规则进行显示:

    • 比如保留原来的文件名、扩展名,同时为了防止重复,包含一个hash值等;

  • 这个时候我们可以使用PlaceHolders来完成,webpack给我们提供了大量的PlaceHolders来显示不同的内容:

  • 我们这里介绍几个最常用的placeholder:

    • [ext]: 处理文件的扩展名;

    • [name]:处理文件的名称;

    • [hash]:文件的内容,使用MD4的散列函数处理,生成的一个128位的hash值(32个十六进制);

    • [contentHash]:在file-loader中和[hash]结果是一致的(在webpack的一些其他地方不一样,后面会讲到);

    • [hash:<length>]:截图hash的长度,默认32个字符太长了;

    • [path]:文件相对于webpack配置文件的路径;

设置文件名称

  • 那么我们可以按照如下的格式编写:

  • 这个也是vue的写法;

设置文件的存放路径

  • 刚才通过 img/ 已经设置了文件夹,这个也是vue、react脚手架中常见的设置方式

    • 其实按照这种设置方式就可以了;

    • 当然我们也可以通过outputPath来设置输出的文件夹;

url-loader

  • url-loader和file-loader的工作方式是相似的,但是可以将较小的文件,转成base64的URI。

  • 安装url-loader:

     url-loader npm install url-loader -D 
  • 显示结果是一样的,并且图片可以正常显示;

  • 但是在dist文件夹中,我们会看不到图片文件:

    • 这是因为我的两张图片的大小分别是38kb和295kb;

    • 默认情况下url-loader会将所有的图片文件转成base64编码

url-loader的limit

  • 但是开发中我们往往是小的图片需要转换,但是大的图片直接使用图片即可

    • 这是因为小的图片转换base64之后可以和页面一起被请求,减少不必要的请求过程;

    • 而大的图片也进行转换,反而会影响页面的请求速度;

  • 那么,我们如何可以限制哪些大小的图片转换和不转换呢?

    • url-loader有一个options属性limit,可以用于设置转换的限制;

    • 下面的代码38kb的图片会进行base64编码,而295kb的不会;

 url-loader的limit效果

  • 我们需要两个步骤来实现:

    • 步骤一:将type修改为asset

    • 步骤二:添加一个parser属性,并且制定dataUrl的条件,添加maxSize属性;

认识asset module type

  • 我们当前使用的webpack版本是webpack5:

    • 在webpack5之前,加载这些资源我们需要使用一些loader,比如raw-loader 、url-loader、file-loader;

    • 在webpack5开始,我们可以直接使用资源模块类型(asset module type),来替代上面的这些loader;

  • 资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

    • asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现;

    • asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现;

    • asset/source 导出资源的源代码。之前通过使用 raw-loader 实现;

    • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体 积限制实现;

asset module type的使用

  • 比如加载图片,我们可以使用下面的方式:

  • 但是,如何可以自定义文件的输出路径和文件名呢?

    • 方式一:修改output,添加assetModuleFilename属性;

    • 方式二:在Rule中,添加一个generator属性,并且设置filename;

加载字体文件

  • 如果我们需要使用某些特殊的字体或者字体图标,那么我们会引入很多字体相关的文件,这些文件的处理也是一样 的。

  • 首先,从阿里图标库中下载了几个字体图标:

  • 在component中引入,并且添加一个i元素用于显示字体图标:

字体的打包

  • 这个时候打包会报错,因为无法正确的处理eot、ttf、woff等文件:

    • 我们可以选择使用file-loader来处理,也可以选择直接使用webpack5的资源模块类型来处理;

认识Plugin

  • Webpack的另一个核心是Plugin,官方有这样一段对Plugin的描述:

    • While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables.

  • 上面表达的含义翻译过来就是:

  • Loader是用于特定的模块类型进行转换;

  • Plugin可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;

CleanWebpackPlugin

  • 前面我们演示的过程中,每次修改了一些配置,重新打包时,都需要手动删除dist文件夹:

  • 我们可以借助于一个插件来帮助我们完成,这个插件就是CleanWebpackPlugin;

  • 首先,我们先安装这个插件:

     npm install clean-webpack-plugin -D
  • 之后在插件中配置:

HtmlWebpackPlugin

  • 另外还有一个不太规范的地方:

    • 我们的HTML文件是编写在根目录下的,而最终打包的dist文件夹中是没有index.html文件的。

    • 在进行项目部署的时,必然也是需要有对应的入口文件index.html;

    • 所以我们也需要对index.html进行打包处理;

  • 对HTML进行打包处理我们可以使用另外一个插件:HtmlWebpackPlugin;

     npm install html-webpack-plugin -D

生成 index.html分析

  • 我们会发现,现在自动在dist文件夹中,生成了一个index.html的文件:

    • 该文件中也自动添加了我们打包的bundle.js文件;

  • 这个文件是如何生成的呢?

    • 默认情况下是根据ejs的一个模板来生成的;

    • 在html-webpack-plugin的源码中,有一个default_index.ejs模块;

自定义HTML模板

  • 如果我们想在自己的模块中加入一些比较特别的内容:

    • 比如添加一个noscript标签,在用户的JavaScript被关闭时,给予响应的提示;

    • 比如在开发vue或者react项目时,我们需要一个可以挂载后续组件的根标签

       <div id = "app"></div>
  • 这个我们需要一个属于自己的index.html模块:

自定义模板数据填充

  • 上面的代码中,会有一些类似这样的语法<% 变量 %>,这个是EJS模块填充数据的方式。

  • 在配置HtmlWebpackPlugin时,我们可以添加如下配置:

    • template:指定我们要使用的模块所在的路径;

    • title:在进行htmlWebpackPlugin.options.title读取时,就会读到该信息;

DefinePlugin的介绍

  • 但是,这个时候编译还是会报错,因为在我们的模块中还使用到一个BASE_URL的常量:

  • 这是因为在编译template模块时,有一个BASE_URL:

    •  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    • 但是我们并没有设置过这个常量值,所以会出现没有定义的错误;

  • 这个时候我们可以使用DefinePlugin插件

DefinePlugin的使用

  • DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装):

  • 这个时候,编译template就可以正确的编译了,会读取到BASE_URL的值;

CopyWebpackPlugin

  • 在vue的打包过程中,如果我们将一些文件放到public的目录下,那么这个目录会被复制到dist文件夹中。

    • 这个复制的功能,我们可以使用CopyWebpackPlugin来完成;

  • 安装CopyWebpackPlugin插件:

      npm install copy-webpack-plugin -D
  • 接下来配置CopyWebpackPlugin即可:

    • 复制的规则在patterns中设置;

    • from:设置从哪一个源中开始复制;

    • to:复制到的位置,可以省略,会默认复制到打包的目录下;

    • globOptions:设置一些额外的选项,其中可以编写需要忽略的文件:

      • .DS_Store:mac目录下回自动生成的一个文件;

      • index.html:也不需要复制,因为我们已经通过HtmlWebpackPlugin完成了index.html的生成;

      •  

         

Mode配置

  • Mode配置选项,可以告知webpack使用响应模式的内置优化:

    • 默认值是production(什么都不设置的情况下);

    • 可选值有:'none' | 'development' | 'production';

  • 这几个选项有什么样的区别呢?

Mode配置列表

  •  

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值