/*
开发环境配置
运行项目指令:
webpack 会将打包结果输出出去
npx webpack-dev-server 只会在内存中编译打包,没有输出
生产环境:
运行项目指令:
webpack 会将打包结果输出出去
*/
/*
babel缓存
cacheDirectory: true
--> 让第二次打包构建速度更快
文件资源缓存
hash: 每次webpack构建时会生成一个唯一的hash值
问题:因为js和css同时使用一个hash值
如果重新打包,会导致所有缓存失效(可能我却只改动一个文件)
chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
问题:js和css的hash值还是一样的
因为css是在js中被引入的,所以同属于一个chunk
contenthahs: 根据文件的内容生成hash值。不同文件hash值一定不一样
--> 让代码上线运行缓存更好使用
*/
/*
tree shaking: 去除无用代码
前提:1,、必须使用ES6模块化 2.开启production环境
作用:减少代码体积
在package.json中配置
"sideEffects": false 所有代码都没有副作用(都可以进行tree shaking)
问题:可能会把css / @babel/polyfill (副作用)文件干掉
"sideEffects": ["*.css", "*.less"]
*/
// 当修改了webpack配置,新配置要想生效,必须重新启动webpack服务
// loader与plugin都需要Npm install 才能正常使用
// resolve 用来拼接绝对路径
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
const webpack = require('webpack');
// 设置nodejs环境变量,下面设置的是开发环境,否则是生产环境
// process.env.NODE_ENV = development;
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss 的插件
require('postcss-preset-env')()
]
}
}
]
module.exports ={
// webpack配置
// 入口文件
entry: ['./src/index.js', './src/index.html'],
// 输出
output: {
// 输出文件名
filename: 'build.[contenthash:10].js',
// 输出路径
// __dirname nodejs的变量,代表当前文件的绝对路径
path: resolve(__dirname,'build')
},
// loader 的配置
module: {
rules: [
/*
语法检查:eslint-loader eslint
注意: 只检查自己写的源代码,第三方库是不用检查的
设置检查规则
package.json中eslintConfig中设置
airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint
*/
{
test: /\.js$/,
exclude: /node_modules/,
// 优先执行
enforce: 'pre',
loader: 'eslint-loader',
options: {
// 自动修复eslint报的错误
fix: true
}
},
{
// 以下loader只会匹配一个
// 注意:不能有两个配置处理同一种文件
oneOf: [
/*
正常来讲,一个文件只能被一个loader处理
当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序
先执行eslint 再执行babel
*/
// 详细loader配置
{
// 匹配哪些文件
test: /\.css$/, // 正则表达式,表示为以.css结尾的文件
// 使用哪些loader进行处
// 要使用多个loader处理用use
use:[
// use数组中loader执行顺序:从右到左,从下到上,依次执行
// 创建style标签,将js中的样式资源插入进行,添加到head中生效、
// 创建style标签,将样式放入
// 'style-loader',
// 这个loader取代style-loader 作用:提取js中css成单独文件
MiniCssExtractPlugin.loader,
// 将css文件变成commonjs模块加载到js中,里面内容是样式字符串
'css-loader',
/*
css兼容性处理:postcss --> postcss-loader postcss-preset-env
帮postcss找到package.json中browserslist(写在devDependencies的后面)里面的配置,通过配置加载指定的css兼容性样式
"browserslist": {
// 开发环境 --> 设置node环境变量:process.env.NODE_ENV = development
"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',css样式的兼容性处理
// 修改loader的配置
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss 的插件
require('postcss-preset-env')()
]
}
}
]
},
// 处理less文件
{
test: /\.less$/,
use:[...commonCssLoader,'less-loader']
},
// 处理图片资源
// 问题:默认处理不了html中img图片
{
test: /\.(jpg|png|gif)$/,
// 使用一个loader
// 需要下载url-loader和file-loader 因为url-loader依托于file-loader
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
// 优点:减少请求数量(减轻服务器压力)
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 8 *1024,
// 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
// 解析时会出现问题:[object Module]
// 解决:关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]取文件原来扩展名
name: '[hash:10].[ext]',
// 指定输出路径
// outputPath: 'imgs'
}
},
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader处理)
loader: 'html-loader'
},
// 打包其他资源(除了html/js/css资源以外的资源)
{
// 排除html/js/css
exclude: /\.(css|js|html|less|jpg|png|gif)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
},
/*
js兼容性处理: babel-loader @babel/core
1. 基本js兼容性处理 --> @babel/preset-env
问题: 只能转换基本语法,如promise高级语法不能转换
2. 全部js兼容性处理 --> @babel/polyfill
使用时需要将 `import '@babel/polyfill'`引入js文件
问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大
3. 需要做兼容性处理的就做 :按需加载 --> corejs
*/
{
test: /\.js$/,
exclude: /node_modules/,
use: [
/*
开启多进程打包
进程启动大概为600ms,进程通信也有开销
只有工作消耗时间比较长,才需要多进程打包
*/
{
loader: 'thread-loader',
options: {
workers: 2 // 两个进程
}
},
{
loader: 'babel-loader',
options: {
// 预设: 指示babel做怎么样的兼容性处理
presets: [
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: {
version: 3
},
// 指定兼容性做到哪个版本浏览器
targhets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
],
// 开启babel缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory: true
}
}
]
},
]
}
]
},
// plugins 的配置
plugins: [
//html-webpack-plugin
//功能:默认会创建一个空的html,自动引入打包输出的所有资源(js/css)
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出所有资源
template: './src/index.html',
// 压缩html代码
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注释
removeComments: true
}
}),
new MiniCssExtractPlugin({
// 对输出的css文件进行重命名
filename: 'css/build.[contenthash:10].css'
}),
// 压缩css
new OptimizeCssAssetsWebpackPlugin(),
/*
下面两个plugin的使用需要提前运行生成maninfest.json的code
使用dll技术,对某些库(第三方库:jquery、react、vue...)进行单独打包
当你运行webpack时,默认查找webpack.config.js配置文件
需求:需要运行webpack.dll.js文件
--> npx webpack --mode=production --config webpack.dll.js
const webpack = require('webpack')
const resolve = require('path')
module.exports = {
entry: {
// 最终打包生成的[name] --> jquery
// ['jquery'] --> 要打包的库是jquery
jquery: ['jquery']
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'dll'),
library: '[name]_[hash]', // 打包的库黎明向外暴露出去的内容叫什么名字
},
plugins: [
// 打包生成一个 manifest.json --> 提供和jquery 映射
new webpack.DllPlugin({
name: '[name]_[hash]', // 映射库的暴露的内容名称
path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径
})
],
mode: 'production'
}
// 告诉webpack哪些库不参与打包,同时使用时的名称也得变
new webpack.DllReferencePlugin({
manifest: resolve(__dirname,'dll/mainfest.json')
}),
// 将某个文件打包输出出去,并在html中自动引入该资源
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname,'dll/jquery.js')
})
*/
],
// 模式
// mode: 'development', // 开发环境
mode: 'production', // 生产环境(js代码会自动压缩)
// 开发服务器 devServer:用来自动化(自动变异,自动打开浏览器,自动刷新浏览器....)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动devServer指令为:npx webpack-dev-server
devServer: {
// 项目构建后的路径
contentBase: resolve(__dirname,'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open:true,
/*
HMR: hot module replacement 热模块替换 / 模块热替换
作用: 一个模块发生变化,只会重新打包这一个(而不是打包所有模块)
极大的提高打包速度
样式文件:可以使用HMR功能:因为style-loader内部实现了
js文件:默认不能使用HMR功能 --> 需要修改js代码,添加支持HMR
注意:HMR功能对js的处理,只能处理非入口js文件的其他文件
// 在js文件中写如下代码,表示一个判断如果有module.hot,则...
if(module.hot){
// 一旦module.hot 为true。说明开启了HMR功能 --> 让HMR功能代码生效
module.hot.accept('./print.js',function(){
// 方法会监听print.js文件的变化,一旦发生变化,其他模块不会重新打包构建
// 会执行后面的回调函数
...
})
}
html文件:默认不能使用HMR功能。同时会导致问题:html文件不能热更新了(不用做hmr功能)
解决:修改entry入口,将html文件引入
*/
// 开启HMR功能
hot: true
},
/*
source-map: 一种 提供源代码到构建后代码映射 技术(如果构建后代码出错了,通过映射可以追踪源代码错误)
[incline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
错误代码准确信息和源代码的错误位置
incline-source-map: 内联
1.只生成一个内联source-map
错误代码准确信息和源代码的错误位置
hidden-source-map外部
错误代码错误原因,但是没有错误位置
不能追踪到源代码错误,只能提示到构建后代码的错误位置
eval-source-map 内联
1. 每一个文件都生成对应的source-map,都在eval
nosources-source-map: 外部
错误代码准确信息但是没有任何源代码信息
cheap-source-map 外部
错误代码准确信息和源代码的错误位置
只能精确的行
cheap-module-source-map 外部
错误代码准确信息和源代码的错误位置
module会将loader的source map加入
内联和外部的区别z
1.外部生成了文件,内联没有
2.内联构建速度更快
开发环境:速度快,调试更友好
速度快(eval>incline>cheap>...)
eval-cheap-source-map
eval-source-map
调试更友好
source-map
cheap-module-source-map
cheap-source-map
--> eval-source-map 最推荐(react,Vue的脚手架使用的是这个)
生产环境:源代码要不要隐藏?调试要不要更有友好
内联会让代码体积变大,所以在生产环境下不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
--> source-map / cheap-module-source-map
*/
devtool: 'eval-source-map',
/*
1.可以将node_modules中代码单独打包一个chunk最终输出
2.自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
*/
// optimization: {
// splitChunks: {
// chunks: 'all'
// }
// }
externals: {
// 忽略库名 --npm包名
// 拒绝jquery被打包进来
jquery: 'jQuery'
}
};
webpack4学习笔记,记录了常用的配置,注释详细
最新推荐文章于 2024-05-24 09:25:29 发布
