不进行配置,webpack默认打开webpack.config.js文件
"scripts": {
"build": "webpack"
},
Loaders
webpack只支持js和json两种文件类型,其他的如html、css、less、jsx、vue的指令语法糖、字体等,webpack需要通过Loaders将原生这些不支持的类型转化成有效的模块,然后webpack解析的时候才能添加到依赖图中。
Loaders本身是一个函数,接收源文件作为参数,输出转换后的结果给下一步使用。
webpack一切皆js模块,所以需要各种loader转换成js。
module.exports = {
// 放到module对象的rules数组中
// test指定匹配规则,use指定使用的loader名称
// use只有一个loader时是字符串,多个时是个数组
module: {
rules: [
{test: /\.txt$/,use: 'raw-loader'}
]
}
}
Plugins
用于增强webpack功能,用于打包输出文件的优化,资源管理和环境变量注入,作用于整个构建过程。
Loaders不能的,都可以使用Plugins完成,比如构建之前删除目录
module.exports = {
// 放到plugins数组中
plugins: [
new HtmlWbpackPlugin({template: './src/index.html'})
]
}
Mode
用来指定当前的构建环境,有三个值:
资源解析-ES6/jsx
webpack支持js解析,但是并不是完全会解析ES6的语法特性,需要使用babel-loader进行解析,而该loader的使用需要在项目中配置.babelrc
- plugins:一个plugin对应一个功能
- preset:是一系列plugin的集合,解析es6的话,preset-env就可以了,解析react,使用preset-react
// .babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
css/less等解析
module: {
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
css-loader是把css转化成commonJs,style-loader是把样式放到html的内联样式中,并不会生成单独的一个文件,需要使用MiniCssExtractPlugin插件把css提取成独立的文件。
文件/字体解析
可以用file-loader或者url-loader,url-loader可以将小图片自动转化成base64
module.exports = {
module: {
rules: [
{
test: /\.(png|jpeg|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
// 小于10k的图片自动转换
limit: 10240
}
}]
}
]
}
}
可见,图片打包进search文件了,只适用于js中引用,html和css中使用其他loader
文件监听
watch:需要刷新浏览器,文件进行I/O操作 WDS:配合HotMoudleReplacementPlugin插件使用,不刷新浏览器,不输出文件,而是将产物放到内存中读取。 WDM:webpack-dev-middleware,适用于定制化场景
"scripts": {
// --open参数含义:每次构建完成自动开启浏览器
"dev": "webpack-dev-server --open"
},
// 在配置文件中
plugins: [
// 插件是webpack内置的,所以需要引入webpack
// but,webpack.HotModuleReplacementPlugin 没有必要加,官网文档说配置了 hot: true 会自动引入这个 plugin。
new webpack.HotModuleReplacementPlugin()
],
devServer: {
// 服务的基础目录
contentBase: './dist',
// 开启热更新
hot: true
}
WDS原理:待深入记录&理解
- HMR Server 是服务端,用来将变化的 js 模块通过 websocket 的消息通知给浏览器端。
- HMR Runtime是浏览器端,用于接受 HMR Server 传递的模块数据,浏览器端可以看到 .hot-update.json 的文件过来。
- webpack 构建出来的 bundle.js 本身是不具备热更新的能力的,HotModuleReplacementPlugin 的作用就是将 HMR runtime 注入到 bundle.js,使得bundle.js可以和HMR server建立websocket的通信连接
webpack-dev-server和hot-module-replacement-plugin之间的关系?
- webpack-dev-server(WDS)的功能提供 bundle server的能力,就是生成的 bundle.js 文件可以通过 localhost://xxx 的方式去访问,另外 WDS 也提供 livereload(浏览器的自动刷新)。
- hot-module-replacement-plugin 的作用是提供 HMR 的 runtime,并且将 runtime 注入到 bundle.js 代码里面去。一旦磁盘里面的文件修改,那么 HMR server 会将有修改的 js module 信息发送给 HMR runtime,然后 HMR runtime 去局部更新页面的代码。因此这种方式可以不用刷新浏览器。
- hot-module-replacement-plugin 包给 webpack-dev-server 提供了热更新的能力。
原理文档:zhuanlan.zhihu.com/p/30669007
文件指纹
用于版本控制,改变则不会从缓存中取。
不能和热更新同时使用,需要配置dev和prod两个不同的环境。
- hash:和整个项目的构建有关,只要文件有修改,整个项目构建的hash也会跟随修改。
- chunkHash:和webpack打包的chunk有关,不同的entry会生成不同的chunkhash值,一般js文件使用。
- contentHash:根据文件内容改变而变化。一般用于css。 占位符含义:
'use strict';
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: {
index: './src/index.js',
search: './src/search.js'
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name]_[chunkhash:8].js'
},
mode: 'production',
module: {
rules: [
{
test: /.js$/,
use: 'babel-loader'
},
{
test: /.css$/,
use: [
// style-loader和MiniCssExtractPlugin是冲突的,所以使用MiniCssExtractPlugin.loader
MiniCssExtractPlugin.loader,
'css-loader'
]
},
{
test: /.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader'
]
},
{
test: /.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name]_[hash:8].[ext]'
}
}
]
},
{
test: /.(woff|woff2|eot|ttf|otf)$/,
use: {
loader: 'file-loader',
options: {
name: '[name]_[hash:8].[ext]'
}
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name]_[contentHash:8].css'
})
]
};
代码压缩
- js文件可使用webpack内置的uglifyjs-webpack-plugin,个性化可以自行再配置
- css使用c,需要配合预处理器cssnano使用, optimize-css-assets-webpack-plugin默认配置
- html使用html-webpack-plugin
plugins: [
new OptimizeCssAssetsWebpackPlugin({
assetNameRegExp: /\.css$/g,
// cssnano是属于默认配置,可以不写不安装
cssProcessor: require('cssnano')
}),
new HtmlWebpackPlugin({
// template:生成filename的文件模版,支持ejs等
template: path.join(__dirname, 'src/search.html'),
// 输出文件的文件名称
filename: 'search.html',
// 允许插入到模版的chunk,不配置则会把output中所有的chunk都插入
chunks: ['search'],
// 向template中注入所有的静态资源
// 1、true或者body:所有JavaScript资源插入到body元素的底部
// 2、head: 所有JavaScript资源插入到head元素中
// 3、false: 所有静态资源css和JavaScript都不会注入到模板文件中
inject: true,
// 设置静态资源的压缩情况,html-minifier
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.html'),
filename: 'index.html',
chunks: ['index'],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
})
]
极客时间-玩转webpack