1 Star 0 Fork 0

WFSWFS/webpackStudying

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
webpack.config.js 29.27 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
// webpack 做的事: 静态资源打包器 将js jquery less css vue 等 bunch (代码块)打包成bundle.js ==> 能在浏览器运行 被浏览器识别
// entry 入口
// outPut输出口
// loader 翻译 非js能识别的东西
/*loader的标准使用方式:
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {}
},
...
]
}
]
}*/
// plugin 扩展功能
// mode: 开发模式 development 与生产模式 production(做的事情更多)
/*
webpack.config.js webpack的配置文件
作用: 指示 webpack 干哪些活(当你运行 webpack 指令时,会加载里面的配置)
所有构建工具都是基于nodejs平台运行的 ~ 模块化默认 采用commonjs 。 而前端项目采用的是ES6 不要混淆
loader: 1. 下载 2. 使用(配置loader)
plugins: 1. 下载 2. 引入 3. 使用
*/
// resolve用来拼接绝对路径的方法
const {resolve} = require('path');
console.log("__dirname:", __dirname)
// 设置nodejs环境变量 开发环境才会生效
process.env.NODE_ENV = 'development';
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 处理html的plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');//★单独提取css
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')//压缩css★
// const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); //压缩js
// const TerserWebpackPlugin = require('terser-webpack-plugin') // 了解 在optimization配置
/*PWA: 渐进式网络开发应用程序(离线可访问) 兼容性问题 使用的不多 使用 workbox --> 下载workbox-webpack-plugin 了解学习*/
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');//安装 webpack插件
//dll的使用
const webpack = require('webpack');
//
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
/*// 代码分割js的方式1: 多入口 一个js 指定输出一个js
entry: {
// 多入口:几个入口,最终输出就对应几个bundle.js
index: './src/js/index.js',
test2: './src/js/test2.js'
},
// 输出
output: {
// [name]:取文件名
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},*/
/*
entry: 入口起点 详细配置
1. string --> './src/index.js'
单入口
打包形成一个chunk。 输出一个bundle文件。
此时chunk的名称默认是 main
2. array --> ['./src/index.js', './src/add.js']
多入口
所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
--> 只有在HMR功能中让html热更新生效~才会用这种
3. object
多入口 1进js对应1个输出js
有几个入口文件就形成几个chunk,输出几个bundle文件
此时chunk的名称是 key
--> 23 混用
{
// 所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
index: ['./src/index.js', './src/count.js'],
// 形成一个chunk,输出一个bundle文件。
add: './src/add.js'
}
*/
// webpack配置
module.exports = {
// 入口起点
// entry: ['./src/index.js','./src/index.html'], html的hmr 不用做
entry: './src/index.js',
target:"web",
// 输出
output: {
// filename: 'js/built[hash:10].js', // 输出文件名 C:\Users\16674\Documents\webpackStudying/build/js/built.js(使用webpack 打包才有作用)
filename: 'js/built[contenthash:10].js',
path: resolve(__dirname, 'build'),// 输出路径 __dirname是nodejs的变量,代表当前文件的目录绝对路径 ==> C:\Users\16674\Documents\webpackStudying
// 所有资源引入公共路径前缀 比如打包后的html里面引入 --> eg: 'imgs/a.jpg' ==> '/imgs/a.jpg'
// publicPath: '/',
// chunkFilename: 'js/[name]_chunkkk.js', // 修改非入口chunk的名称 不设置用的规则就是filename的规则
// library: '[name]', // 整个库向外暴露的变量名
// libraryTarget: 'window' // 变量名添加到哪个上 browser
// libraryTarget: 'global' // 变量名添加到哪个上 node
// libraryTarget: 'commonjs'
},
// loader的配置 作用: 识别js 不能识别的资源
// oneOf 匹配一个loader 之后就不会继续往下找 提高性能
module: {
rules: [
{
test: /\.js$/,
//要排除
exclude: /node_modules/,
loader: 'eslint-loader',
enforce:'pre',
options: {
// 自动修复 (你写的代码hui被eslint识别并改正) 会有警告 不会爆红
fix: true
}
},
{
// 以下loader只会匹配一个 主要为了提升性能
// 注意:不能有两个配置处理同一种类型(css js)文件 要提出来一个
// oneOf 找到即用 不会无脑找下去
oneOf:[
// 详细loader配置
// 不同文件必须配置不同loader处理
{
// test: 匹配哪些文件
test: /\.css$/,
// use: 使用哪些loader进行处理 ;use数组中loader执行顺序:从右到左,从下到上 依次执行
// 普通配置
/* use: [
// 创建style标签,将js中的样式资源插入进去,添加到head中生效 // 要下载
'style-loader',
// 将css文件变成commonjs模块加载js中,里面内容是样式字符串 // 要下载
'css-loader'
],*/
// 提取css成为单独的css文件的 配置
use: [
// 'style-loader' 创建style标签,将样式放入
// 这个loader只取代style-loader。作用:提取js中的css成单独文件★
MiniCssExtractPlugin.loader,
// 将css文件整合到js文件中
'css-loader',
// 'style-loader',
/* 这些都在package.json中配置即可
css兼容性处理:postcss --> 下载postcss-loader 和postcss-preset-env
帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式
//去guihub找
"browserslist": {
// 开发环境配置(要想开发环境需要)设置node环境变量:process.env.NODE_ENV = development 才有效果
//兼容最近的一个浏览器版本
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
// 生产环境:默认是看生产环境
"production": [
//或者更小
">0.2%",
//不要ie
"not dead",
//不要 op_mini
"not op_mini all"
]
}
*/
// css兼容性处理 postcss-loader的配置
// 正确的写法
{
loader: 'postcss-loader',
options: {
// 包裹一层postcssOptions
postcssOptions: {
plugins: [
['postcss-preset-env',{}]
]
}
}
},
]
},
// 将less 也合并到css里面去(暂时别做会有问题)
{
test: /\.less$/,
use: [
{loader:'style-loader'},
{loader:'css-loader'},
{loader:'less-loader'}
]
/* use: [
// 'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
// 包裹一层postcssOptions
postcssOptions: {
plugins: [
['postcss-preset-env',{}]
]
}
}
},
// 将less文件编译成css文件 需要下载 less-loader和less
'less-loader'
]*/
},
{
// 问题:默认处理不了html中img图片
// 处理图片资源
test: /\.(jpg|png|gif|jepg)$/,
// 使用一个loader
// 下载 url-loader 依赖于file-loader 所以俩都得下载
loader: 'url-loader',
options: {
/*图片大小小于8kb,就会被base64处理 webpack的处理build文件目录下不会显示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]',
/* 给打包后的图片重新命名 img:文件夹名字 [name]原文件名字 + 8位(原24位)hash值.扩展名
name:'img/[name].[hash:8].[ext]'*/
outputPath: "assets"
}
},
//处理html src里面的图片
{
test: /\.html$/,
// 处理html文件的img图片? ==> src的路径 (负责引入img,从而能被url-loader进行处理)
loader: 'html-loader'
},
//处理其他资源 比如阿里的字体图标 除了可以用test===include刷选 exclude也可以(优先级高)
// 打包其他资源(除了html/js/css资源以外的资源)
{
// 排除css|js|html|less|json|jpg|png|jepg资源
exclude: /\.(css|js|html|less|json|jpg|png|jepg)$/,
// include
use: [
{
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
/*
语法检查 规范代码: 下载安装eslint-loader , eslint
注意:只检查自己写的源代码,第三方的库是不用检查的
★ package.json中eslintConfig中设置~设置检查规则:
"eslintConfig": {
"extends": "airbnb-base"
}
怎么检查? 按...规则
js风格指南:airbnb --> 下载安装eslint-config-airbnb-base, eslint-plugin-import, eslint */
/*
正常来讲,一个文件只能被一个loader处理。
当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
必须先执行eslint 再执行babel 使用enforce:'pre' */
/* {
test: /\.js$/,
//要排除
exclude: /node_modules/,
loader: 'eslint-loader',
enforce:'pre',
include:resolve(__dirname,"src") // 只检查src下面的js文件
options: {
// 自动修复 (你写的代码hui被eslint识别并改正) 会有警告 不会爆红
fix: true
}
},*/
/* npm i --save-dev
js兼容性处理es6=>es5:@babel/core 核心库
1. 基本js兼容性处理 --> babel-loader @babel/preset-env
问题:目前只能转换基本语法,如promise高级语法不能转换
2. 全部js兼容性处理 --> @babel/polyfill(在js文件里面import引入即可)
问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~
3. 需要做兼容性处理的就做:按需加载 --> 下载core-js
一般是 第一步+第三步 完成最终配置
*/
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use:[
// 开启多进程打包(了解即可)。进程启动大概为600ms,进程通信也有开销;只有工作消耗时间比较长,才需要多进程打包
/* {
loader: 'thread-loader',
options: {
workers: 2 // 进程2个
}
},*/
{
loader: 'babel-loader',
options: {
// 预设:指示babel做怎么样的兼容性处理
presets: [
[
'@babel/preset-env',
{
// 这就是按需加载
useBuiltIns: 'usage',
// 针对ES6的 promise 等语法 识别不了
// 指定core-js版本 与下载版本一致
corejs: {
version: 3
},
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
],
// 性能优化: 开启babel缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory: true,
cacheCompression:false, // 关闭缓存文件压缩
// "plugins": ["@babel/plugin-transform-runtime"] 上述报错则安装以下这个 减少代码体积
}
}
]
}
]
}
]
},
// plugins的配置
plugins: [
// plugins的配置
// html-webpack-plugin
// 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS) 但是看不到css文件...
// 需求:需要有结构的HTML文件
new HtmlWebpackPlugin({
// template: 复制 './src/index.html' 文件,并自动(不要自己引)引入打包输出的所有资源(JS/CSS)
template: './src/index.html',
filename: 'index.html', // 输出的文件名
// 压缩html代码
minify: {
// html里面移除空格
// collapseWhitespace: true,
// html里面移除注释
// removeComments: true
}
}),
// 提取css (如何输出多个css文件?)
new MiniCssExtractPlugin({
// 对输出的css文件进行重命名 基于输出的path路径
// filename: 'css/built[hash:10].css',
filename: 'css/built[contenthash:10].css'
// filename: 'css/[name].css'
}),
// 压缩css★
new OptimizeCssAssetsWebpackPlugin(),
// new UglifyJsPlugin() // dev模式手动压缩js
//使用插件
new WorkboxWebpackPlugin.GenerateSW({
/*
1. 帮助serviceworker快速启动
2. 删除旧的 serviceworker
生成一个 serviceworker 配置文件~
*/
clientsClaim: true,
skipWaiting: true
}),
// 告诉webpack哪些库不参与打包(因为已经被webpack --config webpack.dll.js 打包过了 ),同时使用时的名称也得变~
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, 'dll/manifest.json')
}),
// 将webpack不参与打包 的库 自动引入该资源 到html中(webpack --config webpack.dll.js打包过后的文件)
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js')
})
],
/* 代码分割js的方式2 可以和方式1连用:
1. 可以将node_modules中代码单独打包一个chunk最终输出
2. 自动分析多入口chunk中,有没有公共的文件(例如多个js文件都引入了jq)。如果有会把jq打包成单独一个chunk,而不是多次打包jq
*/
optimization: {
splitChunks: {
chunks: 'all'
},
// 解决问题:修改a文件导致b文件的contenthash变化 (解决因某个js 的修改导致其他js的缓存失效)
runtimeChunk: {
name: (entrypoint) => `runtime-${entrypoint.name}`
},
},
// 模式
mode: 'development', // 开发模式
// mode: 'production' // 生产模式会默认多个js 压缩 (无需再去使用UglifyJsPlugin)
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动devServer指令为:npx webpack-dev-server
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, 'build'),
// contentBase:"./build",
inline:true, //是否实时监听
// 监视 contentBase 目录下的所有文件,一旦文件变化就会 reload
watchContentBase: true,
watchOptions: {
// 忽略(不监视哪些)文件
ignored: /node_modules/
},
compress: true, // 启动gzip压缩
// host:'192.168.0.100', // 项目启用地址 ==>手机也能访问
port: 3001, // 默认8080
open: true, // 自动打开浏览器
clientLogLevel: 'none', // 不要显示启动服务器日志信息
quiet: true, // 除了一些基本启动信息以外,其他内容都不要显示
overlay:true,//(浏览器错误遮罩)
hot:true , //开启热部署
/* historyApiFallback() {
}*/
// 服务器代理
proxy: {
// 一旦devServer(3001)服务器接受到 /api/xxx 的请求,就会把请求转发到另外一个服务器(3000)
// Axios发送请求代码里面有/api的时候生效
'/api': {
target: 'http://localhost:3000',
pathRewrite: {
'^/api': ''
}
}
}
},
// devtool: 'source-map', 基本配置
devtool: 'eval-source-map',
// externals防止将某些 import 的包(package)打包到 bundle 中,这个有用
// 而是在运行时(runtime)再去从外部获取这些扩展依赖
externals: {
// 拒绝jQuery被打包进来(针对CSDN引入)
// jquery: 'jQuery'
},
// resolve:解析模块的规则
resolve: {
// 引入别名配置
alias: {
//用的时候用前面的
$css: resolve(__dirname, 'src/css'),
'@': resolve('src'),
},
// 配置省略文件路径的后缀名(知道为啥 有时候不需要写 xxx.jsx xxx.vue 的后缀了吧)
extensions: ['.js', '.json', '.jsx', '.css'],
// 告诉 webpack 解析模块是去找哪个目录 这里是直接去外面找 node_modules
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
}
}
/* 性能优化1
HMR: hot module replacement 热模块替换 / 模块热替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)
极大提升构建速度
css样式文件:可以使用HMR功能:因为style-loader内部实现了~ use ['style-loader','css-loader'] ★★★★★
js文件:默认不能使用HMR功能 --> 需要修改js代码,添加支持HMR功能的代码
注意:HMR功能对js的处理,只能处理非入口js文件的其他文件(但是HMR代码写在index.js里面
html无需HMR 因为只有一个html文件 (html的hmr 不用做)
html文件: 默认不能使用HMR功能.同时会导致问题:html文件不能热更新了
解决:修改entry入口,将html文件引入
*/
/* 了解即可
source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
source-map:外部
浏览器显示 错误代码准确信息 和 源代码的错误位置
inline-source-map:内联
只生成一个内联source-map
浏览器显示 错误代码准确信息 和 源代码的错误位置
hidden-source-map:外部 (隐藏源码)
浏览器显示 错误代码错误原因,但是没有错误位置
浏览器 不能追踪源代码错误,只能提示到构建后代码的错误位置
eval-source-map:内联
每一个文件都生成对应的source-map,都在eval函数中
浏览器显示 错误代码准确信息 和 源代码的错误位置
nosources-source-map:外部 (隐藏源码)
浏览器有 错误代码准确信息, 但是没有任何源代码信息(定位不到源代码)
cheap-source-map:外部
错误代码准确信息 和 源代码的错误位置
浏览器的 错误代码信息 只能精确到某行
cheap-module-source-map:外部
浏览器有 错误代码准确信息 和 源代码的错误位置
module会将loader的source map加入
内联 和 外部的区别:1. 外部生成相应文件,内联没有 2. 内联构建速度更快
开发环境考虑:考虑 速度快,调试更友好
速度快慢程度(eval>inline>cheap>...)
eval-cheap-souce-map 最快
eval-source-map 快
调试友好程度
souce-map
cheap-module-souce-map 最友好
cheap-souce-map
折中点:使用eval-source-map||eval-cheap-module-souce-map
生产环境考虑:源代码要不要隐藏? 调试要不要更友好
生产环境一律不用内联 因为会使代码体积变大
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
折中:source-map / cheap-module-souce-map
*/
/*
性能优化2:缓存问题
1 babel缓存
cacheDirectory: true 目的:让第二次打包构建速度更快 ★★★
2 文件资源缓存
hash: 每次webpack构建(运行一下)时会生成一个唯一的hash值。
问题: 因为js和css同时使用一个hash值。
如果重新打包,会导致 所有缓存失效。(虽然可能我只改动一个文件)
chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
问题: js和css的hash值还是一样的
因为css是在js中被引入的,所以同属于一个chunk
(所以用这个)★★★★★ contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样
--> 让代码上线运行缓存更好使用 ★★★
*/
/*性能优化3: tree shaking ==>去除 无用代码
前提:1. 必须使用ES6模块化 2. 开启production环境 此时自动开启tree shaking ★★★★★ (自动js丑化压缩)
作用: 减少代码体积(例如有些函数虽然声明了但是没有使用 就会被树妖)
在package.json中配置
"sideEffects": false 所有代码都没有副作用(都进行tree shaking)
问题:可能会把css / @babel/polyfill (直接引用没有使用的文件副作用)干掉
任意的css less 不会进行tree shaking 结果就是 打包过后就会有 css...etc
"sideEffects": ["*.css", "*.less"]
*/
/*
代码分割1 配置多入口
代码分割2 配置optimization
戴码分割3 抛弃1,使用2并 在js文件配置 单独打包该js文件 形成方式3 一般用这个
*/
/*
optimization生产环境配置
splitChunks runtimeChunk minimizer 平行配置
optimization: {
splitChunks: {
chunks: 'all'
// 默认值,可以不写~
/!* minSize: 30 * 1024, // 分割的chunk最小为30kb
maxSiza: 0, // 最大没有限制
minChunks: 1, // 要提取的chunk最少被引用1次
maxAsyncRequests: 5, // 按需加载时并行加载的文件的最大数量
maxInitialRequests: 3, // 入口js文件最大并行请求数量
automaticNameDelimiter: '~', // 名称连接符
name: true, // 可以使用命名规则
cacheGroups: {
// 分割chunk的组
// node_modules文件会被打包到 vendors 组的chunk中。--> vendors~xxx.js
// 满足上面的公共规则,如:大小超过30kb,至少被引用一次。
vendors: {
test: /[\\/]node_modules[\\/]/,
// 优先级
priority: -10
},
default: {
// 要提取的chunk最少被引用2次
minChunks: 2,
// 优先级稍微低一点
priority: -20,
// 如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块 提速
比如JQ打包成一个chunk之后复用不会被重复打包
reuseExistingChunk: true
}
}*!/
},
// 将当前模块的记录其他模块的hash单独打包为一个文件 runtime 形成一对一关系
// 解决问题:修改a文件导致b文件的contenthash变化 (解决因某个js 的修改导致其他js的缓存失效)
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
},
minimizer: [
// 代替unify丑化 生产环境的压缩方案:js和css
new TerserWebpackPlugin({
// 开启缓存
cache: true,
// 开启多进程打包
parallel: true,
// 启动source-map
sourceMap: true
})
]
}*/
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/WFSWFS_admin/webpackStudying.git
git@gitee.com:WFSWFS_admin/webpackStudying.git
WFSWFS_admin
webpackStudying
webpackStudying
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385