这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战
前面我们已经学习了如何让 webpack 工作,包含开发时的 webpack-dev-server 和 用于生产环境的 webpack 打包输出文件。今天我们进一步了解 webpack。
一、 抽离 css 文件
前面我们通过配置 loader 使 webpack 可以处理 import some.css,但是我们发现 webpack 是把 css 变成 style 标签插入到 html 文件中;接着我们将通过 mini-css-extract-plugin 把 css 抽离成单独的文件,并且通过 link 标签的形式引入到 html 文件中;
1.1 安装 mini-css-extract-plugin 插件
npm install mini-css-extract-plugin --dev
1.2 导入 mini-css-extract-plugin 插件,并修改配置文件;有两处修改:
- 修改 modules 字段中处理 css 的 loader
- 在 plugins 中增加一个 mini-css-extract-plugin 的实例
- 配置对象 Object:
- filename: 'main.css' 输出的 css 文件名字和路径,如果不含路径则直接输出到 output 对应的目录,如果包含目录,则会产出到对应目录
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
+ const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); // 抽离 css文件
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
devServer: {
contentBase: './build',
port: 3000,
open: true,
progress: true,
proxy: {
'/api': {
target: 'http://domain.com/somet/api',
changeOrigin: true,
secure: false
}
}
},
module: {
rules: [
- {
- test: /.css$/,
- use: ['style-loader', 'css-loader']
- },
+ {
+ test: /.css$/,
+ use: [
+ MiniCSSExtractPlugin.loader,
+ 'css-loader'
+ ]
+ }
]
},
plugins: [
new HTMLWebpackPlugin({
template: './src/index.html',
hash: true,
filename: 'index.html',
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true
}
}),
// 抽离 css 文件
+ new MiniCSSExtractPlugin({
+ filename: 'main.css'
+ })
]
}
- 效果
二、 处理 css 预处理器
日常开发中我们开会经常使用一些 css 预处理语言,如 less、sass、stylus 等,这里以 less 为例,展示 webpack 如何处理 css 预处理器。处理 CSS 预处理器,我们同样需要借助 loader 的力量;
2.1 安装对应的 loader
yarn add lessc less-loader -D
2.2 在 src 目录下增加 index.less 文件
body {
background: #000;
div {
color: deepskyblue;
}
}
2.3 在 index.js 中导入 index.less 文件
import './index.css';
+ import './index.less'
document.addEventListener('DOMContentLoaded', function () {
let div = document.createElement('div');
div.innerHTML = 'Hello World';
document.body.appendChild(div);
div = null;
});
2.4 修改 webpack 配置文件
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); // 抽离 css文件
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
devServer: {
contentBase: './build',
port: 3000,
open: true,
progress: true,
proxy: {
'/api': {
target: 'http://domain.com/somet/api',
changeOrigin: true,
secure: false
}
}
},
module: {
rules: [
{
test: /.css$/,
use: [
MiniCSSExtractPlugin.loader,
'css-loader'
]
},
+ {
+ test: /.less$/,
+ use: [
+ MiniCSSExtractPlugin.loader,
+ 'css-loader',
+ 'less-loader'
+ ]
+ }
]
},
plugins: [
new HTMLWebpackPlugin({
template: './src/index.html',
hash: true,
filename: 'index.html',
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true
}
}),
// 抽离 css 文件
new MiniCSSExtractPlugin({
filename: 'main.css'
})
]
}
- 效果如图
三、css 属性自动增加前缀
日常开发过程中,我们经过需要给 CSS3 的属性增加前缀,例如 -webkit 等,这些工作也可以通过 webpack 帮我们完成;完成这个工作需要借助两个工具:postcss-loader、autoprefixer;postcss-loader 把 css 处理层 js 可以理解的内容,然后调用插件 autoprefixer,autoprefixer 就是自动前缀的意思;
3.1 安装 postcss-loader、autoprefixer
yarn add postcss-loader、autoprefixer -D
3.2 修改 less 文件
body {
background: #000;
div {
+ transform: rotate(45deg);
color: deepskyblue;
}
}
3.3 在项目目录下增加 postcss 的配置文件:postcss.config.js
module.exports = {
plugins: [require('autoprefixer')]
}
3.4 修改配置文件
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); // 抽离 css文件
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
devServer: {
// 开发服务器的配置
contentBase: './build',
port: 3000,
open: true,
progress: true,
proxy: {
'/api': {
target: 'http://domain.com/somet/api',
changeOrigin: true,
secure: false
}
}
},
module: {
rules: [
{
test: /.css$/,
use: [
MiniCSSExtractPlugin.loader,
'css-loader'
]
},
{
test: /.less$/,
use: [
MiniCSSExtractPlugin.loader,
'css-loader',
+ 'postcss-loader',
'less-loader' // 先调用 less-loader,因为需要先将 less 处理成 css
]
}
]
},
plugins: [
new HTMLWebpackPlugin({
template: './src/index.html',
hash: true,
filename: 'index.html',
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true
}
}),
// 抽离 css 文件
new MiniCSSExtractPlugin({
filename: 'css/main.css'
})
]
}
- 效果
四、 处理图片
4.1 处理 HTML 中的 img 图片
为什么要处理 HTML 文件中图片?还记得,我们使用 html-webpack-plugin 插件,把模板 HTML 文件从项目的源文件目录 src 复制到 输出目录中,开发时同样都是把图片放在 src 目录下,但是输出目录中没有对应图片,这就会导致 HTML 引入图片报错;
- 安装 html-withimg-loader
yarn add html-withimg-loader -D
- 安装 file-loader 和 url-loader
如果想完成页面中引入图片这个工作,还需要 file-loader 和 url-loader;但是我在写这些例子时,发现 file-loader 升级 5.x 后之前的配置(如下)会报错;所以本例的 file-loader 并没有采用最新版,而是采用的 url-loader 的 2.2.0 和 file-loader 的 4.2.0 版本,这些版本都是之前项目中稳定运行的版本;
module.exports = {
modules: {
rules: [
{
test: /.(jpeg|png|jpg)$/,
use: {
loader: 'url-loader',
options: {
limit: 200 * 1024, // 可以把设置小于某个值的图片或者文件打包成 base64,如果超过这个值自动输出为文件;
outputPath: 'img/', // 图片输出到的目录
publicPath: 'https://www.dahai.com/' // 给图片设置单独的 CDN 路径
}
}
},
{
test: /.html$/,
use: 'html-withimg-loader' // 处理 html 中的 img 引用的图片
}
]
}
}
所以,安装指定版本的 url-loader、file-loader
yarn ade url-loader@2.2.0 file-loader@4.2.0 -D
4.2 修改配置文件
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); // 抽离 css文件
module.exports = {
entry: './src/index.js',
mode: 'production',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
devServer: {
// 开发服务器的配置
contentBase: './dist', // 静态资源文件目录
port: 3000, // 开发服务器启动的端口
open: true, // 是否自动启动浏览器
progress: true, // 进度条
proxy: { // 配置代理
'/api': { // 将带有 /api 的请求,转发值 target 指向的域名
target: 'http://domain.com/somet/api',
changeOrigin: true,
secure: false
}
}
},
module: {
rules: [
{
test: /.css$/,
use: [
MiniCSSExtractPlugin.loader,
'css-loader'
]
},
{
test: /.less$/,
use: [
MiniCSSExtractPlugin.loader,
'css-loader',
'postcss-loader',
'less-loader'
]
},
+ {
+ test: /.(jpeg|png|jpg)$/,
+ use: {
+ loader: 'url-loader',
+ options: {
+ limit: 5 * 1024,
+ outputPath: '/img/'
+ }
+ }
+ },
+ {
+ test: /.(htm|html)$/,
+ use: 'html-withimg-loader' // 处理 html 中的 img 引用的图片
+ }
]
},
plugins: [
new HTMLWebpackPlugin({
template: './src/index.html', // 需要引入输出文件的 html 文件模板
hash: true, // 给引入的 js 加hash
filename: 'index.html', // 输出的 html 文件的名字(插件会把模板 html 复制到输出目录中)
minify: { // 压缩优化输出的 html 文件配置
removeAttributeQuotes: true, // 删除行内属性的双引号
collapseWhitespace: true // 删除换行,使内容保持在一行
}
}),
// 抽离 css 文件
new MiniCSSExtractPlugin({
filename: 'css/main.css'
})
]
}
4.3 css/less 中使用图片
经过上面的配置后,同样支持在 CSS 文件中通过引用图片,同样会得到正确的处理;
body {
background: #000;
div {
margin-top: 100px;
display: inline-block;
transform: rotate(45deg);
color: deepskyblue;
}
p {
width: 100px;
height: 100px;
background: url("./stars.jpeg") ;
color: #fff;
}
}
- 效果如图