1
本篇文章为webpack系列文章的第二篇,如果你对webpack一点都不了解,希望你在看本篇文章之前先看一下往期文章。

如何使用webpack实现模块化打包【1】

webpack的思想就是万物皆模块,这里的模块不仅仅只是JavaScript文件,它还可以是一个文件、一张图片、一个css样式表等资源。如果我们把这些内容全部在index.html中引入,那整个项目的代码看起来满篇都是引入的外部资源,自己都无法区分。模块化的思想可以是把某个功能设计为一个模块,我们可以把与这个模块相关的其他资源,只在这个模块中引入,这样做可以大大的提高后期的可维护性。
但是webpack无法直接识别非JavaScript脚本文件。不过webpack提供了另外一个强大之处,使其可以打包任何类型的资源文件,这就是webpack的loader机制。

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!
老规矩,直接接个例子来讲解

新建index.js和base.css文件,在base.css中写一些基本样式
div {    background: pink;    text-align: center;    border-radius: 10px;}
在index.js中引入base.css
import base.css
console.log('Hello webpack loader')
在webpack.config.js中进行基本的打包配置
module.exports = {
    mode: 'none',
    entry: './src/index.js',
    output: {
        filename: 'index.js',
    },
 }

开始打包npx webpack

在控制台可以看到报错了,大概的意思是说你需要一个适当的加载器来处理这个类型的文件,目前没有配置加载器来处理此文件。这里的加载器就是我们所需要的loader,现在我们在JS中引入了一个CSS文件,上面已经提到过,webpack只能识别JavaScript语言,因此这里我们需要对CSS进行转换为JavaScript,这个转换的过程当然不需要们自己起手动的编写,目前已经很多现成的加载器,我们只需要使用npm安装即可使用。
对CSS进行处理所需要用到的是css-loader,那我们就先来安装

npm install css-loader --save

安装后我们需要告诉webpack,遇到CSS样式文件时就需要使用css-loader进行转换,这就需要在webpack.config.js中配置,在module属性中的rules中进行配置,rules是一个数组,因为我们可能会遇到各种类型的文件,对用不同类型的文件就要使用不同的loader进行转换。每一项都包含test和use属性。
test指的是匹配什么文件,是一个正则表达式
use表示使用什么加载器来转换

module.exports = {
    mode: 'none',
    entry: './src/index.js',
    output: {
        filename: 'index.js',
    },
    module:{
        rules:[
            {
                test: /\.css$/,
                use: 'css-loader'
            }
        ]
    }
}

熟练的再次打包

nice,so easy
兴奋的新建一个html引入打包后的index.js测试

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webpack-loader</title>
</head>
<body>
    <div>
        <h2>webpack-loader</h2>
    </div>
    <script src="./dist/index.js"></script>
</body>
</html>

用我的Chrome浏览器打开看看效果

并没有任何样式效果,这是由于css-loader只是把CSS模块加载到JavaScript中,但是并没有使用这个模块。那如何让它被使用呢,只需要在css-loader的基础上再使用style-loader即可,style-loader可以将转换后的结果通过style标签追加到页面中。
npm install style-loader --save
这一步是在css-loader转换后进行,正确的配置方法如下

{
    test: /\.css$/,
    use: [
        'style-loader',
        'css-loader'
    ]
}

use可以接受一个数组,对匹配的文件会经过数组中的每一个loader进行转换,这里要注意一点,转换是有顺序的,从数组的最后往前进行,因此这里的style-loader应该在css-loader的前面。
重新打包,就可以看到我们想要的效果啦

我们也可以来编写自己loader,其实loader的本质就是将接收的内容转换为另一种内容的过程,简单的说就是接收一个值,我处理后再返回给你。

1587692379(1).jpg
我们知道了它的原理后,再来实现思路就很清晰了。我们经常会遇到md文件,md文件中采用的markdown语法,现在我写博客也开始使用markdown来写。如果直接将md文件引入页面中,必然是无法显示的,我们需要将它转化为html文本才行。
新建一个blog.md文件

## 这是我自己写的一个loader
**你能看到我,全靠loader的公功劳。**

欢迎访问[我的网站](www.dengzhanyong.com)
` ` `
console.log('hello webpack')
` ` `

然后在index.js中引入,并插入到body中显示

import blog from  './blog.md'
var node = document.createElement('div')
node.innerHTML = blog
document.body.append(node)

使用webpack进行打包

控制台报错,这是我们意料之中的,因为webpack无法识别md文件。
新建一个md-loader.js文件,这就是我们自己的loader。

const marked = require('marked')
module.exports = source =>{
    var html = marked(source)
    return html
}

它接收一个source,这就是接收的文件内容,这里我们需要用到一个第三方的包marked,他可以将md文本转为html文本,最后返回处理后的结果。
在webpack.config.js中进行配置,这里有两点需要注意
use可以使用本地的loader
转换后的html文本需要经过html-loader再次处理
html-loader应放在./md-loader的前面,也就是后执行

{
    test: /\.md$/,
    use: [
        'html-loader',
        './md-loader',
    ]
}


现在就可以在页面中看到md文件编译后的内容了。
1587693430(1).jpg

上面只是对loader的简单应用,它还具有以下特性:

  • loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。
  • loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
  • loader 可以是同步的,也可以是异步的。
  • loader 运行在 Node.js 中,并且能够执行任何可能的操作。
  • loader 接收查询参数。用于对 loader 传递配置。
  • loader 也能够使用 options 对象进行配置。
  • 除了使用 package.json 常见的 main 属性,还可以将普通的 npm 模块导出为 loader,做法是在 package.json 里定义一个 loader 字段。

插件(plugin)可以为 loader 带来更多特性。

  • loader 能够产生额外的任意文件。

loader是webpack的最核心的机制之一,就是因为它可以通过loader去打包任何你想要加载的资源,才得以在当下的前端领域立足。

我的往网站:www.dengzhanyong.com
个人公众号:【前端筱园】
1587696742.jpg

邓占勇
109 声望6 粉丝

个人网站:www.dengzhanyong.com