const { resolve } = require('path');
process.env.NODE_ENV = 'development';
// 把css-loader处理为js的文件转换为css
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// css 压缩 插件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// 处理HTML插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// PWA 渐进式网络开发应用程序(简单说就是离线网站也可以展示响应内容)
// workbox---> workbox-webpack-plugin
const WrokboxWebpackPlugin = require('workbox-webpack-plugin');
modules.exports = {
// 打包入口文件 单入口文件写法
entry:'./src/index.js',
// 多入口文件写法
// entry:{
// index:'./src/index.js',
// test:'./src/test.js',
// },
// 打包后输出文件
output:{
// 前面加上js 是把文件放到js文件里面
// hash 、 chunckhash 、contenthash 特殊文件命名 解决代码迭代时,取缓存代码不更新问题
// filename:'js/built.[hash:10].js',
// filename:'js/built.[chunckhash:10].js',
filename:'js/built.[contenthash:10].js',
// 对于多入口文件 为了便于查看打包生成文件 使用[name]自动生成入口名称
// filename:'js/[name].[contenthash:10].js',
// 输入路径 __dirname 表示当前文件的根目录下生成 built 文件
path:resolve(__dirname,'built')
},
// 打包模块
module:{
rules:[
{
// 匹配后缀为.css文件
text:/\.css/$,
// 使用加载器loader,loader:webpack值能处理js文件的补充(充当转换功能),丰富webpack打包样式
// 通常是两种用法:
// 1、对于多个loader 需要加载的情况使用 use:['xxx-loader','yyy-loader'],加载时有执行顺序:从右到左执行(也称从下到上执行)
// 2、单个使用时,loader: 'xxx-loader',
// css 处理方式1 css->js->挂载到style
use:[
'style-loader', // 在将变为js文件,挂载到style上
'css-loader', // 处理css文件变为js
],
},{
// css 处理方式2 使用插件loader方法 MiniCssExtractPlugin.loader 从js代码中提取css
// 以处理less 文件为为例
text:/\.less/$,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
{
// loader 配置可以对象形式,配置其他内容
// postcss-loader css兼容性处理
// 注意:postcss-loader加上后,须在package.json中添加区分生产和开发模式,开发兼容上一个浏览器版本,生产兼容98%以上浏览器版本
// "borwserslist":{
// "development":[
// "last 1 chrome version",
// "last 1 firefox version",
// "last 1 safari version",
// ],
// "production":[
// ">0.2%",
// "not dead",
// "not op_mini all"
// ],
// },
loader:'postcss-loader',
options:{
ident:'postcss',
plugins:() => [
require('postcss-preset-env')()
],
},
},
'less-loader',
],
},{
// 在package.json 中eslintConfig ---> 使用 airbnb 规则
// "eslintConfig":{
// "extends":"airbnb-base"
// }
text:/\.js$/,
exclude:/node_modules/,// 排除node_modules,
// eslint-loader 规则加载器
loader:'eslint-loader',
enforce: 'pre' , // enforce 加载多个相同文件时优先加载
options:{
// 手动配置fix 为true 当打包时自动安插件规则修复语法错误
fix:true,
}
},{
text:'/\.js$/',
exclude:/node_modules/,// 排除node_modules,
// thread-loader 多进程打包提高构建速度。通常用于JS代码很多的情况
// 需要用的时候,使用use 配合babel-loader使用
// babel-loader js兼容loader
loader:'babel-loader',
options:{
preset:[
['@babel/preset-env',
{
useBuiltIns:'usege',// 使用按需加载
corejs:{
version:3 //
}, // 使用corejs的按需加载,版本3
targets:{
chrome:'60',// 兼容到谷歌60
firefox:'50',// 兼容到火狐50
}
}
]
],
/**
* 缓存处理
* babel 缓存
* babel-loader 加入
* 代码 options{
* cacheDirectory: true; 开启缓存
* }
*
*/
cacheDirectory: true, // 开启缓存处理
/**
* 开启缓存处理,一般会在输出JS、css文件 加上 contenthash
* contenthash 更具文件内容生生成哈希值。
* contenthash 是弥补 代码迭代时候,用户依旧会取旧缓存值,导致代码不生效问题
*
* hash、chunkhash 也可以处理 代码迭代取缓存值问题。不过,hash 和 chunkhash 会对非改动代码进行重新获取。
* 相比contenthash 性能不友好
*
*
*/
}
},{
test:/\.(png|jpg|gif)$/,
loader:'url-loader',
options:{
// 限制大小低于8k变为base64编码。减少请求数量
limit: 8*1024,
// 名称重新去哈希值前十位为显示名称
name:'[hash:10].[ext]',
// 打包放到imgs目录下
outputPath:'imgs',
// 加上html-loadr时必须加上
esModule: false,
}
},{
test:/\.html$/,
loader: 'html-loader',// 加上html-loader 需要关闭url-loader中的es6 处理方式
},{
// 处理文件压缩
exclude:'/\.(js|css|less|html|jpg|png|gif)$',
loader: 'file-loader',
options:{
// 输出目录到 source 目录下
outputPath:'source'
}
}
]
},
// 插件 plugins 作用引入三方功能,处理特定问题
plugins:[
// new 调用
new MiniCssExtractPlugin({
// hash 、 chunckhash 、contenthash 特殊文件命名 解决代码迭代时,取缓存代码不更新问题
// filename:'css/built.[hash:10].css',// 生成css文件放到css目录下
// filename:'css/built.[chunckhash:10].css',// 生成css文件放到css目录下
filename:'css/built.[contenthash:10].css',// 生成css文件放到css目录下
}),
new OptimizeCssAssetsWebpackPlugin(),// 压缩css
new HtmlWebpackPlugin({
// 加上html插件需要考虑 html 图片处理 需要加上html-loader以处理html文件中的图片
// 添加模板文件路径
template:'./src/index.html',
minify:{
//压缩空格
collapseWhitespace:true,
//去除 html注释
removeComments: true
}
}),
// PWA技术 可以使网站离线也能访问。
// WrokboxWebpackPlugin 加载之后,网站离线也能发访问。
new WrokboxWebpackPlugin.GenerateSW({
/*
1. 帮助serviceworker快速启动
2. 删除旧的 serviceworker
*/
/*
使用workbox 需要在入口js文件中 做兼容性处理和WrokboxWebpackPlugin生成的serviceworker文件加载
在入口js文件中:
if('serviceWorker' in navigator){
window.addEventListener('load',()=>{
navigator.serviceworker.register('/service-worker.js')
.then(()=>{
console.log('sw注册成功~');
})
.catch(()=>{
console.log('sw注册失败~');
})
})
}
*/
clientsClaim: true,
skipWaiting: true,
}),
],
// 打包模式 production 生产 development 开发
// 生产模式下,会自动压缩js代码
mode:'development',
// devServer 开发调式服务器
// 运行 npx webpack-dev-server 启动
devServer:{
//contentBase: resolve(__dirname,'build'), // contentBase 已经淘汰 现在使用static
static:resolve(__dirname,'build'),
compress: true, // 是否压缩
port:3000, //端口号
open:true, // 开启开发调式服务器
hot:true, // 热更新功能提高开发环境性能
},
/* devtool 打包生成map文件
主要分为开发和生产环境
source-map // 能提供错误和精确位置便于调式
hidden-source-map 隐藏错误位置和内容
inline-source-map
eval-source-map // 能提供错误和精确位置便于调式
nosources-source-map 提供错误内容 不提供错误带啊
cheap-source-map 能提供代码所在行错误和精确位置便于调式
cheap-module-source-map 能提供错误和精确位置便于调式
*/
devtool:'source-map',
/*
oneof 提升构建速度
// 打包模块
module:{
rules:[
{
// 对多个多个匹配文件 匹配其中一个。。主要作用提升构建速度
// 但对于多次处理的文件,不放入
oneof:[
{
// 匹配后缀为.css文件
text:/\.css/$,
use:[
'style-loader', // 在将变为js文件,挂载到style上
'css-loader', // 处理css文件变为js
],
},{
text:/\.less/$,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
{
loader:'postcss-loader',
options:{
ident:'postcss',
plugins:() => [
require('postcss-preset-env')()
],
},
},
'less-loader',
],
},
]
}
]
},
*/
/****
* tree_shaking // 树摇 去除应用程序中无用代码
* 1、 前提使用es6模块,2、必须在生产环境 production 下进行
*
*
* /
/**
*
* code_split 代码分割打包,
* optimization:{
splitChunks:{
chunks:'all'
}
} 能将node_modules 文件单独打包
* 避免重复打包
如果想使自己引入的JS文件单独打包,需要使用es6的import方法进行引入
import('./xxx.js').then(()=>{}).catch(()=>{}); 这样引入就可以单独打包了
代码懒加载:
把引入文件放入,一个需要执行的时的异步回调中。以点击按钮加载为例
document.getElementById('btn').onclick = function(){
import('./xxx.js').then(()=>{}).catch(()=>{});
};
*/
optimization:{
splitChunks:{
chunks:'all'
}
},
// 禁止一些包,打包到输入文件中。提示:主要用于不想将引入文件打包,而采用CDN方式引用。
externals:{
// 以禁止打包Jquery 为例
jquery: 'jQuery',
},
// dll 单独打包库文件 使用dll 技术对某些第三方库:jquery、react、vue... 进行单独打包
// 运行时 webpack 时,默认查找 webpack.config.js 配置文件
// 但需要文件名不是默认文件名称时,需要 webpack --config jq.dll.js
/*
// 以单独打包 jquery 为例
// 首先需要 新建一个 jq.dll.js 文件
// resolve、 webpack需要先引入
const { resolve } = requier('path');
const webpack = requier('webpack');
module.exports = {
entry:{
// 最终打包生成的[name]
jquery:['jquery'],
},
output:{
filename:'[name].js',
path:resolve(__dirname,'dll'),
library:'[name]_[hash]',// 打包的库里面向外暴露出去的内容加什么名字
},
plugin:[
// webpack.DllPlugin 打包生成一个 manifest.json ————>提供和jquery映射
new webpack.DllPlugin({
name:'[name]_[hash]',// 映射库的暴露内容名称
path:resolve(__dirname,'dll/manifest.json'),// 输出文件路径
});
mode:'production',
],
}
// 打包完成后生成的JS文件 在需要引用地方,plugins 中引入
// webpack.DllReferencePlugin 告诉webpack 不打包相应文件
// AddAssetHtmlWebpackPlugin 在打包后文件自动添加生成的jqury.js文件
/*
new webpack.DllReferencePlugin({
manifest: resolve(__dirname,'dll/manifest.json')
})
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname:'dll/jquery.js')
})
*/
}