03_loader

目标:

  • 能处理css,less文件,解决css的浏览器兼容性配置
  • 能处理字体文件
  • 能处理图片文件
  • 能处理js降级问题

在webpack看来 一切皆模块,图片,样式文件,js文件… 。 但是webpack默认只能处理js模块,对于非js的内容它就需要一些帮手来处理了。这些帮手就是loader

webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。

处理css文件

下面,我们来讨论如何处理.css文件。

创建.css文件

在src目录下,再次创建一个css目录

|-src
|-src/css
|--------public.css
|--------style.css

src/css/public.css的内容如下

body,html{
  padding:0;
  font-size:14px;
}

src/css/style.css的内容如下

@import "public.css";
div {
  border:4px solid #ccc;
  width: 50%;
  height: 200px;
  margin:30px auto;
  box-shadow: 3px 3px 3px #ccc;
  background-color: #fff;
  text-align: center;
}

说明:

  • @import语句用来导入另一个css文件。

如果希望在.html文件中使用style.css样式,我们以前只学习过一种方式:直接在.html中通过link的方式来引入 。

那如果在js中引入了css会怎么样呢?

在.js中导入css

下面,我们修改自已的main.js,在 src/js/main.js中,引入css。

// nodejs中的模块化
const { updateDom } = require('./tool')

+ import '../css/style.css'
updateDom ('app','index.html')
log('test')

再次,打包代码,会报错。

ERROR in ./src/css/style.css 1:0
Module parse failed: Unexpected character '@' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> @import "public.css";
| div {
|   padding:20px;
 @ ./src/js/main.js 4:0-26

上面报错的原因是:webpack把.css文件内容当作了js代码来运行,那当然会报错了。所以,解决方法是安装相应的loader来处理。

安装并使用css-loader

对于所有的loader的使用,其基本步骤是一致的,分成两步:

    1. 安装loader包
    1. 配置webpack.config.js中的module
安装
npm i css-loader -D
--------------------
+ css-loader@4.1.1
added 16 packages from 51 contributors in 14.718s

7 packages are looking for funding

它也是开发依赖。

在配置文件中使用

修改webpack.config.js文件,添加modules

const path = require('path')
module.exports = {
  mode: 'development',
  entry:'./src/js/main.js',
  output:{
    path:path.resolve(__dirname, './build'),
    filename:'bundle.js'
  },
+  module:{ // 处理非js模块
+    rules:[ // 规则
+      {
+        test: /\.css$/, 		// 正则测试
+        use: ['css-loader'] 	// loader
+      }
+    ]
+  }
}
再次打包

它不会报错。但是,页面上也并没有出现样式的效果。打包之后的文件中并没有包含css代码。

安装并使用style-loader

如果我们希望样式生效,最终在.html文件中有两种情况:

  • 有style标签
  • 有link标签

而css-loader只是能让你在.js中通过import来引入.css,如果你希望引入的css代码最终以style标签的方式插入到html页面中,则还需要安装一个loader:style-loader

安装
npm i style-loader -D 
---------------
+ style-loader@1.2.1
added 4 packages from 6 contributors in 13.086s

8 packages are looking for funding
  run `npm fund` for details
配置
// node 中的核心模块
const path = require('path')
// __dirname: 全局变量,指向当前目录绝对地址
// console.log(__dirname)
// // path.join是拼接
// console.log( path.join(__dirname, 'dist123') )

// 1. 导出一个配置
// 2. mode, entry, output...... 都是webpack这个工具约定的配置名称
// 每一项都有自己的作用
// 3. 学习webpack 就是学习webpac.config.js中的配置项的使用方式
module.exports = {
  // mode: 'production',
  mode: 'development',
  // devtool: 'source-map',
  // devtool: 'inline-source-map',
  // 入口
  // 默认入口:src/index.js
  entry: './src/js/index.js',
  // 出口
  // 默认出口: dist/main.js
  output: {
    filename: 'main.js',
    // path: 必须是一个绝对路径
    path: path.join(__dirname, 'build')
  },
  module: {
    rules: [
      // 每一个对象就是一条规则.
      //  test: 匹配
      //  use: 对匹配到的模块采用对应的loader
      {
        test: /\.css$/, // 正则匹配 .css文件
        // 匹配成功后(从后向前;从右到左)
        // 1. 先用css-loader去加载.css文件
        // 2. 再用style-loader把样式以style标签的方式嵌入到html中 
        use: ['style-loader', 'css-loader']
      }
    ]
  }
}

Tip: 在有多个loader的情况下,use数组中的loader执行顺序是从右到左的过程。即:

  • 先用css-loader来处理css
  • 再用style-loader把css代码插入到html中的style标签中。
打包查看效果

index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <!-- <link rel="stylesheet" href="./css/style.css"> -->
  </head>
  <body>
    <div id="app">
      
    </div>
    <!-- 引入两个js文件 -->
    <!-- <script src="./index.js"></script>
    <script src="./tool.js"></script> -->

    <!-- 引入打包之后的js -->
    <script src="../build/main.js"></script>
</body>
</html>

现在就能看到css的效果了 。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CyA3T8Jn-1603365751269)(asset/image-20200731143422794.png)]

原理是:

  • bundle.js中有一些js代码,它在运行时,会自动在.html文件中追加style标签,并输出样式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uF2nJvhN-1603365751271)(asset/image-20200603143508746.png)]

拓展

你可以分析打包之后代码,来验证style-loader的工作原理。在main.js中,可以找到类似如下的代码:

eval("var api = __webpack_require__(/*! ../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js

再去node_modules\style-loader\dist\runtime\injectStylesIntoStyleTag.js 找下insertStyleElement这个方法,你就可以发现这个过程。

loader使用小结

  • 在webpack看来,一切皆模块: 每一个文件都是一个模块。

  • webpack默认只能处理json和js模块,对于其它的模块它需要对应的loader来处理

  • loader的基本使用是:

    • 安装Loader (npm 包)
    • 配置module中的rules:用loader来处理对应类型的文件

处理less文件

目标:在项目中支持使用less来写css代码。

改进案例

创建less文件

在src目录的css目录下创建 index.less,则内容如下:

@import "style.css";

body{
  div {
    padding:50px;
  }
}
在.js中引用.less

在src/js/main.js文件中引入less

// nodejs中的模块化
const { updateDom } = require('./tool')
// es6中的模块化
import {log} from './tooles6'

- import '../css/style.css'
+ import '../css/index.less'
updateDom ('app','index.html')
log('test')

安装并配置loader包

less less-loader

参考官网

npm i less-loader less -D
-------------------------
+ less@3.11.2
+ less-loader@6.1.0
added 50 packages from 123 contributors in 23.883s
  • less 用来把less–>css
  • less-loader用来加载less文件。
配置模块

在rules中添加一个配置,专门针对less文件。

/**
 1. 要放在项目的根目录下。
 2. 在npx webpack打包时,会自动去找这个文件,并运行其中的
    代码。如果找不到,则进入零配置模式 ---- 采用一些默认配置。
*/
// nodejs中一个核心模板

console.log('打包文件....')
const path = require('path') 
module.exports = {
  // mode: 'development',
  mode: 'production',
  devtool: 'cheap-module-source-map',
  entry: './src/js/main.js', // 入口
  output: {
    // 拼接一个绝对路由
    path: path.join(__dirname, './build'),
    filename: 'bundle.js'
  },
  // 非js模块要如何处理? 在module中定义
  module: {
    // 规则
    rules: [
      {
        test: /\.css$/,  // 如果这个模块以css结尾
        // 如果在打包的过程遇到了.css,则:
        // 1. 先用css-loader读出内容
        // 2. style-loader把读出的内容以style标签的格式
        // 附加在.html文件上
        use: ['style-loader', 'css-loader'] // 设置要处理的loader
      },
      {
        test: /\.less$/,  // 如果这个模块以less结尾
        // 如果在打包的过程遇到了.less,则:从右向左
        // 1. 先用less-loader 读出内容,转成css
        // 2. 用css-loader 读出内容
        // 3. style-loader把读出的内容以style标签的格式
        // 附加在.html文件上
        use: ['style-loader','css-loader', 'less-loader'] // 设置要处理的loader
      }
    ]
  }
}

注意:如上配置中,对于less文件的处理涉及三个loader,其处理顺序是less-loader --> css-loader–>style-loader。

  • less-loader:用来加载less文件,并处理成css
  • css-loader:用来加载css文件
  • style-loader:用来将css代码以style标签的格式插入到html文件中

自动添加css样式前缀

目标:通过postcss及相关工具来处理兼容性问题—自动添加样式前缀

步骤

  1. 安装依赖

  2. 补充loader

  3. 单独设置postcss

安装依赖

npm i postcss postcss-loader autoprefixer -D

补充loader

{
        test: /\.less$/,
        // 匹配成功后(从后向前;从右到左)
        // 1. 先用less-loader去加载.less文件,转成css
        // 2. 用postcss-loader配合autoprofixer加浏览器前缀
        // 3. 先用css-loader去加载css文件
        // 4. 再用style-loader把样式以style标签的方式嵌入到html中 
        use:['style-loader', 'css-loader', 'postcss-loader',  'less-loader']
      }

单独设置 postcss.config.js

const autoprefixer = require('autoprefixer')
module.exports = {
  plugins:[
    autoprefixer({
      // last 2 versions : 浏览器最近的2版本
      // >1% 全球市场占有率在1%以上的浏览器
      // overrideBrowserslist: ['last 2 versions', '> 1%']
    })
  ]
}

默认是兼容所有最新版本

例子说明
> 1%全球超过1%人使用的浏览器
> 5% in US指定国家使用率覆盖
last 2 versions所有浏览器兼容到最后两个版本根据CanIUse.com追踪的版本
Firefox ESR火狐最新版本
Firefox > 20指定浏览器的版本范围
not ie <=8方向排除部分版本
Firefox 12.1指定浏览器的兼容到指定版本
unreleased versions所有浏览器的beta测试版本
unreleased Chrome versions指定浏览器的测试版本
since 20132013年之后发布的所有版本

特别地:对于要支持的浏览器的设置,也可以写在package.json中

{
  // ......
  "browserslist": "ie 10"
}

如果只支持ie 10 ,则flex只会加-ms-前缀

查看当前支持的浏览器的列表npx browserslist

file-loader-处理字体文件

目标:在项目中支持字体文件

步骤:

在src中添加字体文件及对应的css

-src
----/css
--------iconfont.css
----/fonts
--------iconfont.woff

在index.html中引用

<div id="app"></div>
<span class="icon-book iconfont"></span>

安装loader

npm i file-loader -D

配置文件

{
        test:/\.woff$/,
        use:{
          loader: 'file-loader',
          options: {
            // [name]: 这里[]表示里面放一个占位符。name就是要处理的文件名
            // [ext]:  这里[]表示里面放一个占位符。ext就是要处理的文件后缀名
            name: '[name].[ext]',
            outputPath: './fonts'
          }
        }
      }

file-loader的作用就是拷贝

url-loader处理图片

参考链接:npm官网

目标:在项目中支持对图片的处理:如果足够小就直接生成对应的base64编码值,否则就直接拷贝到制定位置。

修改代码

提前准备图片
  • src下新增目录:img,并在其下放置两张图片:一张图片大一些,一张图片小一些(可以自己找图片)。
    • webpack.png: 49.4kb
    • webpack.svg: 3kb
在css中引入图片
  • 在style.css中引入图片,作为div标签的background。
@import "public.css";
div {
  border:4px solid #ccc;
  width: 50%;
  height: 200px;
  margin:30px auto;
  box-shadow: 3px 3px 3px #ccc;
  background-color:pink;
  text-align: center;
+  background-image: url('../img/webpack.png')
}
body {
+  background-image: url('../img/webpack.svg')
}

直接打包,会报错。报错的原因是.svg, .png格式的文件webpack并不能直接处理。

把上面的配置文件中的file-loader直接改成url-loader,就会实现拷贝的功能。

增强版的file-loader —> url-loader

npm i url-loader -D
      {
        test: /\.(png|svg|jpg)$/, // jpg
        use: {
          loader: 'url-loader',
          // url-loader是增强版的file-loader
          // 如果图片小于指定的大小,则会转成base64,否则就调用file-loader进行拷贝
          options: {
            limit: 3*1024, // 如果图片小于3k就转成base64,否则就直接拷贝
            name: '[name].[ext]',
            outputPath: './img'
          }
        }
      }

使用babel-loader处理js降级问题

能够把es6高级内容变为es5的loader名称为 babel-loader

es6/es7/es8等等高级标准有很多(let、箭头函数、对象解构赋值、…展开运算符、字符串模板等等),每个标准都需要一个独立的plugin进行降级处理,如果使用许多高级标准内容,那么势必要为此安装许多plugin,这样工作比较繁琐,系统已经考虑到这点了,其通过preset把许多常用的plugin给做了集合,因此一般性的使用只需要安装preset即可搞定(如果项目应用到了一个生僻的高级标准内容,preset处理不来,就还需要再安装对应的plugin处理)

npm官网: babel-loader

babel官网:https://www.babeljs.cn/setup#installation

步骤:

  1. 安装依赖包

    npm i babel-loader @babel/core @babel/preset-env -D
    
  2. 在webpack.config.js中做如下配置:

    {
        test: /\.js$/,
        exclude: /node_modules/,  // 排除目录
        use: [
            {
                loader:'babel-loader',
                options: {
                  presets: ['@babel/preset-env']
                }
             }
        ]
      // es6转es5
    }
    

    说明: @babel/preset-env用来指定按什么样的预设来进行降级处理

  3. 打包测试

    打包之后,去打包后的文件中检查是否已经把const和箭头函数这种es6的代码转成了es5的代码。

小结

  • 一切皆模块,非js模块有对应的loader来处理
  • loader使用的基本步骤
    • 第一步:安装包
      cn/setup#installation

步骤:

  1. 安装依赖包

    npm i babel-loader @babel/core @babel/preset-env -D
    
  2. 在webpack.config.js中做如下配置:

    {
        test: /\.js$/,
        exclude: /node_modules/,  // 排除目录
        use: [
            {
                loader:'babel-loader',
                options: {
                  presets: ['@babel/preset-env']
                }
             }
        ]
      // es6转es5
    }
    

    说明: @babel/preset-env用来指定按什么样的预设来进行降级处理

  3. 打包测试

    打包之后,去打包后的文件中检查是否已经把const和箭头函数这种es6的代码转成了es5的代码。

小结

  • 一切皆模块,非js模块有对应的loader来处理
  • loader使用的基本步骤
    • 第一步:安装包
    • 第二步:配置rules
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值