loader优化
test、include、exclude三个配置项来缩小loader的处理范围
include、exclude只能使其一
include: path.resolve(__dirname, "./src"),
优化resolve.modules配置
resolve.modules⽤于配置webpack去哪些⽬录下寻找第三⽅模块,默认是
['node_modules']
寻找第三⽅模块,默认是在当前项⽬录下的node_modules⾥面去找,如果没有找 到,就会去上⼀级目录../node_modules找,再没有会去../../node_modules中找,以 此类推,和Node.js的模块寻找机制很类似。
如果我们的第三⽅模块都安装在了项⽬根目录下,就可以直接指明这个路径
module.exports={
resolve:{
modules: [path.resolve(__dirname, "./node_modules")]
}
}
优化resolve.alias配置
resolve.alias配置通过别名来将原导⼊路径映射成一个新的导⼊路径
默认情况下,webpack会从⼊口文件./node_modules/bin/react/index开始递归解 析和处理依赖的⽂件。我们可以直接指定文件,避免这处的耗时
resolve: {
alias: {
"@": path.join(__dirname, "./pages"),
react: path.resolve(
__dirname,
"./node_modules/react/umd/react.production.min.js"
),
"react-dom": path.resolve(
__dirname,
"./node_modules/react-dom/umd/react-dom.production.min.js"
)
}
}
优化resolve.extensions配置
resolve.extensions在导⼊语句没带文件后缀时,webpack会⾃动带上后缀后,去尝试 查找文件是否存在。
默认值
extensions:['.js','.json','.jsx','.ts']
使⽤静态资源路径publicPath
就是在输出的静态资源打包前添加目录,目录可以是本地目录,也可以是服务目录(CDN)
CDN通过将资源部署到世界各地,使得⽤户可以就近访问资源,加快访问速度。要接 ⼊CDN,需要把⽹页的静态资源上传到CDN服务上,在访问这些资源时,使用CDN服 务提供的URL
//webpack.config.js
output:{
publicPath: '//cdnURL.com', //指定存放JS⽂件的CDN地址
}
CSS处理
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"]
}
使⽤postcss为样式自动补齐浏览器前缀
// 新建postcss.config.js
module.exports = {
plugins: [
require("autoprefixer")({
overrideBrowserslist: ["last 2 versions", ">1%"]
})
]
};
//webpack.config.js
{
test: /\.less$/,
include: path.resolve(__dirname, "./src"),
use: [
"style-loader",
{
loader: "css-loader",
options: {}
},
"less-loader",
"postcss-loader"
]
},
如果不做抽取配置,我们的 css 是直接打包进 js ⾥面的,我们希望能单独生成 css ⽂件。 因为单独⽣成css,css可以和js并行下载,提⾼页⾯加载效率
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
{
test: /\.scss$/,
use: [
// "style-loader", // 不再需要style-loader,用MiniCssExtractPlugin.loader代替
MiniCssExtractPlugin.loader,
"css-loader", // 编译css
"postcss-loader",
"sass-loader" // 编译scss
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name]_[contenthash:6].css",
chunkFilename: "[id].css"
})
]
压缩css
- 借助 optimize-css-assets-webpack-plugin
- 借助cssnano(压缩规范)
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
new OptimizeCSSAssetsPlugin({
cssProcessor: require("cssnano"), //引入cssnano配置压缩选项 cssProcessorOptions: {
discardComments: { removeAll: true }
}
})
压缩HTML
new htmlWebpackPlugin({
title: "京东商城",
template: "./index.html",
filename: "index.html",
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换⾏符
minifyCSS: true // 压缩内联css
}
}),
development vs Production模式区分打包
- 两份配置
- 通过传参做区分
// package.json
"dev:build": "webpack --config ./test.config.js --env.production",
//env.production 默认为true
module.exports = env => {
if (env && env.production) {
return merge(baseConfig, proConfig);
} else {
return merge(baseConfig, devConfig);
}
};
- 通过环境变量做区分
//package.json
"test": "cross-env NODE_ENV=test webpack --config//兼容
"test": "NODE_ENV=test webpack --config // mac下无问题, win下有问题
// 在webpack.config.js⾥拿到参数
process.env.NODE_ENV
tree Shaking
Dead Code 一般具有以下几个特征
- 代码不会被执⾏,不可到达 代码执行的结果不会被用到
- 代码只会影响死变量(只写不读)
- Js tree shaking只⽀持ES module的引⼊方式!!!!,
1. Css tree shaking
npm i glob-all purify-css purifycss-webpack --save-dev
const PurifyCSS = require('purifycss-webpack')
const glob = require('glob-all')
plugins:[
// 清除⽆用 css
new PurifyCSS({
paths: glob.sync([
// 要做 CSS Tree Shaking 的路径文件
path.resolve(__dirname, './src/*.html'),
// 请注意,我们同样需要对 html js ⽂件进行 tree shaking
path.resolve(__dirname, './src/*.js')
])
})
]
2. JS tree shaking
只⽀持import⽅式引入,不支持commonjs的方式引入
//expo.js
export const add = (a, b) => {
return a + b;
}
export const minus = (a, b) => {
return a - b;
};
//index.js
import { add } from "./expo";
add(1, 2);
//webpack.config.js
optimization: {
usedExports: true // 哪些导出的模块被使⽤了,再做打包
}
// 只要mode是production就会生效,develpoment的tree shaking是不生效的,因为 webpack为了方便你的调试
只要mode是production就会⽣效,develpoment的tree shaking是不生效的,因为 webpack为了⽅便调试 可以查看打包后的代码注释以辨别是否生效。 ⽣产模式不需要配置,默认开启
usedExports: true 副作⽤
开启tree shaking 代码中引用的css 和图片会不生效
//package.json
"sideEffects":false //正常对所有模块进行tree shaking , 仅⽣产模式有效,需要配合usedExports
或者 在数组⾥面排除不需要tree shaking的模块
"sideEffects":['*.css','@babel/polyfill']
打包完后,所有⻚面只⽣成了⼀一个bundle.js
- 代码体积变大,不利利于下载
- 没有合理利用浏览器资源
其实code Splitting概念 与 webpack并没有直接的关系,只不过webpack中提供了一种 更加⽅便的⽅法供我们实现代码分割
optimization: {
// 自动帮我们做代码分割,默认支持异步
splitChunks: {
chunks: "all", // 所有的 chunks 代码公共的部分离出来成为⼀个单独的 文件
},
},
optimization: {
splitChunks: {
chunks: 'async', //对同步 initial,异步 async,所有的模块有效 all minSize: 30000, //最小尺寸,当模块大于30kb
maxSize: 0, //对模块进⾏二次分割时使用,不推荐使用
minChunks: 1, //打包⽣成的chunk⽂件最少有⼏个chunk引⽤了这个模块
maxAsyncRequests: 5, //最⼤异步请求数,默认5
maxInitialRequests:3,//最⼤初始化请求书,⼊口文件同步请求,默认3 automaticNameDelimiter: '-',//打包分割符号
name: true,//打包后的名称,除了了布尔值,还可以接收一个函数function cacheGroups: {//缓存组
vendors: {
test: /[\\/]node_modules[\\/]/,
name:"vendor", // 要缓存的 分隔出来的 chunk 名称
priority: -10//缓存组优先级 数字越⼤,优先级越高
},
other:{
chunks: "initial", // 必须三选⼀一: "initial" | "all" |"async"(默认就是async)
test: /react|lodash/, // 正则规则验证,如果符合就提取 chunk, name:"other",
minSize: 30000,
minChunks: 1,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true//可设置是否重用该chunk
}
}
} }
打包后的chunk