webpack修炼日记(二)——loader,让webpack不再“裸奔”

对于用惯了脚手架的开发人员来说,编写css样式,引入样式,再npm run serve/dev(以vue使用的脚手架为例),再到浏览器运行和调试代码就和喝水一样自然,根本不需要考虑,对吧?那如果要是告诉你,本来不是这样呢?你可能很奇怪“什么?我一直都是这样用,大家也是这样用,难道脚手架不是一直都可以让我们这样编写吗?”向来如此,便对吗? 我接下来要说的话,可能要让有的人要失望了。我在上一文里面提过,vue/react脚手架都是基于webpack的,但是有一个大部分人都不知道的事实就是,webpack对于除了js/json文件可以进行处理之外,其他后缀名的文件向来不是开箱即用——即使是最简单的css文件。是的,.jsx和.vue也不能用。这样又有疑问了,基于webpack的脚手架可以用,为什么webpack不能用了呢。对此,我要说的是,因为脚手架里面配置好了loader,才让基于webpack的它们,可以处理其他类型的文件。是的,loader,让webpack不再“裸奔”。


什么是loader

什么是loader,官方早已给出了答案。 **“loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块, 以供应用程序使用,以及被添加到依赖图中。”**说白了,加上loader之后,webpack就可以去处理其他类型的文件了,这样一来,webpack的可拓展性就很强了,这也是webapck可玩性体现之一。只要有相关的loader,那么在webpack中就可以对其进行配置然后处理相关文件。

**

缺少loader时的报错信息

在这里,使用css文件来示范没有对css对应的loader进行配置时,进行打包会怎样。

1.在打包入口文件(对入口文件不了解看这个)引入css文件,我这里任意编写了一些css,并且使用esm的方式引入。

import "./assets/index.css"
console.log("first")
复制代码

此时webapck的配置文件

const path = require("path")
module.exports={
    entry:{
        index:"./src/index.js", //index只需要打包的文件,后面指打包的文件所在位置
    },
    output:{
        path:path.resolve(__dirname,"./build"), //生成的文件夹叫做build文件夹
         filename:"bundle.js"  //生成的打包之后的js文件名称
    }
}
复制代码

2.之后使用打包命令对其进行打包,会发现报错信息如下: 在这里插入图片描述 意思很明确,你可能需要一个正确的loader去处理这个文件类型,所以我们需要添加对应的loader对css文件类型进行打包时的处理(这里以css为例),下面就来添加loader对其进行处理

对loader进行配置

1.在webpack.config.js中添加以下内容

const path = require("path")
module.exports={
    entry:{
        main:"./src/main.js", //index只需要打包的文件,后面指打包的文件所在位置
    },
    output:{
        path:path.resolve(__dirname,"./build"), //生成的文件夹叫做build文件夹
        filename:"bundle.js"  //生成的打包之后的js文件名称
    },
    module:{
        rules:[
           //rules中的每一项都是需要配置并且进行处理的文件类型
        ]
    }
}

复制代码

2.下载css-loader

3.在新建部分里面编写css的正则表达式以及对应需要使用到的loader,test选项代表匹配哪种文件,use表示使用哪种loader去处理这种文件,这里展示的use是简化写法,即不对loader有额外配置的时候使用这个方式引入loader

const path = require("path");
module.exports = {
  entry: {
    main: "./src/main.js", //index只需要打包的文件,后面指打包的文件所在位置
  },
  output: {
    path: path.resolve(__dirname, "./build"), //生成的文件夹叫做build文件夹
    filename: "bundle.js", //生成的打包之后的js文件名称
  },
  module: {
    rules: [
        {
            test: /\.css$/,
            use:['css-loader'],
         },
          /* 
          配置loader复杂的写法
           use: [
          {
            loader: 'css-loader',
            options: {
            	//这里写loader的配置对象
            },
          },
        ],*/
    ]
  },
};
复制代码

再次运行打包命令,发现打包完成,没报错

4.那么我们在打包输出之后的文件夹内新建index.html文件,引入刚刚打包之后的文件。并且添加一些内容来验证刚刚样式有没有生效

编写的html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    草新要蹦迪
    <script src="./bundle.js"></script>
</body>
</html>
复制代码
编写的css文件

这里将字体转换为红色

*{
    color: red;
}
复制代码

打开浏览器发现并没有效果,控制台里面也没有相关样式,这是因为css-loader只是加载 CSS 文件并解析 import 的 CSS 文件,并没有将css样式应用起来,要将css样式应用起来,需要再使用style-loader将模块导出的内容作为样式并添加到 DOM 中。 在这里插入图片描述 6.添加style-loader到webpack配置中,注意要将style-loader放在css-loader中,因为loader的执行顺序是从右往左。这里是先解析css文件再将css样式应用到dom节点中

const path = require("path");
module.exports = {
  entry: {
    main: "./src/main.js", //index只需要打包的文件,后面指打包的文件所在位置
  },
  output: {
    path: path.resolve(__dirname, "./build"), //生成的文件夹叫做build文件夹
    filename: "bundle.js", //生成的打包之后的js文件名称
  },
  module: {
    rules: [
        {
            test: /\.css$/,
            use:['style-loader','css-loader'],
         },
    ]
  },
};
复制代码

再次执行打包命令并且在浏览器上查看index.html,发现样式应用上去了,但是是加在style标签内,如何让css样式文件分离,后续章节会提到 在这里插入图片描述 这样,我们在编写代码的时候就可以像引入js文件一样引入css文件了!请记住,无论是脚手架还是webpack,如果没有配置对应的loader,那就是不能处理对应的文件,之所以脚手架对css文件开箱即用,是因为它们帮你配置好了,配置好,并不是与生俱来。

处理其他类型文件

这里再演示一下对图片资源的处理,webpack 5 中,可以使用内置的 Asset Modules对图片等静态资源处理,因此不需要下载对应的loader 1.首先得要有一张图片显示在网站上,因此需要修改打包入口文件,将图片以js的形式显示,在这将其设置为背景

import "./assets/index.css"
import imgSrc from "./assets/image/珠穆朗玛峰.jpg"
const divEl = document.createElement('div');
divEl.textContent = "Hello"
divEl.classList.add("content") //加上类名
document.body.appendChild(divEl)
// 再添加一个div,其样式使用loader来编写
const title = document.createElement("h2")
title.textContent="title"
document.body.appendChild(title)
title.classList.add("title")
const Img = document.createElement("img")
Img.src = imgSrc 
document.body.appendChild(Img)
const divBg = document.createElement("div")
document.body.appendChild(divBg)
divBg.classList.add("imgBg")
复制代码

2.对其进行配置,这时候需要注意type的设置问题,关于type,这有几点需要说明

aseet/resource:生成独立文件,打包之后的图片不会包含在js里面,js代码量减少,会再次请求两次网络请求去请求图片。

asset/inline:不会生成独立文件,打包之后的图片会在js里面,但是少了对图片的网络请求

综合优点: 直接设置asset文件,但是对于不同文件大小进行不同处理但是要对图片的大小进行划分,以达到更好的打包效果 这里主要是对图片资源的打包,其他资源也是大同小异,大家可以去webpack官网查看其他的资源类型,比如字体,svg资源等。

  {
  //在rules里面添加以下内容
                test: /\.(png|gif|jpe?g)$/,
                type: "asset",
                parser: {
                    dataUrlCondition: {
                        maxSize: 60 * 1024 //对于超过这个尺寸的图片单独打包成一个文件
                        //还有其他属性大家可以自行去官网上查看
                    }
                },
                generator: { //这里设置生成之后的图片
                    // 使用占位符来对生成图片名字来重新设置
                    // name:以前图片的名称
                    // ext:以前资源的后缀名
                    // hash:生成的hash值,可选择截取几位
                    filename: "img/[name][hash:8][ext]" //可以添加前缀来生成新的文件夹
                }
            },
复制代码

3.查看打包之后的效果,可以发现webpack已经可以处理图片了!如果还需要对其他类型资源文件打包,可以下载其他类型资源相对应的loader,配置方式都是差不多。 在这里插入图片描述

总结

没想到吧,webpack只能打包js和json文件,对其它类型的文件从来都不是开箱即用的,当没有配置任何loader的时候,它就是“裸奔”状态,但是这就是webpack强大的原因之一,我们可以让他帮我们做什么,而不是它让我们去做什么,这样webpack的可拓展性大大提升了,如果想搭建jsx或者vue的loader,那简直是手拿把掐,是不是感觉脚手架也没有那么远了呢~

猜你喜欢

转载自juejin.im/post/7222210580319387707
今日推荐