概念
在webpack
中任何一个东西都称为模块,js
就不用说了。一个css
文件,一张图片、一个less
文件都是一个模块,都能用导入模块的语法(commonjs
的require
,ES6
的import
)导入进来。webpack
自身只能读懂js
类型的文件,其它的都不认识。但是webpack
却能编译打包其它类型的文件,像ES6
、JSX
、less
、typeScript
等,甚至css
、images
也是Ok的,而想要编译打包这些文件就需要借助loader
loader
就像是一个翻译员,浏览器不是不认识这些东西么?那好交给loader
来办,它能把这些东西都翻译成浏览器认识的语言。loader
描述了webpack
如何处理非js
模块,而这些模块想要打包loader
必不可少,所以它在webpack
里显得异常重要。loader
跟插件一样都是模块,想要用它需要先安装它,使用的时候把它放在module.rules
参数里,rules
翻译过来的意思就是规则,所以也可以认为loader
就是一个用来处理不同文件的规则
文件目录
这节课需要用到图片跟样式,所以我要按传统的目录结构来创建目录,目录如下
结构目录
处理CSS
所需loader
style-loader //把处理完的css放到style标签里css-loader //处理css
安装
npm i style-loader css-loader -D
index.css
文件内容如下:
#box{ width: 800px; height: 500px; border: 5px solid #999; color: #00f; background: green;}
index.js
文件内容如下:
import '../css/index.css'; //两个点是找上级目录
通过前面的课程大家要明白,webpack
的入口文件是index.js
,如果要处理其它类型的文件,就需要在入口文件里把其它类型的文件导入进来,而在webpack
中所有文件都是模块,所以可以使用require
或者import
导入其它文件
package.json
文件内容如下:
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "build": "webpack --mode production", "dev": "webpack-dev-server --mode development" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^1.0.0", "html-webpack-plugin": "^3.2.0", "style-loader": "^0.21.0", "webpack": "^4.16.3", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.1.5" }}
webpack.package.json
文件内容如下:
const path=require('path');const HtmlWebpackPlugin=require('html-webpack-plugin');module.exports={ entry:{ index:'./src/js/index.js', }, output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' }, plugins:[ new HtmlWebpackPlugin({ title:'陈学辉', template:'./src/template.html', filename:'index.html', }) ], devServer:{ host:'localhost', port:1573, open:true, }, module:{ rules:[ { test:/\.css$/, //以点开始css结尾的文件 use:['style-loader','css-loader'] //顺序不能搞错 } ] },}
执行命令npm run dev
后就可以看到效果
说明
rules
里的数据类型为对象,每一个loader
都是一个对象
test
表示loader
要处理什么类型的文件,这里用了一个正则去匹配文件类型
use
表示要使用哪个loader
,它的值是个数组,loader
的使用顺序是从后往前这个
loader
的意思为,在入口文件里找到.css
类型的文件,先拿css-loader
去处理成浏览器认识的css
,再拿style-loader
把处理后的css
放在页面的style
标签里
css-loader
其它配置:https://www.webpackjs.com/loaders/css-loader/style-loader
其它配置:https://www.webpackjs.com/loaders/style-loader/
单独提取CSS
执行命令npm run build
后,在dist
目录里只有两个文件,一个index.bundle.js
一个index.html
文件,并没有css
文件,同时打开index.html
源码后也没有发现有css
的内容。这是因为style-loader
的作用,它把css
一同打包到了js
文件里,js
文件在能过DOM
动态创建style
标签并添加到页面里。所以css
的内容已经放到了index.bundle.js
里。
这种形式只有当文件内容不多的时候可以使用,如果CSS
的内容以及JS
的内容非常的多,把两块都打包到一个文件里就会增加文件的体积,用户打开页面的时候下载速度会受影响,同减肥影响用户体验。这就需要把CSS
文件单独拎出来,那需要一个插件来配合loader
才能完成
mini-css-extract-plugin
webpack
版本需要4.3以上,低版本请使用extract-text-webpack-plugin
使用步骤:
1、安装
npm i mini-css-extract-plugin -D
2、在webpack.config.js
里引入模块
const MiniCssExtractPlugin=require("mini-css-extract-plugin");
3、写入plugins
plugins:[ new HtmlWebpackPlugin({ title:'陈学辉', template:'./src/template.html', filename:'index.html', }), new MiniCssExtractPlugin({ filename:'css/index.css' //文件目录会放入output.path里 }),]
4、写入loader
module:{ rules:[ { test:/\.css$/, use:[MiniCssExtractPlugin.loader,"css-loader"] //代替style-loader } ]}
执行命令npm run build
后可以看到dist
目录里已经多了一个css
文件夹,这个文件夹里放了一个index.css
文件。打开index.html
源码看到css
文件已经通过link
标签引入,这些功能都是mini-css-extract-plugin
所做的
mini-css-extract-plugin
其它配置:https://github.com/webpack-contrib/mini-css-extract-plugin
处理图片
所需loader
file-loader //解析地址url-loader //把图片地址解析成base64
安装
npm i file-loader url-loader -D
index.css
文件内容如下:
#box{ width: 800px; height: 500px; border: 5px solid #999; color: #00f; /*background: green;*/ background: url(../images/img_01.jpg); //背景改成了图片}
index.js
文件内容如下:
import '../css/index.css'; //两个点是找上级目录
webpack.package.json
文件内容如下:
const path=require('path');const HtmlWebpackPlugin=require('html-webpack-plugin');module.exports={ entry:{ index:'./src/js/index.js', }, output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' }, plugins:[ new HtmlWebpackPlugin({ title:'陈学辉', template:'./src/template.html', filename:'index.html', }) ], devServer:{ host:'localhost', port:1573, open:true, }, module:{ rules:[ { test:/\.css$/, //以点开始css结尾的文件 use:[ //这是一个loader,如果loader需要给参数,就写成对象的形式 { loader:MiniCssExtractPlugin.loader, //loader是哪个 options:{ //所有的配置参数都要放在这个对象里面 publicPath:'../' //这个表示在css文件里但凡用到地址的地方在其前面加个目录'../',这个是为了能找到图片 } }, 'css-loader' //这个loader没有其它选项就直接写 ] }, { test:/\.(jpg|png|gif)$/, //找到三种格式中的任意一种 use:['file-loader'] } ] },}
执行命令npm run dev
后就可以看到效果
说明
loader
既可以写成字符串的形式,也可以写成对象的形式。如果这个loader
需要给一些配置,那就需要写成对象的形式,所有的配置放到options
里这里一定要注意第一个
loader
的use
属性,它里面放的是一个个loader
,每个loader
的值既可以是对象形式,又可以是字符串形式
file-loader
其它配置:https://www.webpackjs.com/loaders/file-loader/
在HTML文件中使用图片
index.js
文件内容如下:
import '../css/index.css';import img1 from '../images/img_01.jpg';import img2 from '../images/img_02.jpg';const loadImg=img=>{ const newImg=new Image(); newImg.onload=()=>document.body.appendChild(newImg); newImg.src=img;};loadImg(img1);loadImg(img2);
webpack.package.json
文件内容如下:
const path=require('path');const HtmlWebpackPlugin=require('html-webpack-plugin');const MiniCssExtractPlugin=require("mini-css-extract-plugin");module.exports={ entry:{ index:'./src/js/index.js', }, output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' }, plugins:[ new HtmlWebpackPlugin({ title:'陈学辉', template:'./src/template.html', filename:'index.html', }), new MiniCssExtractPlugin({ filename:'css/index.css' }), ], devServer:{ host:'localhost', port:1573, open:true, }, module:{ rules:[ { test:/\.css$/, use:[ { loader:MiniCssExtractPlugin.loader, options:{ publicPath:'../' } }, "css-loader" ] }, { test:/\.(jpg|png|gif)$/, //use:['file-loader'] use:[ { loader:'url-loader', //把图片转成base64 options:{ limit:50*1024, //小于50k就会转成base64 outputPath: 'images' } } ] //use:'url-loader?limit=50000&outputPath=images' //loader的另一种写法,与get请求方式相同 } ] },}
执行命令npm run dev
后就可以看到效果
说明
url-loader
的作用是把图片转成base64
,它同样可以给配置参数
limit
的作用是小于这个值就会转base64
只用了
url-loader
,并没有用file-loader
,说明url-loader
里已经包含了file-loader
的功能
loader
还可以写成地址的形式,与get
的请求方式相同