webpack 会自动递归解析入口所需要加载的所有资源文件,是一个现代 javascript 应用程序的静态模块打包器,专注构建模块化项目。在 webpack 里一切文件皆模块。这样的好处是可以清楚的了解各模块之间的依赖关系,以便 webpack 进行组合与打包。在打包的过程中:通过 loader 使得 webpack 有能力调用外部的脚本或工具,实现对不同格式的文件的处理,然后再通过 plugins 进行功能的扩展,比如压缩文件、分割文件的处理等,然后进行打包。
(1)、调整webpack配置最简单的方式就是在vue.config.js中的 configureWebpack 选项提供一个对象
。该对象将会被webpack-merge合并如最终的webpack配置。在configureWebpack里可以配置webpack的loader和plugins等
(2)、Vue CLI 内部的 webpack 配置是通过webpack-chain
维护的。这个库提供了一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则和具名插件,并有机会在后期进入这些规则并对它们的选项进行修改。
它允许我们更细粒度的控制其内部配置。
-
stat:文件的“输入”大小,在任何转换(如缩小)之前,它被称为“stat-size”,因为它是从Webpack的stats对象获得的。
-
parsed:这是文件的“输出”大小。如果使用的是像 uglify 这样的 Webpack插件,那么这个值将反映代码的小型化。
-
gzipped:这是通过gzip压缩运行解析的包/模块的大小。
解决 uglifyjs-webpack-plugin 不兼容es6问题
// 最新
module.exports = {
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
config.optimization.minimizer[0].options.terserOptions.compress.pure_funcs = ['console.log']
}
}
}
---
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
// 加密压缩(terser)
configureWebpack: config => {
const optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
warnings: false,
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log', 'console.error']
},
},
}),
],
}
// 将optimization的所有属性合并到config里
Object.assign(config, {
optimization
})
}
}
npm install -D compression-webpack-plugin
const CompressionWebpackPlugin = require("compression-webpack-plugin") // 引入
configureWebpack: config => {
config.plugins.push(
new CompressionWebpackPlugin({
algorithm: "gzip",
filename: "[path].gz[query]",
test: productionGzips,
threshold: 10240, // 只有大小大于该值的资源会被处理
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false, // 删除原文件
}),
)
}
npm install -D babel-polyfill 解决ie11兼容ES6,但同时会增加打包体积
// 引入
chainWebpack: config => {
// ============解决ie11兼容ES6 start==========
config.entry('main').add('babel-polyfill')
// ============解决ie11兼容ES6 end============
}
const tsImportPluginFactory = require("ts-import-plugin")
{
chainWebpack: config => {
config.module
.rule("ts")
.use("ts-loader")
.tap(options => {
options = merge(options, {
transpileOnly: true,
getCustomTransformers: () => ({
before: [
tsImportPluginFactory({
libraryName: "vant",
libraryDirectory: "es",
style: true,
})
]
}),
compilerOptions: {
module: "es2015",
}
})
return options
})
}
}
(1)、参考 1
(2)、参考 2
BundleAnalyzerPlugin 是分析 Webpack 生成的包体组成并且以可视化的方式反馈给开发者的插件
若是项目无package或其他变化,下次就不用花费时间重新构建,直接复用缓存。
将指定的内容排除在构建的vendor中,但是,指定的内容需要出现在用户环境中。
预编译资源模块,加快打包速度
-
样式:
style-loader、css-loader、less-loader、sass-loader等 -
文件:
raw-loader、file-loader 、url-loader等 -
编译:
babel-loader、coffee-loader 、ts-loader等 -
校验测试:
mocha-loader、jshint-loader 、eslint-loader等
ParallelUglifyPlugin 插件则会开启多个子进程,把对多个文件压缩的工作分别给多个子进程去完成,但是每个子进程还是通过UglifyJS去压缩代码。无非就是变成了并行处理该压缩了,并行处理多个子任务,效率会更加的提高。
-
把在 HappyPack 中的多进程并行处理的思想也引入到代码压缩中;
-
使用 ParallelUglifyPlugin 也非常简单,把原来Webpack配置文件中内置的 UglifyJsPlugin 去掉后,再替换成 ParallelUglifyPlugin;
构建优化 -ParallelUglifyPlugin --|-- 构建优化 -使用 HappyPack
// 引入 ParallelUglifyPlugin 插件
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
{
configureWebpack: config => {
// 生产环境打包分析体积
if (isDev === 'production') {
config.plugins.push(
new ParallelUglifyPlugin({
// 传递给 UglifyJS 的参数
uglifyJS: {
output: {
// 最紧凑的输出
beautify: false,
// 删除所有的注释
comments: false
},
warnings: false,
compress: {
reduce_vars: true,
drop_debugger: true,
drop_console: true
}
},
test: /.js$/g,
sourceMap: false // 是否为压缩后的代码生成对应的Source Map
})
)
}
},
}
const path = require('path')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const CompressionPlugin = require("compression-webpack-plugin") // 开启压缩gzip
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
// 定义getAliasPath方法,把相对路径转换成绝对路径
function resolve(dir) { return path.join(__dirname, dir)}
const isDev = process.env.NODE_ENV; //当前的环境
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
const isDevCS = {
'/api': {
target: 'http://114.5200.165.42:6100',
changeOrigin: isDev === 'development' ? true : false,
wx: true,
pathRewrite: {
"^/api": "/"
}
}
}
module.exports = {
runtimeCompiler: true,
productionSourceMap: false,
lintOnSave: false,
devServer: {
open: false,
https: false,
proxy: isDevCS
},
transpileDependencies: [],
/*
* 链式操作:
* - 允许对内部的webpack配置进行更细粒度的修改
*/
chainWebpack: (config) => {
// 缩小文件检索解析范围
config.resolve.alias
.set('@', resolve('src'))
.set('aset', resolve('src/assets/img'))
.set('cpts', resolve('src/components'))
if (isDev === 'production') {
return {
plugins: [
// 移除 prefetch 插件
config.plugins.delete('prefetch')
// 移除 preload 插件
config.plugins.delete('preload');
]
}
}
},
// 生产环境禁用eslint
lintOnSave: !process.env.NODE_ENV !== 'production',
/*
* 简单配置 loader和plugins
* - 生产环境打包分析体积
*/
configureWebpack: config => {
if (isDev === 'production') {
config.mode = "production";
config.plugins.push(
new UglifyJsPlugin({
// 删除debugger和console
uglifyOptions: {
compress: {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
},
warnings: false,
},
sourceMap: false,
parallel: true, // 多进程并行来提高构建速度
}),
// 压缩代码
new CompressionPlugin({
algorithm: 'gzip',
filename: '[path].gz[query]',
test: productionGzipExtensions,
threshold: 10240,
minRatio: 0.8,
deleteOriginalAssets: false // 是否删除源文件
}),
// 压缩分析提示
new BundleAnalyzerPlugin()
)
} else {
// 为开发环境修改配置...
config.mode = "development";
}
},
/**
* webpack的css的一些loader
* - 支持的 loader:
* css-loader, postcss-loader, sass-loader, less-loader, stylus-loader
*/
css: {
extract: false, //是否使用css分离插件
modules: false,
sourceMap: process.env.NODE_ENV === "production" ? false : true,
loaderOptions: {
sass: {
data: `
@import "@/style/mixin.scss";
@import "@/style/_var.scss";
`
},
// 传递给 postcss-loader
postcss : {
}
}
},
// 第三方插件的选项
pluginOptions: {}
}