大声对webpack4.0说声你好之loader基础篇资源打包讲解(二)

导读

哈哈哈,它踏着轻快的步伐来啦。 若是你尚未看过个人《 大声对webpack4.0说声你好之webpack的基本使用(一)》,建议您先大体浏览,由于我会接着上一节的代码继续记笔记。css

本篇你将会对loader有个初步认识,还会对一些经常使用的静态资源打包,例如图片、样式、字体等,若是你想学习更多关于loader的知识点和其余的,记得关注我,我将会尽快更新。html


思考到你们可能以为阅读文章有些许枯燥,而后我决定将代码放到github-webpack上面,代码里面使用webpack的地方,我也写了详细的注释,若是有用请记得✨,有问题能够及时交流。vue

若是你是webpack的初学者,那么你跟着个人代码,手动的敲打一下键盘,相信你也能和我同样快速步入webpack的神圣殿堂。由于我会将全部的笔记都作得很是很是仔细,让你在运行的过程当中不受任何阻拦。node

loader

为了完全的搞懂什么是loader,咱们先来作一个小练习,经过它来认识咱们的loader。webpack

打包图片练练手

webpack号称能够对文件进行打包,咱们第一部分彻底是对js文件进行打包,那么咱们能不能对图片进行打包呢?css3

首页先根目录下新建文件夹statics做为个人资源文件夹,git

1. 准备资源
mkdir statics // 新建静态资源文件夹
// 拷贝一个shu.jpg的图片

2.图片资源引入到index.js中
//index.js
var avator = require('../statics/images/shu.jpg')

3.使用webpack打包
npx webpack
复制代码

顺利的就遇到了问题,打包出现了问题github

ERROR in ./statics/images/shu.jpg 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
(Source code omitted for this binary file)
 @ ./src/index.js 5:13-49
复制代码

webpack是默认支持js文件的打包的,可是遇到了图片文件的打包,他并不知道怎么办,因此咱们须要修改配置文件来告诉webpack在模块打包的时候应该怎么办。web

// webpack.config.js
module: { // 模块打包配置
    rules: [ // 新增规则 能够有不少,数组
      {
        test: /\.jpg$/, // 检测文件是jpg结尾的
        use: { 
          loader: 'file-loader'
        }
      }
    ]
  },
复制代码

咱们会使用到loader,可是咱们并无安装这个loader,因此在执行以前咱们还会使用npm进行安装chrome

npm install file-loader -D

npx webpack

Entrypoint main = main.js
[0] ./src/index.js 198 bytes {0} [built]
[1] ./src/header.js 325 bytes {0} [built]
[2] ./src/slider.js 325 bytes {0} [built]
[3] ./src/footer.js 326 bytes {0} [built]
[4] ./statics/images/shu.jpg 80 bytes {0} [built]
复制代码

这样就多了一个图片文件,咱们打开就是咱们本身的shu.jpg的内容。

在这里咱们使用了一个loader,名称叫file-loader,那么咱们又是怎么知道 file-loader是能够打包这个图片资源的呢?

文档地址

webpack中文文档

webpack-loader文档

咱们只有阅读官方文档后,才能更好的选取本身所用的loader。如今咱们来看看loader究竟是什么?

loader是什么?

官方定义:webpack 可使用 loader 来预处理文件。

实际上,loader就是咱们打包文件的一种方式

再看打包图片

让咱们再来看看这个打包图片的例子,由于我准备把代码上传至github,可是每一个人可能看到的文章系列不一样,因此我从新新建一个js文件。

// src目录下新建loader-img.js dist目录下新建loader-img.html

// loader-img.js 使用import...from 方式引入
import avator from '../statics/images/aa.jpeg'

var img = new Image
img.src = avator
var root = document.getElementById('root')
root.append(img)

// loader-img.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>打包图片文件</title>
</head>
<body>
  <div id="root"></div>
</body>
<script src="./main.js"></script>
</html>

// 配置webpack.config.js
module: { // 模块打包配置
    rules: [ // 新增规则 能够有不少,数组
      {
        test: /\.(jpg|jpeg)$/, // 检测文件是jpg或者jpeg结尾的
        use: { 
          loader: 'file-loader'
        }
      }
    ]
  },

// 打包loader-img.js
npx webpack src/loader-img.js

复制代码

ok,打包完成,这样咱们就能够直接在咱们的loader-img.html预览图片,获得了咱们的效果。

使用loader打包vue文件

在vue的官网右上角,有个生态系统,咱们能够看到是给咱们提供了一个生态系统的,里面就有一个vue loader。 这个时候若是咱们要配置本身的vue打包文件的话,就能够直接使用vue loader打包。

// 咱们直接在modulues中新加入一条规则便可
module: { // 模块打包配置
    rules: [ // 新增规则 能够有不少,数组
      {
        test: /\.(jpg|jpeg)$/, // 检测文件是jpg/jpeg结尾的
        use: { 
          loader: 'file-loader'
        }
      },
      {
        test: /\.vue$/, // 检测文件是vue结尾的
        use: {
          loader: 'vue-loader'
        }
      }
    ]
  },
复制代码

前提是你须要本身先提早安装vue loader这个依赖。

经过几个详细的例子下来,相信你对webpack中的loader有了必定的了解。

使用loader打包静态资源

OPTIONS参数

资源自定义名称

像刚才咱们打包的图片都是一些静态资源,可是咱们还能够更深层次的来看看咱们的loader对静态资源的处理,好比,我如今想上传一个图片,可是我但愿他的名字不改变,这个时候应该怎么作呢?

use: { 
  loader: 'file-loader',
  options: {
    name: '[name].[ext]'
  }
},
复制代码

这个操做咱们称为placeholder 占位符 [name]: 文件名 [hash]: 打包文件的hash值(若是不清楚,请看系列一有详解) [ext]: 文件后缀 [path]: 路径等等

npx webpack laoder-img.js
复制代码

就会帮助咱们打包一个aa.jpeg的图片,咱们还可使用hash值去拼接name

name: '[name]_[hash].[ext]'
复制代码

这样就OK了。

打包到某个路径

若是咱们想打包文件到某个文件夹,咱们直接可使用outputPath属性,若是你还要其余打包操做能够直接去官网查询。

outputPath: '/images'
复制代码
limit

其实咱们还可使用url-loader来打包,它会直接帮咱们打包成base64格式。

若是咱们直接打包成base64的话,咱们就会少一个图片加载,这样就会节约一次http请求,可是,若是咱们的文件过大,他就会转成不少的代码,js文件就会变得相对过大,因此咱们就能够判断图片20k之内咱们就使用url-loader打包,这个具体的实现思路又是怎么样的呢?

首先咱们先安装url-loader

npm install url-loader -D
复制代码

判断大小使用limit参数

// options 参数
limit: 1024 * 20
复制代码

这样就会判断图片是否大于20kb,若是超过就会像file-loader同样将文件打包到dist的images文件夹下,否则的话就会直接将图片转成base64格式打包进咱们的js文件中。

打包样式文件

打包css文件

webpack默认只支持js文件的打包,因此不用想咱们先安装css-loader。

npm install css-loader style-loader -D
复制代码

而后咱们新增css文件来修饰咱们的img

// index.css
.avatar{
  width: 100px;
  height: 100px;
}

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>css-loader,style-loader,url-loader</title>
</head>
<body>
  <div id="root"></div>
</body>
<script src="./main.js"></script>
</html>

// css.js
import avatar from '../statics/images/aa.jpeg'
import '../statics/style/index.css'

var img = new Image
img.src = avatar
img.classList.add('avatar')
var root = document.getElementById('root')
root.append(img)
复制代码

咱们就能够直接打包了,咱们还能够一个css文件经过@import 'xx.css',这种方式来引入另外一个css,这里我就很少作演示了。

打包scss文件等

官网提示,若是你想使用scss,那么就必须安装sass-loader、node-sass这两个包

// 安装loader
npm install sass-loader node-sass -D

// 修改配置
{
    test: /\.scss$/, // 检测文件是scss结尾的
    use: ['style-loader','css-loader','sass-loader']
},

// statics/style/index.scss
#root{
  .avatar{
    width: 100px;
    height: 100px;
  }
}

// css.js
// import '../statics/style/index.css'
import '../statics/style/index.scss'

// 打包
npx webpack src/css.js

复制代码

最后打开咱们的laoder-img.html就能够直观的看到咱们的样式生效了。

注意在loader中他是从下到上,从右到左的一个执行过程,因此咱们在打包scss文件的时候,他会先执行sass-loader,将咱们的代码转成css后再交到css-loader,最后再给咱们的style-loader挂载到页面上。

ok,那咱们接下来在来升级一下咱们的打包流程。

咱们在样式中修改一下咱们的代码,我想让个人图片进行偏移,因此咱们在样式中加上以下代码

transform: translate(100px,100px);
复制代码

而后咱们在进行打包。图片按照咱们理想的行为作出了偏移,咱们一块儿来看看浏览器代码。

如指望,可是在css3中,咱们遇到浏览器的兼容问题以后,咱们会手写不少-webkit-等等诸多的前缀,若是如此写下去的话,不得不说是一件十分使人头疼的事情。

其实也有不少的loader为咱们提供了这样的自动添加前缀的功能。

打包c3自动加前缀

1.安装 postcss-loader

// 下载postcss-loader autoprefixer插件
npm install postcss-loader -D
复制代码

2.在根目录下新建postcss.config.js

module.exports = {
  plugins: [ // 使用插件
    require('autoprefixer')({ overrideBrowserslist: ['last 15 versions'] })
  ]
}
复制代码

3.修改webpack.config.js

{
    test: /\.scss$/, // 检测文件是vue结尾的
    use: ['style-loader','css-loader','sass-loader','postcss-loader']
},
复制代码

ok,咱们来进行一次梳理。

  • 咱们在打包scss文件的时候,首先会使用postcss-loader
  • postcss-loader会去招到postcss的配置项
  • 在配置项里面发现使用了autoprefixer插件给咱们自动加前缀
  • 而后处理scss文件转成css交到css-loader
  • 最后经过style-loader挂载到咱们的页面中

这里有一个新的知识点,pulgin-插件,这个暂时能够知道这么使用,由于我会在后面的系列中单独讲到这个核心概念。

({ overrideBrowserslist: ['last 15 versions'] }) 这个是我本身加上去的。

ok,咱们再次打包以后,来看看咱们的页面中已经为咱们自动生成了前缀。

样式篇补充

首先咱们来假设这样一个场景

  1. 我如今在css.js中引入index.scss
  2. 而后在index.scss中@import './other.scss'

在打包过程当中,他先走postcss-loader,而后走sass-loader,但在遇到@import其余scss文件的时候可能就不会从新走postcss-loader,sass-loader了,那这个时候咱们又应该怎么办呢?

// importLoaders 
use: [
  'style-loader',
  {
    loader: 'css-loader',
    options: {
      importLoaders : 2 // 经过import引入的scss文件,也要走下面两个loader
    }
  },
  'sass-loader',
  'postcss-loader'
]
复制代码

这样就能保证不管是在scss中仍是页面中import的scss文件,都会从新顺序执行loader.

模块化打包

咱们在dist目录下新建m.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>模块化打包</title>
</head>
<body>
  <div id="root"></div>
</body>
<script src="./main.js"></script>
</html>
复制代码

在src下新建m1.js/m2.js

// m1.js
import avatar from '../statics/images/aa.jpeg'
import createAvatar from './m2'
import '../statics/style/index.scss'

createAvatar()

var img = new Image
img.src = avatar
img.classList.add('avatar')
var root = document.getElementById('root')
root.append(img)

// m2.js
import avatar from '../statics/images/aa.jpeg'

export default function createAvatar(){
  var img = new Image
  img.src = avatar
  img.classList.add('avatar')
  var root = document.getElementById('root')
  root.append(img)  
}
复制代码

m2中有一个方法建立图片,那么咱们每次调用一次就会建立一个图片,而后在m1中引入了index.scss样式。这样的话,m1的样式文件就会做用于我当前引入的页面标签,还会做用于m2我本身封装的建立函数中,因此这样引入的方式,样式至关因而全局的。

css打包模块化概念

若是描述咱们的代码就会变得很糟糕,因此咱们须要开启css打包的模块化概念

在webpack.config.js中开启css的模块化打包

modules: true
复制代码

而后咱们还会在引入方式中作出改变。

// m1.js
import style from  '../statics/style/m.scss'

img.classList.add(style.avatar)

// m.scss
.avatar{
  width: 100px;
  height: 100px;
}
复制代码

在打包就不会出现刚才的问题,这个时候就以后m1中图片的样式生效了。这样就只会有一个图片样式生效。

若是你想要在建立的文件里也生效。那么用一样的方式处理便可。

打包字体文件

字体图标库在近几年的网站中运用的已经愈来愈普遍了。因此在不少项目中都会用到一些图标来装饰咱们的网站,其中阿里图标库就作的至关不错。

  1. 咱们随便的选取一些下载至本地。而后运用到咱们的项目当中。而后在statics中新建fonts文件夹,讲字体文件所有放进去。

  2. 新建font.scss,将下载的iconfont.css内容拷贝进去,需注意文件路径

@font-face {font-family: "iconfont";
  src: url('../fonts/iconfont.eot?t=1590298271844'); /* IE9 */
  src: url('../fonts/iconfont.eot?t=1590298271844#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
  url('../fonts/iconfont.woff?t=1590298271844') format('woff'),
  url('../fonts/iconfont.ttf?t=1590298271844') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
  url('../fonts/iconfont.svg?t=1590298271844#iconfont') format('svg'); /* iOS 4.1- */
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-biaoqing:before {
  content: "\e63d";
}

.icon-biaoqing1:before {
  content: "\e650";
}

.icon-biaoqing2:before {
  content: "\e62d";
}
复制代码
  1. 新建font.html/font.js
import '../statics/style/font.scss'

var root = document.getElementById('root')
root.innerHTML = '<div class="iconfont icon-biaoqing"></div>'
复制代码

这个时候都不用想,引入样式而后进去会找到字体文件,打包确定失败,因此咱们会继续进行配置字体文件的打包。

// 取消scss的模块化打包
// modules: true

// 利用file-loader将个人字体文件打包,并放在fonts目录下
{
    test: /\.(eot|svg|ttf|woff|woff2)$/, // 检测文件是vue结尾的
    use: {
      loader : 'file-loader',
      options: {
        outputPath: '/fonts/'
      }
    }
  },
复制代码

ok,这样就能够完美的运行了。

总结

loader咱们的入门已经差很少了,回顾一下本节内容。

  1. 打包图片资源
  2. 打包css文件
  3. 打包scss文件,并@import打包,自动加前缀
  4. loader基本知识以及配置项讲解 输出路径等
  5. 字体打包等练习。

这里为你们推荐官方的打包讲解,以及对数据之类的打包方案等。webpack资源管理

若是这篇文章对您有帮助,还请为个人努力点个赞,下一节咱们将会认识webapck的插件(plugin)。

相关文章
相关标签/搜索