webpack基本配置
const path = require('path');
const os = require('os');
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserWbpackPlugin = require('terser-webpack-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');
const threads = os.cpus().length; // cpu核数
// 封装样式loader函数,获取处理样式的loader
function getStyleLoader(pre) {
return [
MiniCssExtractPlugin.loader, // 提取css成单独的文件
'css-loader', // 将css资源编译成commonjs的模块到js中
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
'postcss-preset-env' // 能解决大多数样式兼容问题
]
}
}
},
pre
].filter(Boolean);
}
module.exports = {
// 单入口
entry: 'app.js',
// 多入口
// entry: {
// app: './src/app.js',
// main: './src/main.js'
// },
// 输出
output: {
// 所有文件的输出路径
// __dirname为node.js的变量,代表当前文件的文件夹目录
path: path.resolve(__dirname, 'dist'), // 绝对路径
// 入口文件打包输出的文件名
filename: 'static/js/main.js',
// 多入口文件打包
// filename: '[name].js', // webpack命名方式,[name]以入口文件名的key命名打包后的文件名
// 自动清空上次打包结果
clean: true
},
// 加载器
module: {
// loader的配置
rules: [
{
// 每个文件只能被其中一个loader配置处理
oneOf: [
// 处理css资源
{
test: /\.css$/, // 只检测.css文件
// loader: '', // 只能使用一个loader
// 使用多个loader,使用那些loader处理,执行顺序为【倒序】执行
use: getStyleLoader()
},
// 处理less资源
{
test: /\.less$/, // 只检测.css文件
use: getStyleLoader('less-loader')
},
// 处理sass资源
{
test: /\.s[ac]ss$/, // 只检测.css文件
use: getStyleLoader('sass-loader')
},
// 处理stylus资源
{
test: /\.sty$/, // 只检测.css文件
use: getStyleLoader('stylus-loader')
},
// 处理图片资源
{
test: /\(png|jpe?g|gif|webp|svg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
// 小于10kb的图片转成base64,优化请求数量,但是会导致打包体积变大
maxSize: 10 * 1024 // 10kb
}
},
generator: {
// 输出图片名称
// [hash:10] hash值取前十位,[hash]取全部hash值
filename: 'static/image/[hash:10][ext][query]'
}
},
// 处理字体图标和其他资源
{
test: /\(ttf|woff2?|mp3|mp4|avi)$/,
type: 'asset/resource',
generator: {
// 输出字体名称
filename: 'static/media/[hash:10][ext][query]'
}
},
// babel
{
test: /\.js$/,
// include和exclude只能任选其一
exclude: /node_modules/, // 排除node_modules文件夹下的js文件
// include: path.resolve(__dirname, 'src'), // 只处理src文件夹下的文件,其它不做处理
use: [
{
loader: 'thread-loader', // 开启多进程对babel进行处理
options: {
works: threads // 进程数量
}
},
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
// corejs解决js兼容性问题
{
useBuiltIns: 'usage',
corejs: 3
}
], // 使用智能预设
cacheDirection: true, // 开启babel缓存,提升开发环境下的打包速度
cacheCompression: false // 关闭缓存文件压缩,开启的话会占用内存空间,降低打包速度
}
}
]
}
]
}
]
},
// 插件
plugins: [
// eslint插件(必须先配置eslint文件 .eslintrc.js)
new ESLintPlugin({
// 检测哪些文件夹
context: path.resolve(__dirname, 'src'),
// 排除那些文件夹
exclude: 'node_modules', // 默认值
// 开启缓存
cache: true,
// 指定缓存文件的路径
cacheLocation: path.resolve(__dirname, 'node_modules/.cache/eslintcache'),
threads // 开启多进程和设置进程数量
}),
new HtmlWebpackPlugin({
// 模板:以public/index.html文件创建html文件
// 新的html文件特点:1、结构与原来一致 2、自动引入打包输出的资源
template: path.resolve(__dirname, 'public/index.html')
}),
// 提取css成单独文件
new MiniCssExtractPlugin({
filename: 'static/css/main.css'
}),
// PWA离线技术,将文件缓存在本地,可以实现离线访问,但是兼容性教差
new WorkboxPlugin({
clientClaim: true,
skipWaiting: true
})
// 若要使用PWA离线技术,需要将以下代码需要加到main.js当中
// if ('serviceWorker' in navigator) {
// window.addEventListener('load', () => {
// navigator.serviceWorker.register('/service-worker.js').then(registration => {
// console.log('SW registration', registration)
// })
// .catah(registrationError => {
// console.log('SW registration failed', registrationError)
// })
// })
// }
],
optimization: {
// 压缩的操作
minimizer: [
// css压缩
new CssMinimizerPlugin(),
// js压缩
new TerserWbpackPlugin({
parallel: threads // 开启多进程和设置进程数量
}),
// 图片压缩
new ImageMinimizerPlugin()
],
// 代码分割的操作
splitChunks: {
chunks: 'all'
},
runtimeChunk: {
name: (entrypoint) => `runtime${entrypoint.name}.js`
}
},
// 开发服务器(不会输出资源,在内存中编译打包)
devServer: {
host: 'loaclhost', // 域名
port: '3000', // 端口
open: true, // 是否自动打开浏览器
hot: true // HMR(HotModuleReplacement),默认开启(true),只能用于开发环境,生产环境不再需要,旨在提升打包构建速度
},
// 模式
mode: 'development', // 'production'
// Source-Map,形成映射文件,方便查定位错误
devtool: 'cheap-module-source-map' // 'source-map'
};