一直使用webpack,上次也分享过webpack配置es6~9的语法参考链接,但是对于一些小白童鞋来说,最基本的配置都不太知道,刚好利用春节休假期间对webpack4的知识点梳理一次。方便一些刚刚入行的人学习,也是对自己的一种总结与提高
一、几个盲点的解释
1、全局安装与局部安装
- 对于一般的新手都有一个疑惑我是全局安装还是本项目中安装(局部安装),个人建议,现在前端发展那么快,我们使用局部安装的方式更好(使用最新的技术栈)。
- 我们知道javascript是弱语言,有局部变量和全局变量,其实全局安装与局部安装的性质与函数的全局变量与局部变量有点类似。
2、安装包的时候--save与-D的区别
一般我们仅仅是在开发环境依赖的包直接使用-D就可以,这样就会在项目的package.json文件中的devDependencies新增相关的配置信息
1
|
npm install webpack webpack-cli -D
|
--save是会放在package.json文件的dependencies中
记住仅仅是开发环境需要使用的包就使用-D
二、webpack所谓的0配置使用
webpack是基于配置的前端脚手架,在实际项目中开发需要配置你需要的插件与加载器。
1、webpack最基本的基重要的是:
- plugins:配置插件的
- module:主要配置一些加载器
2、初始化项目
创建一个文件夹webpack-demo
初始化生成package.json文件
1
|
npm init -- yes
|
3、安装webpack最基本的依赖包
1
|
npm install webpack webpack-cli -D
|
4、创建一个文件夹src并在里面创建一个index.js的文件
5、在命令行中运行(先忽视警告信息)
1
|
npx webpack |
6、在生成的dist文件夹下会生成一个大包好的main.js文件,在该文件夹下创建一个index.html文件引入main.js,在浏览器中查看控制台是否输出信息。
二、webpack的配置
1、在项目下创建一个webpack.config.js文件
2、可以配置的有
1
2
3
4
5
6
7
8
9
10
11
|
const path = require( ‘path‘ );
module.exports = { entry: ‘‘ , // 打包文件的入口
output: {}, // 打包后的出口文件配置
devServer: {}, // 开发服务器
module: {}, // 模块配置
plugins: {}, // 插件的配置
mode: ‘development‘ , // [‘development‘, ‘production‘]模式
resolve: {}, // 配置解析
} |
三、配置开发环境(在内存中打包)
1、安装包
1
|
npm install webpack-dev-server -D
|
2、在webpack.config.js中配置入口文件与出口文件
1
2
3
4
5
6
7
8
9
|
module.exports = { entry: ‘./src/index.js‘ , // 打包文件的入口
output: {
filename: ‘build.js‘ ,
// 注意这个位置必须是绝对路径
path: path.join(__dirname, ‘dist‘ )
},
...
} |
3、配置开发devServer
1
2
3
4
5
6
7
8
9
|
module.exports = { ...
devServer: {
contentBase: path.join(__dirname, ‘dist‘ ),
port: 8000,
compress: true , // 自动压缩
open: true , // 自动打开浏览器
},
} |
4、在package.json中配置命令
1
2
3
4
5
|
... "scripts" : {
"dev" : "webpack-dev-server" ,
}, ... |
5、调试性的运行命令(会自动打开浏览器,但是里面没任何信息展示)
1
|
npm run dev |
6、使用html-webpack-plugin自动生成html页面的插件
1.安装包
1
|
npm install html-webpack-plugin -D
|
2.在webpack.config.js中引入
1
|
const HtmlWebpackPlugin = require( ‘html-webpack-plugin‘ );
|
3.在plugins中配置
1
2
3
4
5
6
|
plugins: [ new HtmlWebpackPlugin({
template: ‘./src/index.html‘ ,
title: ‘webpack测试‘ ,
})
], |
4.关于index.html的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!DOCTYPE html> < html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< meta http-equiv = "X-UA-Compatible" content = "ie=edge" >
< title ><%=htmlWebpackPlugin.options.title%></ title >
</ head >
< body >
</ body >
</ html >
|
5.关于html-webpack-plugin的配置请查看
6、运行npm run dev直接打开浏览器,打开控制台可以查看到打印信息
7、创建打包命令(在package.json中添加命令)
1
2
3
4
|
"scripts" : {
"dev" : "webpack-dev-server" ,
"build" : "webpack"
}, |
8、使用哈希值的方式创建随机生成数字,解决缓存的问题
1、对生成的js文件生成随机数
1
2
3
4
5
6
|
output: { filename: ‘build.[hash].js‘ , // 默认生成20位的哈希值
// filename: ‘build.[hash:8].js‘ 可以定制生成多少位的随机数
// 注意这个位置必须是绝对路径
path: path.join(__dirname, ‘dist‘ )
}, |
2、对html里面引入的js生成哈希值(会生成?哈希值)
1
2
3
4
5
6
7
|
plugins: [ new HtmlWebpackPlugin({
template: ‘./src/index.html‘ ,
title: ‘webpack测试‘ ,
hash: true ,
})
], |
3、运行命令npm run build可以查看dist文件夹下的文件是否带了尾巴(注意点:要更新文件打包会生成新的,如果没改动文件,仅仅是多次打包是一样的)
4、运行后的效果
1
|
<script type= "text/javascript" src= "build.1ac0ed4b.js?1ac0ed4bfca95df7576e" ></script>
|
9、关于html-webpack-plugin其它常用的配置
1
2
3
4
5
6
7
|
new HtmlWebpackPlugin({
...
minify: {
removeAttributeQuotes: true , // 去除双引号
collapseWhitespace: true , // 合并代码到一行
}
}) |
四、清除之前的plugin的插件的使用
我们对每次打包后的缓存文件进行删除确保每次都是最新的
1、安装
1
|
npm install clean-webpack-plugin -D
|
2、在webpack.config.js中使用
1
2
3
4
5
|
const CleanWebpackPlugin = require( ‘clean-webpack-plugin‘ );
plugins: [ new CleanWebpackPlugin([ ‘./dist‘ ]),
...
], |
五、关于webpack入口文件的几种方式
1、单一入口文件(参考上面)
2、多入口文件(可以写成一个数组),共同打包带一个出口文件中
1
2
3
4
5
6
7
8
9
10
11
12
|
module.exports = { mode: ‘development‘ ,
entry: [
‘./src/index.js‘ ,
‘./src/a.js‘
],
output: {
filename: ‘build.[hash:8].js‘ ,
// 注意这个位置必须是绝对路径
path: path.join(__dirname, ‘dist‘ )
}
} |
3、多入口多出口多模板的模式
1.入口文件与出口文件的配置
1
2
3
4
5
6
7
8
9
10
11
|
module.exports = { mode: ‘development‘ ,
entry: {
index: ‘./src/index.js‘ ,
a: ‘./src/a.js‘
},
output: {
filename: ‘[name].[hash:8].js‘ ,
path: path.join(__dirname, ‘dist‘ )
}
} |
2.模板的配置(需要注明输出文件的名字)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
... plugins: [ new CleanWebpackPlugin([ ‘./dist‘ ]),
new HtmlWebpackPlugin({
filename: ‘index.html‘ , // 注明打包后的文件名
template: ‘./src/index.html‘ ,
title: ‘webpack测试1‘ ,
hash: true ,
chunks: [ ‘index‘ ] // 注明选择哪个js文件
}),
new HtmlWebpackPlugin({
filename: ‘a.html‘ ,
template: ‘./src/index.html‘ ,
title: ‘webpack测试2‘ ,
hash: true ,
chunks: [ ‘a‘ ]
})
],
} ... |
六、webpack热更新的使用
1、根据上面的方式我们可以实现,修改js代码浏览器会刷新,但是是类似我们人工的刷新(如果是有状态机的数据的时候会丢失数据)
2、我们可以使用webpack自带的一个热更新的插件
3、使用方式
1.在webpack.config.js中配置
1
2
3
4
5
6
7
|
const webpack = require( ‘webpack‘ );
... plugins: [ new webpack.HotModuleReplacementPlugin(),
...
] ... |
2.在主要的入口index.js文件中加上
1
2
3
|
if (module.hot) {
module.hot.accept();
} |
七、配置加载css样式的
webpack默认是支持js的,对于别的css或者typescript必须要安装加载器
1、安装包
1
|
npm install style-loader css-loader less less -loader -D
|
2、在webpack.config.js中的module配置规则(use中是一个数组,从后面解析到前面)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
... module: { rules: [
{
test: /\.css$/,
use: [
{ loader: ‘style-loader‘ },
{ loader: ‘css-loader‘ }
]
},
{
test: /\.less$/,
use: [
{ loader: ‘style-loader‘ },
{ loader: ‘css-loader‘ },
{ loader: ‘less-loader‘ },
]
}
]
},
... |
3、在src中创建一个css的文件夹,里面创建a.css和b.less文件
4、在index.js中引入样式文件
1
2
|
import ‘./css/a.css‘ ;
import ‘./css/b.less‘ ;
|
5、启动服务,查看浏览器Elements栏
八、抽取成单独的一个样式文件
上面的方式虽然可以加载样式文件,但是加载出来的全部的以<style type="text/css">....</style>的方式到页面中,增加了js文件的体积,如果项目大,可能会造成js文件过大加载慢,甚至加载不出的弊端。
1、抽取单独的css目前主要有2个包可以选择
- 使用插件extract-text-webpack-plugin@next
- 使用插件mini-css-extract-plugin(今后取代上面那个插件的包)
2、安装包
1
|
npm install extract-text-webpack-plugin@next mini-css-extract-plugin -D
|
3、使用extract-text-webpack-plugin@next插件的方式
1.引包
1
|
const ExtractTextWebpackPligin = require( ‘extract-text-webpack-plugin‘ );
|
2.修改module中的加载器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
module: { rules: [
{
test: /\.css$/,
use: ExtractTextWebpackPligin.extract({
use: [
{ loader: ‘css-loader‘ }
]
})
},
{
test: /\.less$/,
use: ExtractTextWebpackPligin.extract({
use: [
{ loader: ‘css-loader‘ },
{ loader: ‘less-loader‘ }
]
})
}
]
}, ... |
3.使用插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
plugins: [ ...
new ExtractTextWebpackPligin({
filename: ‘css/index.css‘ ,
}),
new HtmlWebpackPlugin({
template: ‘./src/index.html‘ ,
title: ‘webpack测试‘ ,
hash: true ,
// 先注释下面的代码,更好看结果
// minify: {
// removeAttributeQuotes: true, // 去除双引号
// collapseWhitespace: true, // 合并代码到一行
// }
})
], |
4、在index.js中依然是导入css文件
1
2
|
import ‘./css/a.css‘ ;
import ‘./css/b.less‘ ;
|
4、使用mini-css-extract-plugin插件方式
1.导包
1
|
const MiniCssTractPlugin = require( ‘mini-css-extract-plugin‘ );
|
2.在module中配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
module: { rules: [
{
test: /\.css$/,
use: [
MiniCssTractPlugin.loader,
{ loader: ‘css-loader‘ }
]
},
{
test: /\.less$/,
use: [
MiniCssTractPlugin.loader,
{ loader: ‘css-loader‘ },
{ loader: ‘less-loader‘ }
]
}
]
}, |
3.配置插件
1
2
3
4
5
6
|
plugins: [ ...
new MiniCssTractPlugin({
filename: ‘css/css.css‘ ,
}),
] |
4.一样的在index.js中导包
5.测试
九、抽取成多个单独的样式文件
1、导包
1
|
const ExtractTextWebpackPligin = require( ‘extract-text-webpack-plugin‘ );
|
2、预先实例化两个输出文件的对象
1
2
|
const cssExtract = new ExtractTextWebpackPligin( ‘css/a.css‘ );
const lessExtract = new ExtractTextWebpackPligin( ‘css/b.css‘ );
|
3、在module中预先实例化的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
module: { rules: [
{
test: /\.css$/,
use: cssExtract.extract({
use: [
{ loader: ‘css-loader‘ }
]
})
},
{
test: /\.less$/,
use: lessExtract.extract({
use: [
{ loader: ‘css-loader‘ },
{ loader: ‘less-loader‘ },
]
})
}
]
}, |
4、配置插件
1
2
3
4
5
|
plugins: [ cssExtract,
lessExtract,
...
] |
5、运行命令npm run build查看
十、关于抽取样式修改后不刷新的问题(开发的时候依然是加上style中)
1.定义disable
1
2
3
4
5
6
|
const cssExtract = new ExtractTextWebpackPligin({
filename: ‘css/a.css‘ ,
}); const lessExtract = new ExtractTextWebpackPligin({
filename: ‘css/b.css‘ ,
}); |
2.在modul中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
module: { rules: [
{
test: /\.css$/,
use: cssExtract.extract({
fallback: ‘style-loader‘ ,
use: [
{ loader: ‘css-loader‘ }
]
})
},
{
test: /\.less$/,
use: lessExtract.extract({
fallback: ‘style-loader‘ ,
use: [
{ loader: ‘css-loader‘ },
{ loader: ‘less-loader‘ },
]
})
}
]
}, |
十一、关于抽取的时候不引入未使用的样式来简单打包后的体积
1、安装包
1
|
npm install purifycss-webpack purify-css glob -D
|
2、导入
1
2
|
const PurifycssWebpack = require( ‘purifycss-webpack‘ );
const glob = require( ‘glob‘ );
|
3、使用
1
2
3
4
5
6
|
... // 注意必须要在HtmlWebpackPlugin后面使用 new PurifycssWebpack({
paths: glob.sync(path.resolve( ‘src/*.html‘ ))
}) ... |
十二、给css3样式加上前缀
1、使用postcss实现该功能
2、安装包
1
|
npm install postcss-loader autoprefixer -D
|
3、配置postcss-loader的加载器
1
2
3
4
5
6
7
8
9
10
11
12
|
... { test: /\.css$/,
use: cssExtract.extract({
fallback: ‘style-loader‘ ,
use: [
{ loader: ‘css-loader‘ },
{ loader: ‘postcss-loader‘ },
]
})
}, ... |
4、项目下新创建一个postcss.config.js的配置文件
1
2
3
4
5
|
module.exports = { plugins: [
require( ‘autoprefixer‘ )
]
} |
5、在a.css中写上css3的样式
1
2
3
4
|
body { background : cyan;
transform:rotate( 30 deg);
} |
6、执行命令npm run build查看生成的文件