配置文件名称
webpack
默认配置文件:webpack.config.js
webpack
配置组成:entry
——打包的入口文件(指定默认的entry
为:./src/index.js
)output
——打包的输出(指定默认的output
为:./dist/main.js
)mode
——环境rules
——Loader
配置plugin
——插件配置
hello-world
创建一个文件目录
生成
package.json
文件shell1
npm init -y
安装
webpack
和webpack-cli
shell1
npm install webpack webpack-cli --save-dev //安装至dev-dependency中
创建一个
webpack.config.js
文件Javascript1
2
3
4
5
6
7
8
9
10
11
12;
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
mode: 'production'
}编写入口文件
打包
shell1
./node_modules/.bin/webpack
更便捷的打包方式为——在
package.json
文件中的srcipt
中设置Javascript1
2
3
4"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack"
}设置完毕后即可使用
npm run build
来进行打包。
基本用法
Entry
Entry
用来指定webpack
的打包入口
单入口——
entry
为一个字符串Javascript1
entry: './src/index.js'
多入口——
entry
为一个对象Javascript1
2
3
4entry: {
app: './src/app.js',
adminApp:'./src/adminApp.js'
}
Output
output
用来告诉webpack
如何将编译后的文件输出到磁盘
单入口
Javascript1
2
3
4output: {
filename:'boundle.js'.
path:__dirname + 'dist'
}多入口
Javascript1
2
3
4output: {
filename:'[name].js', //通过占位符来保证名字的唯一性
path: __dirname + 'dist'
}
Loaders
webpack
开箱即用只支持JS
和JSON
两种文件类型,通过Loaders去支持其他文件类型并把它们转化为有效的模块。
本质是一个函数,接受源文件作为参数,返回转化的结果
常见的Loaders
名称 描述 babel-loader 转换 ES6、ES7 等 JS 新特性语法 css-loader 支持 .css 文件的加载和解析 less-loader 将 less 转化为 css ts-loader 将 ts 转换为 js file-loader 进行图片、字体等的打包 raw-loader 将文件以字符串形式导入 thread-loader 多进程打包 js 和 css 用法
Javascript1
2
3
4
5
6
7module: {
rules:[
{test:/\/txt$/, use: 'raw-loader'}
//test 指定匹配规则
//use指定使用的loader名称
]
}
plugins
插件用域bundle文件的优化,资源管理和环境变量注入。
作用于整个构建过程
常见的Plugins
名称 描述 CommonsChunkPlugin 将chunks相同的模块代码提取成公共js CleanWebpackPlugin 清理构建目录 ExtractTextWebpackPlugin 将css从bundle文件里提取成一个独立的css文件 CopyWebpackPlugin 将文件或者文件夹拷贝到构建的输出目录 HtmlWebpackPlugin 创建html文件去承载输出的bundle UglifyjsWebpackPlugin 压缩js ZipWebpackPlugin 将打包出的资源生成一个zip包 用法
Javascript1
2
3plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
mode
用来指定当前的构建环境
选项 | 描述 |
---|---|
production | 设置process.env.NODE_ENV的值为development。开启 NamedChunksPlugins 和 NamedModulesPlugin |
development | 设置process.env.NODE_ENV的值为production。开启 FlagDependencyUsagePlugin , FlagIncludedChunksPlugin, ModuleConcatenationPlugin , NoEmitOnErrorsPlugin , OccurrenceOrderPlugin, SideEffectsFlagPlugin和TerserPlugin |
none | 不开启任何优化选项 |
进阶用法
解析ES6
安装
babel-loader
、@babel/core
、@babel/preset-env
shell1
npm i @babel/core @babel/preset-env babel-loader -D
创建
.babelrc
文件并配置Javascript1
2
3{
"presents": ["@babel/preset-env"] //增加es6的babel present配置
}在
webpack.config.js
中设置Javascript1
2
3
4
5
6rules: [
{
test:/.js$/,
use:'babel-loader'
}
]
解析React Jsx
安装
react-dom
、@babel/preset-react
shell1
npm i react-dom @babel/preset-react -D
在
.babelrc
中配置Javascript1
2
3{
"presents": ["@babel/preset-react"]
}在
webpack.config.js
中设置Javascript1
2
3
4
5
6rules: [
{
test:/.js$/,
use:'babel-loader'
}
]
解析css
安装
shell1
npm i style-loader css-loader -D
在
webpack.config.js
中配置Javascript1
2
3
4
5
6
7
8
9
10rules: [
{
test: /.css$/,
use: [
'style-loader', //将样式通过<style>标签插入到head中
'css-loader'
// loader调用方式为链式调用,即从右到左。所以应当先写style-loader
]
}
]
解析less、sass
安装
shell1
npm i less less-loader -D
配置
Javascript1
2
3
4
5
6
7
8
9
10rules: [
{
test: /.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
解析图片
安装
shell1
npm i file-loader -D
配置
Javascript1
2
3
4{
test: /.(png|jpg|gif|jpeg)$/,
use: 'file-loader'
}
解析字体
解析字体同样是使用file-loader
配置
Javascript1
2
3
4{
test: /.(woff|woff2|eot|ttf|otf)$/,
use: 'file-loader'
}
解析字体和图片还可以使用url-loader
,相比较于file-loader
它可以设置较小资源自动base64
配置
Javascript1
2
3
4
5
6
7
8
9{
test: /.(png|jpg|gif|jpeg)$/,
use: [{
loader: 'url-loader',
options: {
limit:10240
}
}]
}
文件监听
文件监听是指在发现源码发生变化时,自动重新构建出新的输出文件,有两种实现方式:
缺陷——每次需要手动刷新浏览器
启动
webpack
命令时,带上--watch
参数在
package.json
中配置Javascript1
2
3"scripts": {
"watch": "webpack --watch"
}
在配置
webpack.config.js
中设置watch:true
原理分析:轮询判断文件的最后编辑时间是否变化,某个文件发生了变化,并不会立刻告诉监听者,而是先缓存起来,等
aggregateTimeout
Javascript1
2
3
4
5
6
7
8
9
10
11
12
13module.export = {
//默认为flase
watch: true,
//只有开启监听模式时,watchOptions才有意义
watchOption: {
//默认为空,不监听的文件夹
ignored: /node_modules/,
//监听到变化后会等300ms再去执行,默认300ms
aggregateTimeout: 300,
//判断文件是否发生变化是通过不断询问系统指定文件有没有变化实现的,默认每秒问1000次
poll: 1000
}
}
热更新——webpack-dev-server
- 不刷新浏览器
- 不输出文件,而是放在内存中
- 使用
HotModuleReplacementPlugin
插件
使用
在
package.json
文件中配置Javascript1
2
3"scripts": {
"dev": "webpack-dev-server --open" //open参数:每次构建完成后自动开启浏览器
}在
webpack.config.js
文件中配置Javascript1
2
3
4
5
6
7
8
9
10mode: 'development' //只在开发环境中使用
module: {
plugins: [
new webpack.HotModuleReplacementPlugin() //需要引入webpack
],
devServer: [
contentBase: './dist', //服务基础目录
hot: true
]
}
文件指纹
hash
:和整个项目的构建相关,只要项目文件有修改,整个项目构建的hash
值就会改变Chunkhash
:和webpack
打包的chunk有关,不同的entry
会生成不同的chunkhash
值Contenthash
:根据文件内容来定义hash,文件内容不变,则contenthash
不变
使用策略:
js
的文件指纹Javascript1
2
3
4output: {
path: path.join(__dirname, 'dist'),
filename: '[name]_[chunkhash:8].js'
}字体、图片的文件指纹
Javascript1
2
3
4
5
6
7
8
9
10
11{
test: /.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name]_[hash:8].[ext]'
}
}
]
}css
的文件指纹安装插件,把
css
提取出来成为一个独立文件,不能与style-loader
一同使用。shell1
npm i mini-css-extract-plugin -D
使用插件并配置
Javascript1
2
3
4
5plugins: [
new MiniCssExtractPlugin({
filename: '[name]_[contenthash:80].css'
})
]Javascript1
2
3
4
5
6
7
8{
test: /.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader'
]
}
文件压缩
html
压缩安装
shell1
npm i html-webpack-plugin -D
引用插件,一个页面对应一个
HtmlWebpackPlugin
Javascript1
2
3
4
5
6
7
8
9
10
11
12
13
14new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.html'), //html模板所在位置
filename: 'index.html', // 指定打包出来的文件名称
chunks: ['index'], // html使用哪些chunk
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: flase
}
})
css
压缩使用
optimize-css-assets-webpack-plugin
插件和cssnano
预处理器安装
shell1
npm i optimize-css-assets-webpack-plugin cssnano -D
引用插件
Javascript1
2
3
4new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano')
})
js
压缩内置了
uglifyjs-webpack-plugin
插件,自动压缩js
文件。
自动清理构建目录
安装
shell1
npm i clean-webpack-plugin -D
引入并使用插件
Javascript1
new CleanWebpackPlugin()
自动补齐css3前缀
安装
sh1
npm i postcss-loader autoprefixer -D
使用loader
Javascript1
2
3
4
5
6
7
8
9
10
11
12
13
14use: [
'style-loader'
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer')({
browsers: ['last 2 version', '>1%', 'ios 7'] //指定所需要兼容的浏览器版本
})
]
}
}
]
移动端px转换为rem
安装
shell1
npm i px2rem-loader -D
shell1
npm i lib-flexible -S //用来动态计算根元素字体的大小
配置
loader
Javascript1
2
3
4
5
6
7{
loader: 'px2rem-loader',
options:{
remUnit: 75, //一个rem=75px
remPreCesion: 8 // px转换成rem后的小数点位数
}
}页面引入
lib-flexible
,不支持内联,需手动引入
静态资源内联
安装 (注意安装版本)
shell1
npm i raw-loader@0.5.1 -D
使用
html1
2
3
4
5
6
7<head>
<!--内联html-->
${ require('raw-loader!../meta.html')}
<title>demo</title>
<!-- 内联js -->
${ require('raw-loader!babel-loader!../../node_modules/lib-flexible/flexble.js')}
</head>
多页面应用打包
安装库
shell1
npm i glob -D
设置函数
Javascript1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38const setMPA = () => {
const entry = {}
const htmlWebpackPlugins = []
const entryFiles = glob.sync(path.join(__dirname, './src/*/index.js'))
Object.keys(entryFiles)
.map((index) => {
const entryFile = entryFiles[index]
const match = entryFile.match(/src\/(.*)index.js/)
const pageNaem = match && match[1]
entryFile[pageName] = entryFile
htmlWebpackPlugins.push(
new HtmlWebpackPlugin({
template: path.join(__dirname, `src/${pageName}/index.html`),
filename: `${pageName}.html`,
chunks: [pageName],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: flase
}
})
)
})
return {
entry,
htmlWebpackPlugins
}
}
const { entry, htmlWebpackPlugins} = setMPA()
module.exports = {
plugins: [].concat(htmlWebpackPlugins)
}
scope hoisting
原理: 将所有模块的代码按照引用顺序放在一个函数作用域里,然后适当的重命名一些变量以防止变量名冲突。
意义:可以减少函数声明代码和内存开销
提取公共资源
使用html-webpack-externals-plugin