打包css资源
使用loader
webpack可以使用各种不同loader来预处理不同格式的资源。
- 在项目目录下添加文件:
// src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
<div class="box"></div>
</body>
</html>
// src/css/style.css
.box{
width:50px;
height: 50px;
background-color: pink;
}
- 安装
css-loader
和style-loader
css-loader
负责读取css文件,然后使用style-loader
将css内容注入到js里面去,最终是以style标签的形式嵌入到Html代码中
npm i -D css-loader style-loader
- 更改配置文件
module:
{
test: /\.css$/,
use: [
{
loader:'style-loader', //以style标签的形式嵌入到html中
options:{
insertAt:top //嵌入位置,top指顶部,不会覆盖掉html自带的style样式
}
}
'css-loader' //解析css文件
]
},
module使用方法:
rules
:一个数组,存放各种Loadertest
:正则表达式,用来匹配不同的文件名后缀loader
:有多种使用方法
{
test:/\.js$/,
loader:'babel-loader' //只有一个loader时
}
{
test:/\.css$/,
use:['style-loader','css-loader'] //多个loader,从右往左加载
}
{
test:/\.css$/,
use:[
'style-loader', //多个loader混合使用
{ //loader要设置相关参数时可以使用对象
loader:'css-loader',
options:{
minimize:true
}
}
]
}
使用插件MiniCssExtractPlugin
使用css-loader
+style-loader
的方式是将样式打包进js
文件,然后以style
标签的形式嵌入页面。css
样式与js
文件混在一起可能导致一些样式混乱,所以使用插件将css
样式统一打包进一个cs
s文件,然后以link
标签的形式嵌入页面进行资源请求。
webpack3
通常使用的是ExtractWebpackPlugin
,但在webpack4中已不再支持,官方推荐使用MiniCssExtractPlugin
进行替代。
首先安装 :
npm i -D mini-css-extract-plugin
修改配置文件
const miniCssExtractPlugin=require('mini-css-extract-plugin');
module.exports = {
entry: path.join(__dirname, 'src/index.js'),
output: {
path: path.join(__dirname, 'dist'),
filename:'bundle.js',
},
module: {
rules:[
{
test: /\.css$/,
use: [
{
loader:miniCssExtractPlugin.loader
},
'css-loader'
]
}
]
},
plugins: [
new htmlWebpackPlugin({
template:'./src/index.html'
}),
new miniCssExtractPlugin({
filename:'[name].css' //输出的css文件名,放置在dist目录下
})
]
}
打开dist/index.html,可以看到以link形式引入了css样式。
自动添加前缀
我们希望可以给css自动添加浏览器前缀,可以使用插件autoprefixer
.
- 首先安装,
npm i -D postcss-loader autoprefixer
postcss-loader
需要一个配置文件,在根目录下新建postcss.config.js
文件,写入:
module.exports={
plugins:[require('autoprefixer')]
}
- 配置loader
// webpack.config.js
{
test: /\.css$/,
use: [
{
loader:miniCssExtractPlugin.loader //抽离成一个css文件
},
'css-loader', //解析css
'postcss-loader' //先添加前缀
]
}
- 编写css测试代码
// src/css/style.css
.box{
width:50px;
height: 50px;
background-color: pink;
transform: rotateX(30deg);
}
- 打包
npm run build
后,打开dist/main.css
,可以看到tranform已经加上了webkit前缀。
压缩css/js代码
使用optimize-css-assets-webpack-plugin
插件来压缩css代码。
- 安装
npm i -D optimize-css-assets-webpack-plugin
- 修改配置文件
// webpack.config.js
const opimizeCss=require('optimize-css-assets-webpack-plugin');
module.exports = {
optimization:{
minimizer:[
new opimizeCss()
]
},
mode:'production'
....
}
- npm run build以后打开main.css发现已经被压缩,但是在默认环境为production时自动压缩的js代码却不再压缩了,我们使用
uglifyjs-webpack-plugin
来压缩js代码。 - 安装
npm i -D uglifyjs-webpack-plugin
- 修改配置文件
//webpack.config.js
const uglifyJsWebpackPlugin=require('uglifyjs-webpack-plugin')
module.exports = {
optimization:{
minimizer:[
new uglifyJsWebpackPlugin({
cache:true, //是否缓存
parallel:true, //是否并发打包,同时打包多个文件
sourceMap:true //打包后的代码与源码的映射,方便调试
})
...
]
...
}
es6转es5
webpack里面使用了大量的es6语法,我们需要转换为es5,使用babel来完成此功能。
- 安装babel
npm i -D babel-loader @babel/core @babel/preset-env
- 配置loader
{
test:/\.js$/,
use:[
{
loader:'babel-loader',
options:{
presets:[
`@babel/preset-env` //es6转es5
]
}
}
]
}
打包图片资源
在js中创建图片引入
(1)引入的图片需要在入口的js文件中import进去
// index.js
import img from './img/big.jpg'; //file-loader将该图片放入到dist下,同时返回图片的地址
var imgElement = document.createElement('img');
imgElement.src = img;
document.body.appendChild(imgElement);
(2)安装file-loader
并配置 npm i -D file-loader
// webpack.config.js
{
test: /\.(png|jpg|gif|svg|jpeg)$/,
loader: 'file-loader',
}
在css中中引入背景图片
与js引入图片用法相同,不过比起file-loader
,更常用的是url-loader
,可以将小图片直接base64编码,减少http请求。
(1)安装url-loader
并配置 npm i -D url-loader
// webpack.config.js
{
test: /\.(png|jpg|jpeg|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 1024, //小于该值的图片会使用base64编码
name: '[name].[hash:8].[ext]' //打包后的图片名称 [ext]指图片格式
}
}
直接在html写入标签
// src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
<div class="box"></div>
<img src="./img/big.png">
</body>
</html>
打包后发现该图片的地址是写死的,并不会相对于dist,导致无法找到该图片,使用html-withimg-loader
来处理html中的图片。
安装并配置
npm i -D html-withimg-loader
// webpack.config.js
{
test:/\.html$/,
loader:'html-withimg-loader'
}
再次打包运行后发现可以正确加载图片了。
配置不同的资源路径
现在这种配置下,所有的资源都放置在dist目录下,看起来很混乱,我们希望js在js文件夹下,css在css文件夹下,图片在img文件夹下,修改相关配置。
//webpack.config.js
module.exports = {
entry: path.join(__dirname, 'src/index.js'),
output: {
path: path.join(__dirname, 'dist'),
filename:'js/bundle.js', //给打包输出的js添加一层目录
},
module: {
rules:[
{
test: /\.css$/,
use: [
{
loader:miniCssExtractPlugin.loader
},
'css-loader',
'postcss-loader'
]
},
{
test:/\.js$/, //最后会打包进输出的js的文件,所以不需要配置路径
use:[
{
loader:'babel-loader',
options:{
presets:[
`@babel/preset-env`
]
},
}
]
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:8].[ext]',
//不能通过名字添加路径,因为背景图片还会被css处理一次,会再添加上css的路径
//最后就会变成 css/img/big.1763821.png
outputPath:'img/', //通过该属性设置,打包输出的路径多一层
publicPath:'http://cdn.com' //图片的访问路径为 http://cdn.com/img/big.561361.png
},
},
{
test:/\.html$/,
loader:'html-withimg-loader', //会加上url-loader里的outputPath
}
]
},
plugins: [
new htmlWebpackPlugin({
template:'./src/index.html'
}),
new miniCssExtractPlugin({
filename:'css/[name].css' //通过名字添加一层路径
}),
new cleanWebpackPlugin()
]
}
最终npm run build后,就可以有不同的文件夹,同时index.html也正确处理了路径。