分析一波,webpack中的loader

152 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

背景

webapck默认只支持js、json文件,不支持vue、jpg、css、sass、ts,那么这时候,就用到了loader。
看下面的例子,因为入口文件引入的一个css文件,报错了,因为webpack默认压根就不支持css。
项目目录:

image.png
src/index.js:

import {add} from './other.js'
import css from './index.css'
const json =require('./index.json')
console.log(json,add(1,2));
console.log('哈哈');

src/index.json:

{
  "age": 18
}

src/other.js:

 export function add(a,b){
  return a+b
}

src/list.js:

console.log('我是list文件呀');

src/index.css:

body{
    background: red;
}

webpack/config.js:

const path = require("path");
module.exports = {
    // entry:'./src/other.js',
    entry: {
        index: './src/index.js',
        list: './src/list.js'
    },
    output: {
        filename: "[name].js",//利用占位符,文件名不要重复
        path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径
    },
    mode: 'development'
}

package.json:

{
  "name": "01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "webpack": "^4.44.0",
    "webpack-cli": "^4.9.2"
  },
  "devDependencies": {},
  "scripts": {
    "test": "webpack"

  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

执行npm run test构建,出现下面错误:

image.png
说是不支持css,可能需要个loader去支持这个文件类型。

loader 到底什么?

默认情况下,webpack仅支持.js、.json文件,通过loader,可以让它解析其他类型的文件,充当翻译官的角色。理论上只要有相应的loader,就可以处理任何类型文件。
再说的细一点:模块解析,模块转换器,用于把模块原内容按照需求转换成新内容,webpack是模块打包工具,而模块不仅仅是js,还可以是Css,图片或者其他格式,但是webpack默认只知道如何处理js和json模块,那么其他格式的模块处理,和处理方式就需要loader了。

loader具体怎么做翻译呢?

在Webpack官网查找需要的loaderwebpack里所需的loader链接
常见的loader:
style-loader
css-loader
less-loader
sass-loader
ts-loader //将Ts转换成js
babel-loader //转换ES6、7等js新特性语法
file-loader //处理图片子图
eslint-loader
...

具体使用和解析

找到需要的loader安装在你的项目里就可以啦,怎么选择需要的loader的呢?
比如:你的css文件需要转换,那就在官网文档里面找css-loader+...;要转换less文件+...;就找less-loader+...;sass=>sass-loader+...,ts=>ts-loader等,找到自己需要的loader后,用npm install或者yarn add等命令安装在自己项目里,然后配置一下就好了。

拿我上面的代码案例说事,我操作一遍,让Webpack支持css。
首先安装css-loader:
yarn add css-loader
安装完成:

image.png
安装完后,切记,一定要配置,不然是不成功的,也还是会报上面那个错误,在webpack.config.js里面配置:
webpack.config.js:

const path = require("path");
module.exports = {
    // entry:'./src/other.js',
    entry: {
        index: './src/index.js',
        list: './src/list.js'
    },
    output: {
        filename: "[name].js",//利用占位符,文件名不要重复
        path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径
    },
    mode: 'development',
    module: {
        rules: [
            {
               test:/\.css$/, //指定匹配正则
                use:['css-loader'] 指定使用的loader
            }
        ]
    }
}

在moudle字段里面配置,什么是module?

module

模块,在webpck里一切皆模块,一个模块对应着一个文件,webpack会从配置的Entry开始递归找出所有的依赖的模块
当webpack处理到不认识的模块时,需要在Webpack中的nmodule处进行配置,当检测到是什么格式的模块,使用loader来处理。
多个loader作用于一个模块时,使用数组格式,一个的话可用字符串,也可用数组。
配置完,我们再执行一下构建,看下效果:

解析

image.png
它报错了,一系列分析后,是版本的问题,我现在的版本是6.0的版本我换成5.0.1的就构建成功了,所以小伙伴们,如果遇到构建失败的,降低一下版本试试,因为新的webpack,loader高版本还不稳定,所以会报错。
image.png
构建成功后,看看样式出来了没:

image.png
样式并没有出来哦,看一下,css文件是成功加载到出口文件里的,但是样式为什么没有生效呢?
这是dist/index.html的代码,用这个文件展示效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="index.js"></script>
</head>

<body>

</body>
</html>

看效果: image.png
这是因为css-loader只是把文件处理到出口文件里,但是并没有把样式成功添加到html里,这时候就需要另外一个loader,style-loader,所以还要需要安装style-loader,并做配置。
yarn add style-loader@2.0.0

image.png
这里我装的是2.0.0的版本,因为最新版本3.0的也会出错,所以装了个稳定版本的。
配置webpack.config.js:

const path = require("path");
module.exports = {
    // entry:'./src/other.js',
    entry: {
        index: './src/index.js',
        list: './src/list.js'
    },
    output: {
        filename: "[name].js",//利用占位符,文件名不要重复
        path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /.css$/,
                use: ["style-loader","css-loader"]
            }
        ]
    }
}

这里注意:顺序,是自后向前,后面的先执行,然后再前面的,因为:先把css文件成功处理到出口文件中,然后再把css的样式。 执行构建,看效果:

image.png 效果出来了,成功过啦。
可以看到,是在style标签里写入了样式。
这是因为style.loader,在html的头部通过dom动态创建style标签,然后css放在style标签里,达到生效的效果。

css-loader、style-loader分别干了什么?

css-loader:分析模块之间的关系,并合成一个css.
style-loader:会把css-loader生成的内容以style挂载到页面的header

其他类型文件解析,如less文件,sass文件

同理哦,分别这样配置的:
webpack.config.js:

const path = require("path");
module.exports = {
    // entry:'./src/other.js',
    entry: {
        index: './src/index.js',
        list: './src/list.js'
    },
    output: {
        filename: "[name].js",//利用占位符,文件名不要重复
        path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /.css$/,
                use: ["style-loader","css-loader"]
            },
            {
                test: /.less$/,
                use: ["style-loader","css-loader","less-loader"]
            },
            {
                test: /.sass$/,
                use: ["style-loader","css-loader","sass-loader"]
            },
        ]
    }
}

都要有style-loader这个,因为最后都要让css样式生效,less文件是:less.loader先将less编译成css,然后把css-loader,把css处理到出口文件里,最后style-loader把css动态放在html的头部的style标签里,生成效果,sass文件也同理哦。
注意: 针对于less文件时,安装less-loader的同时也要安装less,因为less-loader依赖less,sass也一样,安装sass-loader的同时也要安装sass,sass-loader是依赖于sass的。