Skip to content

Latest commit

 

History

History
193 lines (141 loc) · 5.49 KB

04.md

File metadata and controls

193 lines (141 loc) · 5.49 KB

title: Webpack 模块儿加载器 Loaders 使用

Loaders

回顾第二章提出的一个问题:

上面只是演示了对 js 文件的打包,所谓的一切皆模块儿的概念没有体现呢,如何做?

webpack 的世界里,一切都是模块儿,不同的模块通过相应的模块儿加载器去处理。

其实在我们前端的范畴里,模块儿的类型并不会太多,一般也就那么几种:

文件类型 后缀名
js .js
JSON .json
css .css, .scss, .sass
图片文件 .jpg, .png, .webp, .gif...
字体文件 .eot, .svg, .ttf, .woff ...
flash .swf
jsx .jsx
vue .vue
html .html
twig .twig
jade .jade
... ...

下面我们就通过 webpack 加载 css 模块儿来理解 loader 在 webpack 中所起的作用。

CSS module

我们依然使用之前的测试项目 webpack-test

准备工作

在 src 目录下新建 css 文件夹,完成 main.css 的编写

// main.css
html, body {
    background: red;
}

修改 main.js 将 css 模块添加到项目中,作为依赖。

// main.js
import './css/main.css' // 这里可以使用相对路径来引入
import './js/b';

这个时候去执行编译命令 npm run build

会得到如下报错:

> webpack

Hash: 695f49dbe3071133e5f6
Version: webpack 3.5.4
Time: 105ms
         Asset    Size  Chunks             Chunk Names
main.bundle.js  3.7 kB       0  [emitted]  main
   [0] ./src/main.js 51 bytes {0} [built]
   [1] ./src/css/main.css 215 bytes {0} [built] [failed] [1 error]
   [2] ./src/js/b.js 49 bytes {0} [built]
   [3] ./src/js/a.js 68 bytes {0} [built]

ERROR in ./src/css/main.css
Module parse failed: /Users/Ben/Work/webpack-test/src/css/main.css Unexpected token (1:11)
You may need an appropriate loader to handle this file type.
 html, body {
   background: red;
 }
 @ ./src/main.js 1:0-25

大概意思是说:错误发生在 ./src/css/main.css, 模块解析失败,你可能需要适当的loader 来解析这种文件类型。

是的,我们只是告诉 webpack 我们依赖 css 文件,但是 webpack 需要合适的 loader 才能处理 css 模块儿。处理 css 模块儿的 loader 是 css-loader

通过 npm 安装 css-loader到开发依赖

npm i -D css-loader

修改 webpack 的配置文件 webpack.config.js 如下

const patch = require('path');

module.exports = {
  entry: './src/main.js',
  output: {
    path: patch.resolve(__dirname, './dist'),
    filename: 'main.bundle.js'
  },
  // 编写针对模块儿的处理配置
  module: {
    loaders: [
        {
            test: /\.css$/,  // 利用正则匹配,匹配到各种类型的模块儿。
            loader: ['css-loader']  // 为具体类型的模块儿使用适当的loader
        }
    ]
  },
  devServer: {
    contentBase: './dist'
  }
}

然后重启 devServernpm run devServer

可以发现打包成功,没有报错了。

然后查看页面发现,,,我们的样式没有生效。。。这是为什么呢 ??

因为 css-loader 只负责解析 css 文件,并不负责将样式代码添加到页面中。为了做这一步,我们还需要另外一个loader,可以帮助我们把css 代码以 html 中 style 标签的形式插入 html 中。

通过npm 安装 style-loader 到开发依赖

npm i -D style-loader

修改 webpack 配置文件 webpack.config.js

// webpack.config.js
    // ...
    loaders: [
        {
            test: /\.css$/,
            loader: ['style-loader', 'css-loader']  // loader 的应用顺序是倒序的。
            // 所以,webpack 的处理顺序是先试用css-loader 处理,然后再使用style-loader 处理。
        }
    ]
    // ...

npm run devServer 重启devServer.

这次可以看到我们的样式已经生效了。并且审查页面的 style 元素可以看到我们写的 css 代码。

至此我们支配 webpack 完成了对 css 模块儿的处理和使用。

LESS Module

但是我们经常使用的是 LESS ,又需要怎么处理呢?非常简单,只需要先把 less 文件利用 less-loader 处理成 css ,然后再按照 css module 处理不就可以了。

直接把前面的 main.css 修改成 main.less

把入口文件main.js 里对 main.css 的依赖改为 main.less

然后把前面写的对 css 文件的正则匹配改成对less 文件的正则匹配。并且在loader 最后面添加 less-loader

// webpack.config.js
    // ...
    loaders: [
        {
            test: /\.less$/,
            loader: ['style-loader', 'css-loader', 'less-loader']  // loader 的应用顺序是倒序的。
        }
    ]
    // ...

记得通过npm 来安装 less-loader 到开发依赖哦

npm i -D less-loader

最后,重启devServer。看看是不是已经生效了 ?

SCSS Module

类似 LESS Module 的处理,,不再做说明。

总结:

我们以 css 和 less 为例学习了配置 webpack 加载其他类型的模块儿的方法。在使用的时候,我们只需要通过匹配,匹配到具体某种类型的模块儿,然后为这种类型的模块儿使用合适的 loader 就可以了。

问题:

  • 我们刚才把css代码添加到了 html 的 style 标签中,如果存在大量的 css 代码,难道还要放在style 标签吗?如何把 css 文件提取出来放在单独的文件。
  • loader 的运行原理是什么? loader 到底内部做了什么处理就可以让 webpack 来打包不同类型的模块儿 ?