webpack学习记录

/ 默认分类 / 没有评论 / 120浏览

Webpack

静态模块打包器,处理css、图片、字体、JSON5等静态文件转换成为JavaScript应用程序。天生实现CommonJS和ES模块化,本身就可拓展性的工具,通过安装不同的装备(loader和plugin)可以实现各种功能效果。

学习指南

附上官方文档:webpack文档

每一个分栏的侧重点不同,简要说明如下:

安装

全局安装是安装node的安装路径下的node_modules,安装记录也在全局的package.json文件中,全局安装的插件可以在任何终端/cmd窗口下运行插件指令。局部安装则是项目内的node_modules的文件夹内,安装信息记录在项目中package.json文件,只是安装的插件只能在项目根目录的运行,具体的寻址规则需要大家学习node。

本次文章推荐大家使用webpack依赖于node版本15+的LTS版本,方便大家体会到webpack的新特性。webpack4开始,需要安装webpack、webpack-cli(脚手架工具)两个包,如果已经安装可以通过webpack --version进行查看安装的版本。如需更新则使用npm update webpack webpack-cli命令,希望大家养成好习惯,建议使用局部的webpack!

webpack

npm install webpack

内部逻辑核心包,调用低层node对文件进行遍历、标记、操作,可以直接通过require引入webpack的执行函数进行构建,Vue-cli和react-cli内部的实现原理。

webpack-cli

npm install webpack-cli

似乎webpack-cli特别的鸡肋?其实不是!保证命令行可以执行webpack指令的工具,例如:webpack --config xxx,执行命令时携带的参数需要通过webpack-cli进行解析,并且传递给webpack。所以vue、react主流框架均开发了相对应的工具对webpack-cli进行替代。

工作环境

命令行工作环境

测试webpack是否可以正常运行,但是实际开发中会使用单独的webpack.config.js配置文件的形式。

目录结构

项目初始化

通过npm init -y初始化一个包管理清单package.json,本地安装npm i webpack webpack-cli -D,注意安装的路径,为了演示项目的优雅性,请时刻注意终端的路径。

调用进行打包

npx webpack 进行打包文件,默认寻找./src/index.js作为入口,如果需要自定义入口和出口时则命令为npx webpack --entry ./src/main.js --output-path ./dist,注意执行命令的路径。

打包结果

默认打包生成dist文件夹,main.js就是打包构建后的文件,引入html文件,通过vs code的live server插件进行运行即可查看结果。

webpack.config.js工作环境

注意webpack需要和package.json处于相同路径,所有的webpack信息需要包括在webpack.config.js文件中,至少需要书写entry和output两个模块内容。

目录结构

配置package.json

目的是可以使用npm run XXX进行打包程序

简单说一下原理,命令行输入npm run dev时,默认会查找package.json下的scripts对应的标识,相当于执行../node_modules/.bin/webpack --config ./webpack.config.js命令,获取上一级node_modules下面的webpack二进制文件,并且携带配置参数的地址。

webpack.config.js核心结构

简单进行一下概念解释:

  1. entry,入口文件配置,webpack打包的起始点,通过入口文件内获取到各分模块间的引用关系依赖图;
  2. outout,打包生存文件的输出目录;
  3. mode,打包的模式环境,不同的环境webpack有不同的默认功能;
  4. module,配置各个loader,负责解释转译webpack所不能识别的内容文件;
  5. plugin,配置各种插件,功能更广泛,可以进行文件的生存、变量注入、压缩代码、代码拆分功能;

处理样式文件

webpack默认只能识别解析json和js代码,无法处理css、图片、字体、JSON5、表格等文件,需要安装对应的loader才可以进行对文件的转译功能。

loader使用方式

内联方式使用

在引入文件中指明需要转译的loader

命令行执行时使用

已经淘汰,请勿使用!

webpack.config.js进行配置loader

强烈推荐并且以下全部通过此方法演示

处理CSS文件

webpack需要通过css-loader将css样式合入构建后js文件的style标签中,进而通过style-loader进行将style标签插入html文件的head标签中,才可以生效,而且需要注意laoder使用的顺序!

css-loader

npm i css-loader -D

读取css文件并且加入到打包构建后的js中,需要配合style-loader使用,否则无法看到效果。

style-loader

npm i style-loader -D

将打包构建后js文件中的style标签,动态的插入html文件的head标签中,并且style自带可以热模块更新,支持模块热替换。

处理Less文件

less是css的一种书写方式,但是浏览器无法识别,需要通过webpack进行转换成为css,所以处理less文件比css多一步,首先使用less-loader将less语法转换成为css,然后再复用css-loader和style-loader。

less

npm i less -D

Less是一个可以独立于webpack的工具,可以单独通过命令行使用less,支持将less文件转换为css文件并且输出。

less-loader

npm i less-loader less -D

通过webpack使用less批量转换文件则需要安装less-loader

样式兼容性适配

某些css规则在一些浏览器中需要通过添加浏览器前缀才可以生效,需要到postcss工具,它可以根据我们配置的规则去添加需要适配的浏览器前缀,规则是通过浏览器进行的市场占有率进行设定。

规则的配置方式

package.json
.browserslistrc文件

PostCss

npm install postcss postcss-cli -D

PostCSS是一个独立的工具可以单独使用,将为css文件的规则添加前缀,并且输出。

Postcss-loader

npm install postcss postcss-cli postcss-loader autoprefixer postcss-preset-env -D

需要通过webpack批量操作则需要通过postcss-loader,通过为postcss-loader设置插件实现不同功能。autoprefixer插件根据browserslist配置规则,为浏览器添加样式前缀。

Autoprefixer

autoprefixer插件根据browserslist配置规则确定适配的浏览器,browserslist规则是根据浏览器市场占有率进行设定,参考的数据来源由caniuse网站进行统计。npm初始化webpack项目携带有browserslist工具,可以单独使用。

Postcss-preset-env

可以代替autoprefixer的功能之外还有CSS特性转换的功能

处理文件资源

File-loader

npm i file-loader -D

负责解析我们通过impot和require引入的资源, 并且以正确的路径进入到打包文件中。

Url-loader

npm i url-loader -D

作用与file-loader相似,增加了可以控制文件转为base64直接插入js脚本中。

Asset module type

webpack5自带的处理静态文件工具,根据不同的资源设定类型值,使用不同的内置功能进行处理。推荐使用最新的处理方式,但是需要注意,本方式会与上面的url-loader和file-loader冲突而生成多份文件。

资源模块的有如下几种类型:

  1. asset/resource,导出一个资源的URL,引入打包文件夹中,并且以正确路径引入构建的文件中,类似于file-loader的功能;
  2. asset/inline,导出一个资源的dataURL,类似于url-loader的功能;
  3. asset/source,导出资源的源代码,通过使用raw-loader实现;
  4. asset,自动在导出dataURL和单独文件选择,类似于url-loader,并且配置限制limt体积的功能;

Plugin的介绍

配置各种插件,功能更广泛,可以进行文件的生存、变量注入、压缩代码、代码拆分功能。

Clean-webpack-plugin

npm i clean-webpack-plugin -D

允许在打包之前清空打包输出的文件夹,防止上次打包遗留文件干扰。

Html-webpack-plugin

npm i html-webpack-plugin -D

允许我们为项目自动生成html模版,并且可以配合动态引入打包后的文件。可以设置模版的标题、源模版等功能。

Define-plugin

webpack内置插件无需安装

允许我们在webpack在编译时创建全局的常量,如下例子演示,定义了一个可以全局访问的BASE_URL 常量。

Copy-webpack-plugin

npm i copy-webpack-plugin -D

从指定目录拷贝文件到打包目录中

Source-map

打包构建后的代码和源代码的映射关系,source-map同样也有版本之分,source-map的生效需要浏览器的支持,配置清单Devtool | webpack 中文文档 (docschina.org)内容相对较多,大家自行查阅。

启用

启用webpack的source-map功能有如下两个步骤:

  1. 使用devtool功能打开source-map选项并且设定对应的值;
  2. 打包文件的最后一样添加魔法注释(自动实现);

配置值

开发和测试阶段: source-map或者cheap-module-source-map,发布阶段false或者缺省(不写)。

默认值为none,不同变体组合有不一样的效果,大体上的概念如下:

  1. eval开头的配置打包速度快,映射文件通过eval函数包裹并嵌入在打包文件中,内容被转换成base64格式,可以定位到行和列的信息;
  2. source-map配置可以清晰的访问到对应的源代码,可以准备的定位到错误于源代码的位置,并且生成独立的.map文件,能够在浏览器中查看到源代码,打包速度慢;
  3. 含cheap的配置不会有列映射,打包速度相对较快一些,cheap-module-source-map能够将babel-loader转译后的语法还原为源文件,方便与定位;
  4. inline开头的配置会在打包文件的尾部通过dataURL的形式去家在真正的source-map文件;
  5. 含nosources的配置不会生产source-map文件,无法定位到错误信息,但是可以防止代码泄漏;
  6. hidden开头的配置会生成source-map文件,但是不会在打包文件内设置dataURL,所以无法访问到对应的错误信息;

处理Es语法

npm i @babel/core babel-loader @babel/preset-env -D 全部安装

Babel

JavaScript的编译器,可以将低版本浏览器不支持的ES6语法转换成为可识别的ES5语法,达到兼容浏览器的效果,Babel和PostCSS一样是个独立的工具,通过安装各种插件实现语法转换,例如:transform-block-scopiing(块级作用域)插件实现const、let语法转换,如果我们需要在Webpack中使用Babel则需要引入babel-loader。

Babel-loader

npm i babel-loader D

webpack通过babel-loader去匹配js文件,然后根据配置安装的插件进行语法的转换。

@Babel/preset-env

npm i @babel/preset-env -D

我们需要babel进行语法转换,就要记住所有的babel插件?不不不,babel给我们推出了preset-env预设,它可以根据我们的browserslist配置,自动针对特定浏览器进行语法转换。

Polyfill

npm i core-js regenerator-runtime (推荐)

babel自带的库只可以进行语法的转换,但是无法转换promise、symbol、Array.prototype.includes等语法新特性,因为浏览器不能识别,这时可以通过polyfill配合babel进行为浏览器进行补充拓展。

7.4.0版本之前

npm i @babel/polyfill

polyfill的原理就是将语法的新特性通过ES5的方式转换成浏览器能够识别的代码,在入口文件中引入,webpack将整个polyfill库进行打包,并且嵌入到入口文件中为浏览器做一个拓展,以下分别是两种使用方式:

方式一 方式二

7.4.0版本之后

npm i core-js regenerator-runtime

新版本的polyfill是配合preset-env预设进行使用,可以根据预设兼容的浏览器,动态的添加polyfill补丁,而不是整个库进行引入,极大的缩减代码体积。如下是polyfill和preset-env合作的两种方式:

方式一 方式二