const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir) // path.join(__dirname)设置绝对路径
}
let developmentPath = './' //开发环境-npm run serve时引用文件路径
let productionPath = './' //生产环境-npm run build打包后引用文件路径
// const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = ['js', 'css']
const Version = 'V6.1'
const Timestamp = new Date().getTime()
// 导出模块
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? productionPath : developmentPath, // 基本路径-引用文件的路
outputDir: __dirname + '/server/dist', //build之后静态文件输出路径,__dirname 是 Node.js 中的一个全局变量,表示当前模块的目录的绝对路径。在这个上下文中,__dirname 指的是 vue.config.js 文件所在的目录。
assetsDir: 'static', //打包后生成的静态资源目录,默认“ ” ,也就是我们打包后的css,js等存放的位置
lintOnSave: process.env.NODE_ENV !== 'production', // eslint-loader,是否在保存的时候检查
productionSourceMap: process.env.NODE_ENV !== 'production', //控制在生产环境中是否生成源映射(Source Map)文件 //源映射文件是一种用于将编译后的代码映射回原始源代码的文件,在开发环境中,通常会启用源映射,但是在生产环境中,为了减小文件体积,提高页面加载性能,通常会关闭生成源映射文件。因为源映射文件包含了源代码的信息,如果暴露给用户,可能会带来一些潜在的安全风险。
// 反向代理,devServer 是用于配置开发服务器的选项。
devServer: {
open: true, //启动项目自动打开浏览器
host: 'localhost', //默认打开域名
port: 8080, //默认打开端口号
https: false, //开启关闭https请求
proxy: {
// 配置跨域
'/api': {
target: 'http://dev.aabb.cn:8082/', //代理地址,这里设置的地址会代替axios中设置的baseURL
ws: true, proxy websockets
changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
pathRewrite: {
//pathRewrite方法重写url
'^/api': '/',
},
},
},
},
//声明配置webpack
chainWebpack: config => {
// 这两行代码用于在 Vue CLI 的 webpack 配置中删除 preload 和 prefetch 插件。有时你可能需要禁用或移除这个插件,特别是在特定场景下。
// 以下是一些可能需要删除preload 和 prefetch 插件这两个插件的情况:
// 1、资源过多导致带宽浪费: 当你的应用有很多静态资源,而用户可能只会访问应用的一小部分时,预加载和预取可能导致不必要的带宽浪费。在这种情况下,你可能会考虑禁用这两个插件。
// 2、资源已经内联或同步加载: 如果你的应用已经通过其他方式将关键资源内联到 HTML 中,或者你更喜欢同步加载资源,而不是异步加载,那么预加载和预取可能不再需要。
// 3、对首次加载性能敏感: 在某些情况下,如果你对首次加载性能非常敏感,你可能希望禁用预加载,以减少初始加载时间。这样可以确保页面仅加载必需的资源,延迟加载其他资源。
// 4、某些场景下的性能问题: 在某些情况下,使用预加载和预取可能会导致性能问题,特别是在一些网络条件下。在这种情况下,禁用这两个插件可能有助于提高用户体验。
config.plugins.delete('preload') //preload 插件用于预加载与初始页面加载相关的资源,以提高页面性能。
config.plugins.delete('prefetch') //prefetch 插件用于预取资源,通常是异步加载的模块。它可以在空闲时提前加载一些资源,以提高后续导航的速度。
// 在处理 SVG 文件的 webpack 规则中,排除了指定的目录。
config.module.rule('svg').exclude.add(resolve('src/assets/icons')).end()
// 用于处理 SVG 图标文件
// 每个 .rule()、.use()、.options() 等方法都会创建一个配置块。
config.module
.rule('icons') // 在 Vue CLI 的 webpack 配置中创建一个名为 'icons' 的规则。这个规则用于处理 SVG 图标文件。
.test(/\.svg$/) // 这是设置规则匹配的文件类型,即以 .svg 结尾的文件。这表示这个规则将用于处理 SVG 文件。
.include.add(resolve('src/assets/icons')) // 为规则指定包含的目录。它告诉webpack只在src/assets/icons目录下的 SVG 文件上应用这个规则。
.end() // 结束当前的配置块,返回到上一级配置块。
.use('svg-sprite-loader') // 这是告诉 webpack 在匹配到的文件上使用 svg-sprite-loader 这个 loader。
.loader('svg-sprite-loader') // 这是指定 loader 的名称,即使用 svg-sprite-loader 来处理 SVG 文件。
.options({
symbolId: 'icon-[name]', //这是为 svg-sprite-loader 提供的选项。在这里,设置了 symbolId 选项,用于生成每个 SVG 符号的 ID。这里的设置是生成的 ID 以 'icon-' 开头,后面跟随 SVG 文件的名称(不包含扩展名)
})
.end() // 结束当前的配置块,返回到上一级配置块。
const imagesRule = config.module.rule('images') // 创建一个名为 imagesRule 的变量,它是对处理图片的规则的引用。
imagesRule.uses.clear() // 清除原本与 imagesRule 相关的 loader 配置。这样做的目的是在重新配置图片处理规则时,清除掉默认配置,从而定制化配置。
imagesRule
.test(/\.(jpg|gif|png|svg)$/) // 设置图片规则的文件测试条件,即匹配以 .jpg、.gif、.png、.svg 结尾的文件。
.exclude.add(path.join(__dirname, '../node_modules')) // 设置排除的目录,即不对 node_modules 目录中的图片文件进行处理。通过 .exclude.add() 添加排除的目录,这里排除了 node_modules 中的图片文件。
.end() // 结束当前的配置块,返回到上一级配置块。
.use('url-loader') // 在图片规则中使用 url-loader,用于将图片文件转换成 Data URL,或者在文件大小超过指定阈值时,将图片文件复制到输出目录。
.loader('url-loader') // 指定使用 url-loader 这个 loader 来处理图片文件。
.options({ name: 'img/[name].[hash:8].[ext]', limit: 6000000 }) //配置 url-loader 的选项,设置生成的文件名称和转换的条件。
// name: 'img/[name].[hash:8].[ext]':生成的文件名将位于 img/ 目录下,包括原文件名、8 位哈希和原始文件的扩展名。
// limit: 6000000:当文件大小小于 6MB(即 6000000 字节)时,将文件转换成 Data URL,否则将文件复制到输出目录。
config.optimization.splitChunks({
//cacheGroups: 是 splitChunks 的一个配置项,用于配置缓存组。缓存组是一组满足特定条件的模块,它们会被拆分成一个单独的代码块。
cacheGroups: {
// vendors 缓存组:
vendors: {
name: 'chunk-vendors', // 生成的代码块的名称。
minChunks: 5, //表示至少有 pageNum 个入口文件共同依赖的模块才会被拆分到这个缓存组。这个值可以是一个数字或者 Infinity,表示共同依赖的模块数量的最小值。
test: /node_modules/, // 用于匹配需要被拆分的模块的路径。这里匹配了 node_modules 目录下的模块。
priority: -10, // 缓存组的优先级,数值越大,优先级越高。这里设置为负值,确保在拆分时优先考虑这个缓存组。
chunks: 'initial', // 表示只在初始加载时拆分模块
},
// elementUI 缓存组:
elementUI: {
name: 'chunk-elementUI', // 生成的代码块的名称。
priority: 20, // 优先级高于 vendors 缓存组,确保 element-ui 的模块在拆分时优先考虑。
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // /[\\/]node_modules[\\/]_?element-ui(.*)/:用于匹配 element-ui 模块的路径。
},
// commons 缓存组:
commons: {
name: 'chunk-commons', // 生成的代码块的名称。
test: resolve('src/components'), // :用于匹配需要被拆分的模块的路径,这里匹配了 src/components 目录下的模块。
minChunks: 3, // 表示至少有 3 个入口文件共同依赖的模块才会被拆分到这个缓存组。
priority: 5, // 优先级较低,确保在拆分时优先考虑前面的缓存组。
reuseExistingChunk: true, // 如果当前代码块已经被拆分过,可以重用它而不是创建一个新的代码块。
},
},
})
},
// webpack配置
configureWebpack: config => {
// 这是一个条件语句,表示只有在生产环境下才会执行以下的插件配置。
if (process.env.NODE_ENV === 'production') {
// 将配置项推入 webpack 配置的 plugins 数组中,以便在构建时应用这些插件。
config.plugins.push(
// UglifyJsPlugin要求的最小版本为 Node v6.9.0 和 Webpack v4.0.0 版本。但是到了Webpack5 terser-webpack-plugin 取代了之前版本的 uglifyjs-webpack-plugin
// 使用 UglifyJsPlugin 插件对代码进行压缩。
// new UglifyJsPlugin({
// // uglifyOptions 中的 compress 部分用于指定压缩选项,如删除
// uglifyOptions: {
// compress: {
// drop_debugger: true, //生产环境自动删除debugger
// drop_console: true, //生产环境自动删除console
// pure_funcs: ['console.log'], // 移除console
// },
// warnings: false, //禁用警告输出。
// },
// sourceMap: false, //关掉sourcemap 会生成对于调试的完整的.map文件,但同时也会减慢打包速度
// parallel: true, //使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。
// }),
new TerserPlugin({
//是一个对象,用于配置 Terser 压缩器的选项。
terserOptions: {
// 属性配置 Terser 的输出格式。
ecma: undefined, // ECMAScript 版本,默认为 5
parse: {}, // 解析器选项
// 压缩选项
compress: {
dead_code: true, // 删除无法访问的代码true
directives: true, //删除冗余或非标准指令true
drop_console: {
filter: node => {
if (node.arguments[0].name === 'err') {
// 保留 console.log(err)
return false
}
// 删除其他 console.log
return true
},
}, // 删除除console.log(err)的所有console.log
},
mangle: true, // 混淆选项,Note: `mangle.properties` 默认为 `false`
module: true, // 是否支持 ES6 模块语法,默认为 false
format: {
// comments: false 表示禁用压缩后的代码中的注释,以减小输出文件的体积。
comments: false,
},
toplevel: false, // 是否混淆顶级作用域的变量和函数名,默认为 false
nameCache: null, // 名称缓存,用于跨次构建保持混淆结果不变
ie8: true, // 是否兼容 IE8,默认为 false
keep_classnames: undefined, // 是否保留类名,默认为 undefined
keep_fnames: false, // 是否保留函数名,默认为 false
safari10: false, // 是否兼容 Safari 10,默认为 false
},
// extractComments 是一个布尔值,用于配置是否提取并保留源代码中的注释。在这里设置为 false,表示不提取注释,从而进一步减小输出文件的体积。
extractComments: false,
}),
// 实例化 CompressionWebpackPlugin 插件,用于对文件进行 gzip 压缩。
new CompressionWebpackPlugin({
// filename: '[path].gz[query]', // 设置压缩后的文件名格式,其中 [path] 表示原始文件路径,[query] 表示原始文件的查询参数(query)。
algorithm: 'gzip', //使用 gzip 算法进行压缩
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), //通过正则表达式匹配需要压缩的文件后缀。这里使用了 productionGzipExtensions 变量,该变量应该是一个包含文件后缀的数组。插件会匹配这些文件后缀的文件进行压缩。
threshold: 10240, //设置文件大小超过 10KB 才进行压缩。
minRatio: 0.8, // 设置压缩比例达到 80% 才进行压缩。。这个值表示压缩后的文件大小相对于原始文件大小的比例,只有达到设定的比例才进行压缩。
})
)
}
// 告诉 webpack 在构建时应该将哪些模块视为外部依赖,不需要被打包进最终的输出文件。
// 在这里配置后,减少了压缩的包内容,需要在public/index.html通过cdn方式再引入,注意对应的版本
config.externals = {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios',
}
// 这段代码使用了 Object.assign 方法,将一些配置合并到 config 对象中
Object.assign(config, {
// 这里配置了 webpack 的 resolve 属性
resolve: {
// alias 字段用于创建模块别名,使得在代码中引用模块时更加方便。
alias: {
'@': resolve(__dirname, './src'),
'@c': resolve(__dirname, './src/components'),
'@p': resolve(__dirname, './src/pages'),
},
},
})
// filename 属性指定了构建输出的主文件的文件名。这里使用了模板字符串,其中:
// [name] 表示入口点(entry)的名称,通常与入口文件的名称相对应。
// ${Version} 表示一个变量或标记,可能是项目的版本号。
// ${Timestamp} 表示一个时间戳,可能用于标记构建时间。
config.output.filename = `[name].${Version}.${Timestamp}.js` //打包生成的文件
// chunkFilename 属性指定了非入口点的代码块(chunk)的文件名。这些代码块通常是按需加载的模块或按需分割的代码。与 filename 类似,使用了模板字符串,其中的占位符与 filename 一致。
config.output.chunkFilename = `[name].${Version}.${Timestamp}.js`
},
// vue,适配方案 将像素(px)转换成vh 或者 vw
css: {
loaderOptions: {
postcss: {
postcssOptions: {
plugins: [
[
'postcss-px-to-viewport',
{
unitToConvert: 'px', // 需要转换的单位,默认为"px"
viewportWidth: 1920, // 设计稿的视口宽度
viewportHeight: 919, // 视窗的高度
unitPrecision: 5, // 单位转换后保留的精度
propList: ['*'], // 能转化为vw的属性列表
viewportUnit: 'vw', // 希望使用的视口单位
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
mediaQuery: false, // 媒体查询里的单位是否需要转换单位
replace: true, // 是否直接更换属性值,而不添加备用属性
exclude: undefined, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
landscapeUnit: 'vw', // 横屏时使用的单位
landscapeWidth: 1920, // 横屏时使用的视口宽度
},
],
],
},
},
},
},
}
vue.config配置
于 2024-01-23 11:05:59 首次发布