配置
webpack是一种前端资源构建工具,一个静态模块打包器。
在webpack看来,前端的所有资源文件(js/css/img/less/...)都会作为模块处理。
它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。
开发环境
const path = require('path');
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin');
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin')
const os = require('os');
const threads = os.cpus().length;
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
fileName: 'static/js/main.js',
chunkFilename: 'static/js/[name].chunk.js',
assetModuleFilename: 'static/media/[hash:10].[ext][query]'
// clean: true, // 自动清空上次打包结果 在打包前将path整个目录内容清空,再进行打包
},
module: {
rules: [
{
oneOf: [
{
test: /\.(css|less)$/,
use: [
'style-loader', // 将js中css通过创建style标签添加到html中生效
'css-loader', // 将css资源编译成commonjs的模块到js中
'less-loader', // 将less编译成css
]
},
{
test: /\.(png|jpg|gif|svg)$/,
type: 'asset',
parser: {
dataUrlCOndition: {
// 小于10KB的图片转base64
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024
}
},
generator: {
// 输出图片名称 hash值取前10位
fileName: 'static/images/[hash:10].[ext][query]'
}
},
{
// 处理字体图标和其他资源
test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
type: 'asset/resource', // 原封不动打包
// generator: {
// fileName: 'static/media/[hash:10].[ext]'
// }
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'thread-loader',
works: threads,
},
{
loader: 'babel-loader',
options: { // 可以写在babel.config.js
preset: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
}
]
],
cacheDirectory: true, // 开启babel缓存
cacheCompression: false, // 关闭缓存压缩
plugins: ["@balel/plugin-transform-runtime"],
}
}]
}
]
}
]
},
plugin: [
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, 'src'),
exclude: 'node_modules', // 默认值
cache: true,
cacheLocation: path.resolve(__dirname, 'node_modules/.cache/eslintcache'),
threads,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/index.html')
}),
new PreloadWebpackPlugin({
// rel: 'preload',
// as: 'script',
rel: 'prefetch',
})
],
optimization: {
minimizer: [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin({
parallel: threads
})
],
splitChunks: {
chunks: 'all',
cacheGroups: { // 单入口文件不需要配置
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
},
// 一个文件改变,contenthash更新,所有依赖他的文件都会跟着变化,缓存失效
// 把hash值保存在一个runtime文件
runtimeChunk: (entrypoint) => `runtime~${entrypoint.name}.js`
}
},
mode: 'development',
// 不输出资源 在内存中编译打包
devServer: {
host: 'localhost', //启动服务器的域名
port: 3000,
open: true, // 是否自动打开浏览器,
hot: true
}
}
生产环境
const path = require('path');
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin');
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin')
const os = require('os');
const threads = os.cpus().length;
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'static/js/main.js',
chunkFilename: 'static/js/[name].chunk.js',
assetModuleFilename: 'static/media/[hash:10].[ext][query]'
// clean: true, // 自动清空上次打包结果 在打包前将path整个目录内容清空,再进行打包
},
module: {
rules: [
{
oneOf: [
{
test: /\.(css|less)$/,
use: [
MiniCssExtractPlugin.loader,
// 'style-loader', // 将js中css通过创建style标签添加到html中生效
'css-loader', // 将css资源编译成commonjs的模块到js中
// 解决css兼容性问题 postcss-loader postcss postcss-preset-env
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: ['postcss-preset-env']
}
}
},
'less-loader', // 将less编译成css
]
},
{
test: /\.(png|jpg|gif|svg)$/,
type: 'asset',
parser: {
dataUrlCOndition: {
// 小于10KB的图片转base64
// 优点:减少请求数量 缺点:体积会更大
maxSize: 10 * 1024
}
},
generator: {
// 输出图片名称 hash值取前10位
filename: 'static/images/[hash:10].[ext][query]'
}
},
{
// 处理字体图标和其他资源
test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
type: 'asset/resource', // 原封不动打包
// generator: {
// filename: 'static/media/[hash:10].[ext]'
// }
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'thread-loader',
works: threads,
},
{
loader: 'babel-loader',
options: { // 可以写在babel.config.js
preset: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
}
]
],
cacheDirectory: true, // 开启babel缓存
cacheCompression: false, // 关闭缓存压缩
plugins: ["@balel/plugin-transform-runtime"],
}
}]
}
]
}
]
},
plugin: [
new ESLintPlugin({
// 检测哪些文件
context: path.resolve(__dirname, 'src'),
exclude: 'node_modules',
cache: true,
cacheLocation: path.resolve(__dirname, 'node_modules/.cache/eslintcache'),
threads,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/index.html')
}),
// 提取css成单独文件 css目前被打包到js文件中,当js文件加载时,会创建一个style标签
// 来生成样式,这样对于网站来说,会出现闪屏现象,用户体验不好
// 我们应该是单独的css文件,通过link标签加载性能才好
new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].chunk.[contenthash:10].css',
})
// css压缩 生产环境html js自动压缩
// new CssMinimizerWebpackPlugin(),
// new TerserWebpackPlugin({
// parallel: threads
// })
new PreloadWebpackPlugin({
// rel: 'preload',
// as: 'script',
rel: 'prefetch',
})
],
optimization: {
minimizer: [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin({
parallel: threads
})
],
splitChunks: {
chunks: 'all',
cacheGroups: { // 单入口文件不需要配置
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
},
// 一个文件改变,contenthash更新,所有依赖他的文件都会跟着变化,缓存失效
// 把hash值保存在一个runtime文件
runtimeChunk: (entrypoint) => `runtime~${entrypoint.name}.js`
}
},
mode: 'production',
}