webpack默认打包

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

在目录下直接执行webpack命令 使用的是全局的webpack

  • 之后生成一个dist文件夹,里面存放一个main.js的文件,就是我们打包之后的文件
    • 这个文件中的代码被压缩和丑化了;

webpack是如何确定我们的入口?

  • 我们运行webpack时,webpack会查找当前目录下的 src/index.js作为入口;
  • 所以,如果当前项目中没有存在src/index.js文件,那么会报错;

通过配置指定入口和出口 npx webpack --entry ./src/main.js --output-path ./build

Webpack配置文件

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

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

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

指定配置文件

  • 如果配置文件不是webpack.config.js那么需要执行指令

    • 比如我们将webpack.config.js修改成了 wk.config.js
    • 那么需要执行指令 webpack --config wk.config.js
    • 并且可以通过在package.json中添加脚本
    1
    2
    3
    "scripts"{
    "build":"webpack --config wk.config.js"
    }
  • 执行npm run build 来打包即可

webpack依赖图

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

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

    字体等);

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

Loader

创建一个common.js 通过js创建一个元素 并且当我们希望给他设置一些样式的时候引入css文件 这个时候执行打包 会有如下报错

这个错误信息提醒我们需要一个loader来加载这个css文件 那么什么是loader呢

  • loader可以对 模块的源代码 进行转换
  • 我们可以将css文件也看成是一个模块 通过import来加载这个模块
  • 在加载这个模块时,webpack其实并不知道如何对其进行加载,我们必须制定对应的loader来完成这个功能

css-loader的使用

对于加载css文件来说 我们需要一个可以读取css文件的loader 是这个loader最常用的就是css-loader

安装css-loader npm install css-loader -D

  • 内联方式;
    • 使用较少 不方便管理
    • 在引入的样式前加上使用的loader,并且使用!分割;
    • import "css-loader ! ../css/style.css
  • CLI方式(webpack5中不再使用);
    • 在webpack5的文档中已经没有了–module-bind;
    • 在webpack5的文档中已经没有了–module-bind;
  • 配置方式

配置方式

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

  • module中有一个rules 属性 这个属性的配置如下

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

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

      • test属性 :用于匹配resource 通常是正则表达式

      • use属性 : 对应的是一个数组

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

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

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

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

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

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

loader配置代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module: {
rules : [
{
//规则使用正则表达式
test: /\.css$/, //匹配资源
//loader:"css-loader" 写法一
// use:["css-loader"] 写法二
// 写法三
use: [
{ loader:"css-loader" }
],
}
]
}

style-loader的使用

使用css-loader后可以加载css文件了 但是我们会发现css 并没有生效

  • 因为css-loader只是负责将.css文件进行解析,并不会将解析之后的css插入到页面中;
  • 如果我们希望再完成插入style的操作,那么我们还需要另外一个loader,就是style-loader
  • 安装style-loader
    • npm install style-loader -D

注意: webpack中处理loader是从后往前处理的 所以要将style-loader写在 css-loader前面

1
2
3
4
use:[
"style-loader",
"css-loader",
]
  • 当前的style-loader是通过 document.createElement(style) 的方式生成了页内样式让css生效

less 的处理

当我们使用预处理器编写css样式的时候 怎么让我们的环境支持这些预处理器呢?

  • 首先我们要把 less sass等通过工具转换成css

  • 我们需要使用less工具完成它的编译转换

    • npm install less -D
    • npx less ./src/css/title.less > title.css
  • 当在项目中编写大量的css 我们需要自动转换

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

    • npm install less-loader -D
    • 并对webpack.config.js进行配置

浏览器兼容性

我们该如何解决浏览器兼容性?这里指的是针对不同浏览器支持的特性

在很多脚手架中会看到如下配置

1
2
3
> 1%
last 2 versions
not dead

这里的百分之一,就是指市场占有率

浏览器市场占有率

通过如下网站可以查看浏览器市场占有率

https://caniuse.com/usage-table

重要的 browserslist工具

如何可以在css兼容性和js兼容性下共享配置的兼容性条件?

  • 当我们设置了一个条件 >1%
  • 该条件代表的意思是css和js 要兼容市场占有率大于1%的浏览器

如何共享配置?

  • 通过Browserslist

  • Browserslist是一个在不同的前端工具之间共享目标浏览器和Node.js版本的配置

    Browserslist编写规则一:

  • defaults:Browserslist的默认浏览器(> 0.5%, last 2 versions, Firefox ESR, not dead)。

  • 5%:通过全局使用情况统计信息选择的浏览器版本。 >=,<和<=

  • dead:24个月内没有官方支持或更新的浏览器。现在是IE 10,IE_Mob 11,BlackBerry 10,BlackBerry 7, Samsung 4和OperaMobile 12.1。

  • last 2 versions:每个浏览器的最后2个版本。

    Browserslist编写规则二 :

  • node 10和node 10.4:选择最新的Node.js10.x.x 或10.4.x版本。

    • current node:Browserslist现在使用的Node.js版本。
    • maintained node versions:所有Node.js版本,仍由 Node.js Foundation维护。
  • iOS 7:直接使用iOS浏览器版本7。

    • Firefox ESR:最新的[Firefox ESR]版本。
    • 。。。
  • supports es6-module:支持特定功能的浏览器。

  • browserslist config:在Browserslist配置中定义的浏览器。在差异服务中很有用,可用于修改用户的配置

  • since 2015或last 2 years:自2015年以来发布的所有版本

  • unreleased versions或unreleased Chrome versions:Alpha和Beta版本。

  • not ie <= 8:排除先前查询选择的浏览器。

Browserslist浏览器查询过程

我们可以将配置通过两种方式编写

  • 一种是通过在package.json中添加
1
2
3
4
5
"browserslist": [
">1%",
"last 2 version",
"not dead"
]
  • 或者新建文件 .browserslistrc
1
2
3
>1%
last 2 version
not dead

PostCSS工具

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

这个工具可以帮助我们进行一些CSS的转换和适配,比如自动添加浏览器前缀css样式的重置

但是实现这些工具,我们需要借助于PostCSS对应的插件;

使用PostCSS

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

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

在命令行使用PostCSS

  • 我们需要单独安装一个工具 postcss-cli npm install postcss postcss-cli -D
  • 编写一个需要添加前缀的css
  • 因为要添加前缀 所以安装autoprefixer
    • npm install autoprefixer -D
  • 直接使用postcss工具 并指定使用autoprefixer
    • npx postcss –use autoprefixer -o end.css ./src/css/style.css

PostCSS在webpack中使用

  • 在webpack中postcss就是使用 postcss-loader来处理的
    • npm install postcss-loader -D
  • 然后修改加载css的loader
    • 注意:因为postcss需要有对应的插件才会起效果,所以我们需要配置它的plugin
1
2
3
4
5
6
7
8
9
10
{        
loader: "postcss-loader",
options: {
postcssOptions:{
plugins: [
require("autoprefixer")
]
}
}
}

单独的postcss配置文件

可以将这些配置信息放到一个单独的文件中进行管理

创建文件 postcss.config.js

1
2
3
4
5
module.exports = {
plugins: [
require('postcss-preset-env')
]
}

postcss-preset-env

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

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

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

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

    境添加所需的polyfill;

  • 也包括会自动帮助我们添加autoprefixer

  • npm install postcss-preset-env -D

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

1
2
3
4
5
module.exports = {
plugins: [
'postcss-preset-env'
]
}

比如在设置十六进制颜色时设置了八位 但是某些浏览器并不认识这种语法 所以我们把颜色转成rgba形式 但是autoprefixer 并不会帮我们转换 使用postcss-preset-env可以完成这样的功能

1
2
3
.content{
color: #12345678
}
css-loader的importLoaders属性
  • 当我们在index.css中使用@import引入另一个css文件test.css(index.css是被关联的css) 那么postcss-loader并不会对test.css进行处理
  • 这个时候使用css-loader的options中importLoaders属性 importLoaders属性的值取决后面有几个loader 设置了对应值以后就可以让 后面的loader在处理一次

加载和处理其他资源

file-loader

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

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

    文件夹中;

  • npm install file-loader -D

文件的名称规则

  • 有时候我们处理后的文件名称按照一定的规则进行显示:
    • 比如保留原来的文件名、扩展名,同时为了防止重复,包含一个hash值等;
  • 这个时候我们可以使用PlaceHolders来完成,webpack给我们提供了大量的PlaceHolders来显示不同的内容:
  • 常用的placeholder
    • [ext]: 处理文件的扩展名;
    • [name]:处理文件的名称;
    • [hash]:文件的内容,使用MD4的散列函数处理,生成的一个128位的hash值(32个十六进制)
    • [path]:文件相对于webpack配置文件的路径
  • 设置文件存放路径有两种方式
    • 一种是设置name时 直接img/[name]
    • 另一种是设置outputPath设置输出的文件夹

url-loader

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

显示结果是一样的,并且图片可以正常显示;

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

  • 因为小的图片转换base64之后可以和页面一起被请求,减少不必要的请求过程;
  • 而大的图片也进行转换,反而会影响页面的请求速度;

url-loader需要更多http请求

我们可以通过url-loader中 options属性limit 来设置转换的限制 100*1024 为100kb

asset module type

在webpack5版本中我们可以直接使用资源模块类型(asset module type)来替代之前我们加载资源时使用的loader,比如raw-loader 、url-loader、file-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的使用

1
2
test: /\.(png|jpe?g|gif|svg)$/,
type:"asset/resource", //file-loader的效果

当我们需要自定义文件的输出路径和文件名时 有两种方式

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

如果我们想要实现url-loader的limit效果

  • 步骤一:将type修改为asset;
  • 步骤二:添加一个parser属性,并且制定dataUrl的条件,添加maxSize属性;

加载字体文件

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

我们可以使用 file-loader 来进行处理 也可以直接使用 asset module type 来进行处理

1
2
3
4
5
6
7
{
test: /.ttf|eot|woff2?$/i,
type: "asset/resource",
generator: {
filename: "font/[name].[hash:6][ext]"
}
}