回顾
回顾一下,我们现在已经能使用Webpack对JS文件进行打包了。并且支持JS文件的模块化开发。Webpack会自动帮我们处理好模块之间的依赖关系。但是往往我们不止有js文件,还有css文件等等。之前我们说过,Webpack可以将他们也看作一个模块然后进行打包。**其实Webpack本身并没有这个功能,他唯一能做的就是打包js文件,并且处理好模块之间的关系。**他也不能把里面的ES6转成ES5.那这些功能是怎么实现的呢?都是通过安装loader来实现的。loader的作用就是拓展Webpack的功能。
loader的作用
loader可以把Webpack打包不了的文件(如css文件)转化成Webpack能打包的模块。比如我举个栗子: 我在之前的文件的基础上,又创建了一个css文件 index.css
body{
background-color:red;
}
现在如果我直接打包main.js,会不会打包我们的index.css呢?很明显是不会的,因为index.css这个文件和我们的main.js文件之间没有任何联系,没有任何依赖。
现在我们让他产生依赖。导入index.css:
import {decrement} from "./es6Module"
let css = require("./index.css")
let a = 11;
let b = 12;
decrement(a,b);
console.log(css);
使用webpack进行打包,发现报错。 很明显的错误提示:you may an appropriate loader handle this file type.你需要一个合适的loader来处理这个文件。也就是说我们的Webpack打包不了css文件。这时候我们需要使用loader了。
使用loader
使用loader,主要分为两步,一个是下载我们的loader。一个是配置好我们的loader
- 下载对应的loader。比如打包css文件,我们需要的是css-loader
- 配置对应的loader.有关于webpack的配置应该都在webpack.config.js中进行,这个也不例外
安装对应的loader
以安装css-loader为例
npm install css-loader --save-dev
css-loader是把我们的css文件打包成我们webpack可以打包的模块。所以它也是一个开发时依赖。
配置相应的loader
之前我们在webpack.config.js中,配置了出口,入口。接下来我们来配置loader的有关东西。应该是在导出对象的module属性中配置。module属性对应的是一个对象,这个对象有一个rules属性对应一个数组,所有的loader配置规则都存放在这里。每种规则对应代码其实又是一个对象,这个对象有两个特别重要的属性:
- test属性,是一个正则表达式,匹配哪些文件要使用对应的loader进行转换
- use属性,对应的一个loader组成的数组,表明匹配到对应文件后,使用哪些loader以及使用的顺序
const path = require("path");
module.exports={
entry:"./src/main.js",
output:{
path:path.resolve(__dirname,"dist"),
filename:"bundle.js"
},
module:{
rules:[
{
test:/\.css$/,
use:["css-loader"]
}
]
}
}
配置好后,webpack如果在打包过程中碰到.css文件,在对它打包之前他会先使用css-loader对css文件做转换,转换成webpack可以打包的模块,然后你再打包。
配置好,我们再对项目进行打包。发现样式并没有生效。这是为什么呢?
原因是这样的:css-loader只是解析了我们css代码,并没有把样式添加到DOM上去,我们可以打印一下刚刚那个那个css变量。
这居然是一个数组。所以我猜测css-loader它把css文件解析成了数组的形式。但是这个js的形式,浏览器肯定解析不懂。这个时候我们需要另一个loader把我们的js形式的样式,转成浏览器能看懂的样式。这就是我们的style-loader
首先,第一步还是安装npm uninstall style-loader --save-dev
第二步配置,应该是只要修改use属性就可以 use:["style-loader","css-loader"]
,请注意,webpack调用loader是从右往左的顺序调用的,所以我们也是倒着写的。
再打包,果然就可以了。
很明显,它的网页代码里面多了一个style标签,所以style-loader的作用应该就是解析css-loader解析后的js代码,然后使用创建style标签的形式,存放样式,并把style标签添加到页面。webpack官网也说了
处理less文件
当我们的项目存在less文件的话我们需要添加less-loader
- 安装
npm install less-loader less --save-dev
less-loader的作用是将我们的less文件编译成我们css文件。为什么要安装less呢?less-loader将less文件编译为css文件的过程中是要依赖到less.
2. 配置
处理图片文件
我们的项目中可能还会存在一些图片文件,处理图片文件,我们需要使用url-loader。webpack处理图片的时候也会把他当作一个模块。
安装url-loader
cnpm install url-loader@1.1.2 --save-dev
cnpm是淘宝镜像,相比npm下载速度更快
配置url-loader
{
test: /\.(png|jpg|gif)$/,//匹配使用url-loader的文件
use: [
{
loader: 'url-loader',
options: {
limit: 8192//它的配置项,就是对图片大小进行限制,默认值是8kb,超过的就不归url-loader管了。
}
}
]
}
效果
可以看到,url-loader把指定的图片文件转成了base-64的字符串,它实际做的事儿就是对图片进行base64编码
大于limit值的图片文件
大于limit值的图片文件,不能使用url-loader了。只能使用file-loader。
安装file-loader
cnpm install file-loader@3.0.1 --save-dev
file-loader好像并不用配置,直接打包即可。
重新打包,没有效果。但是dist文件夹中会多出一个图片文件,并且名字很乱。
file-loader将图片文件进行了打包,打包到了目标文件夹./dist中。而之前url-loader是将图片进行了base64编码并没有进行打包到dist文件夹中。那么为什么会没有效果呢?
看这里:
生成的url路径并不存在dist文件夹,导致文件无法找到。
解决方法:在webpack.config.js中配置publicPath,那么所有和路径有关的东西都会加上公共路径了。
其实这个也不是特别重要,因为最后的index.html文件也要放在dist文件夹中,所以公共路径就没有意义了。
生成的图片名字
这是一个随机的32位hash值,目的就是怕重名的情况。但是往往我们需要知道图片的内容,也就是图片名字要有一定的含义,这样我们就需要重新命名图片的名字。
很多情况下,我们不想把图片直接放在dist文件夹下,需要把他统一放在一个子文件夹。这个问题也是通过命名来解决。
在options下,配置name
他是配置在url-loader的配置项下,就有点奇怪。解释下几个组成部分
- img/ 这个img是随便命名的就是再创建一个子文件夹
- [name] 获取图片打包前的name,放在这里(让图片的名字有了含义)
- [hash:6] 获取六位hash值,因为图片的name可能相同
- [ext] 获取图片原来的拓展名
这就是我们重新命名的图片文件的方式了,重新打包看看效果。
ES6转ES5
当Webpack帮我们打包js文件的时候,其实js文件中,es的语法并没有转化成es5的语法。这导致bundle.js中的代码还含有es6的语法,这样可能不是所有浏览器都能适配,所以我们需要使用babel.loader来转换ES6的语法
安装babel-loader
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
babel-core 依赖它对我们es6转成es5
babel-preset-es2015 好像和配置有关
配置babel-loader
- 匹配js/mjs文件
- exclude 去除掉这两个文件的js文件
- presets 设置