这篇主要介绍《webpack优化环境配置》。
知识点包括:
一、开发环境性能优化(HMR)
1、将webpack生产环境配置汇总工程完整复制一份,并重命名。
在终端输入npx webpack serve
启动热更新服务。
然后我们简单修改index.less内的样式,会发现只单独更新了样式模块。
2、此时在简单修改index.js和index.html文件,则不会仅仅更新js或者html模块,而是整个工程进行更新。
在webpack.config.js内代码中有注释说明。
/**
* 启动devServer命令:
* npx webpack serve
* 开发环境的性能优化(HMR):hot module replacement热模块替换/模块热替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)极大提升构建速度.
样式文件:可以使用HMR功能:因为style-loader内部实现了~
js文件:默认不能使用HMR功能,我们可以在入口文件中引入其他js文件,实现修改其他js文件,达成HMR功能
html文件:默认不能使用HMR功能.同时会导致问题: html文件不能热更新了~,在入口entry属性中配置上html文件即可解决
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: ['./src/index.js', './src/index.html'],
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
//处理less资源
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
],
},
{
//处理css资源
test: /\.css$/,
use: [
'style-loader',
'css-loader'
],
},
{
//处理图片资源Ⅰ
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
// 关闭ES6模块化
esMoudle: false
},
type: 'javascript/auto'
},
{
//处理html中img资源
test: /\.html$/,
loader: 'html-loader',
options: {
esModule: false,
}
},
{
//处理其他资源
exclude: /\.(html|js|css|less|jpg|png|gif)$/,
loader: 'file-loader',
options: {
esModule: false,
},
type: 'javascript/auto'
}
]
},
plugins: [
// plugins的配置
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
devServer: {
compress: true,
port: 3000,
open: true,
// 开启hmr功能,webpack5默认开启了
// hot: true
},
mode: 'development'
}
3、入口文件index.js不能使用HMR功能,那么在入口文件中,引入其他的js则可以使用,不过要修改代码。
index.js:
import '../src/iconfont';
import '../src/index.less';
import print from './print';
console.log('index.js文件被加载了');
function add(x, y) {
return x + y;
}
console.log(add(1, 8));
if (module.hot) {
// 一旦 module.hot为true,说明开启了HMR功能。--> 让HMR功能代码生效
module.hot.accept('../src/print.js', function () {
//方法会监听 print.js文件的变化,一旦发生变化,其他模块不会重新打包构建。
//会执行后面的回调函数
print();
})
}
4、我们新建的另一个print.js
function print() {
const content = 'print.js被加载了';
console.log(content);
}
export default print;
此时修改print.js文件,则会发生HMR热更新模块功能。
但是,注意:入口文件index.js一修改是只能整个工程全部更新。
二、source-map
source-map:一种提供源代码到构建后(打包)代码映射技术(如果构建后(打包)代码出错了,通过映射可以追踪源代码错误)。
1、将上一小节工程文件复制,并重命名。修改webpack.config.js代码
/**
* 启动devServer命令:
* npx webpack serve
* 开发环境的性能优化(HMR):hot module replacement热模块替换/模块热替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)极大提升构建速度.
样式文件:可以使用HMR功能:因为style-loader内部实现了~
js文件:默认不能使用HMR功能
html文件:默认不能使用HMR功能.同时会导致问题: html文件不能热更新了~,在入口entry属性中配置上html文件即可解决
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: ['./src/index.js', './src/index.html'],
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
//处理less资源
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
],
},
{
//处理css资源
test: /\.css$/,
use: [
'style-loader',
'css-loader'
],
},
{
//处理图片资源Ⅰ
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
// 关闭ES6模块化
esMoudle: false
},
type: 'javascript/auto'
},
{
//处理html中img资源
test: /\.html$/,
loader: 'html-loader',
options: {
esModule: false,
}
},
{
//处理其他资源
exclude: /\.(html|js|css|less|jpg|png|gif)$/,
loader: 'file-loader',
options: {
esModule: false,
},
type: 'javascript/auto'
}
]
},
plugins: [
// plugins的配置
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
devServer: {
compress: true,
port: 3000,
open: true,
// 开启hmr功能,webpack5默认开启了
// hot: true
},
// source-map:一种提供源代码到构建后(打包)代码映射技术(如果构建后(打包)代码出错了,
//通过映射可以追踪源代码错误)。
// 开启source-map,打包后会生成一个.js.map文件
devtool: 'source-map',
// 测试不同种类的source-map
// devtool: 'eval-source-map',
mode: 'development'
}
/*
有如下几个组合source-map
[inline-|hidden-|eval-] [nosources-] [cheap-[ module-]] source-map
inline-source-map:把原本单独生成的built.js.map文件,整体内嵌到了built.js中尾部去了
hidden-source-map:单独生成一个built.js.map文件,
eval-source-map:内嵌到built.js中,但是是以分段的形式,从头至尾,遍布于整个.js文件中
nosources-source-map:单独生成一个built.js.map文件
cheap-source-map:单独生成一个built.js.map文件
cheap-module-source-map:单独生成一个built.js.map文件。
*/
2、输入npm run dev
进行打包。
3、然后输入npx webpack serve
开启热更新。效果如下
4、那么我们为了验证代码出错时是否有映射关系。把print.js中代码人为制造一个错误。
function print() {
// 人为制造一个log的错误 —— 多加两个逗号
const content = 'print.js被加载了',,
console.log(content)
}
export default print;
自动热更新后,网页报错的提示。
小结,不同的sourece-map对比:
三、oneOf
1、将webpack生产环境配置工程复制,并重命名oneOf。
oneOf功能是:使每个类型的文件,只匹配到一个适用的loader即可,不会把代码中写的所有loader挨个匹配一遍,优化了构建速度。
2、在webpack.config.js代码如下,把相关的loader放入oneOf选项中。
const { resolve } = require('path');
const minicssextractplugin = require('mini-css-extract-plugin');
// css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
process.env.NODE_ENV = 'development'
const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
const Htmlwebpackplugin = require('html-webpack-plugin');
const Eslintwebpackplugin = require('eslint-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
// oneOf是每一个文件,只匹配到一个loader即可,
//不像之前,每个文件都要把下列loader全部匹配一遍
// 注意不能有两个loader处理同一个类型文件
oneOf: [
{
// 检测css文件,并打包
test: /\.css$/,
use: [
minicssextractplugin.loader,
'css-loader',
{
// 对css做兼容性处理
// 还需要在package.json中定义browserslist
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [require('postcss-preset-env')()]
}
}
}
]
},
{
// 检测less文件,并打包
test: /\.less$/,
// use内代码,是从下往上的顺序执行的
use: [
minicssextractplugin.loader,
'css-loader',
{
// 还需要在package.json中定义browserslist
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [require('postcss-preset-env')()]
}
}
},
'less-loader'
]
},
// 正常来讲,一个文件只能被一个loader处理,比如一个index.js文件。
//当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序
// {
// //在package.json中定义eslintConfig --> airbnb
// // js语法检查,webpack4写法
// test: /\.js$/,
// exclude: /node_modules/,
// // 优先执行eslint-loader,对js文件进行处理
// enforce: 'pre',
// loader: 'eslint-loader',
// options: {
// // 自动修复语法检查的报错
// fix: true
// }
// },
{
// js兼容性处理
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', {
useBuiltIns: 'usage',
corejs:
{
version: 3
},
targets: {
// 浏览器兼容的版本
chrome: '60',
firefox: '50'
}
}
]
]
}
},
{
//对图片进行打包处理
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
outputPath: 'imgs',
esModule: false
},
type: 'javascript/auto'
},
{
// 处理html中的图片文件
test: /\.html$/,
loader: 'html-loader',
options: {
esModule: false,
}
},
{
// 处理其他文件,如字体图标等
exclude: /\.(js|css|less|html|jpg|png|gif)$/,
loader: 'file-loader',
options: {
outputPath: 'media',
esModule: false,
},
type: 'javascript/auto'
}
]
}
]
},
plugins: [
new minicssextractplugin({
// 打包提取成单独文件
filename: 'css/built.css'
}),
new cssminimizerwebpackplugin(
// 压缩css文件
),
new Htmlwebpackplugin({
template: './src/index.html',
// 压缩html
minify: {
collapseWhitespace: true,
removeComments: true
}
}),
new Eslintwebpackplugin({
// 使用默认配置
fix: true
})
],
// 生产环境下,js自动压缩
mode: 'production'
}
注:笔记转载自疯子的梦想@博客,课程来自尚硅谷b站Webpack5实战课程