webpack4.x从0开始构建多页项目(三)-插件及loader配置.
1.转换 ES6 代码,解决浏览器兼容问题
用 babel 转换 ES6 代码需要使用到 babel-loader ,我们需要安装一系列的依赖:
cnpm i babel-core babel-loader babel-preset-env --save-dev
使用 babel-polyfill 解决兼容性问题
npm i babel-polyfill babel-plugin-transform-runtime --save-dev
在webpack.rules.conf.js中添加如下配置
{
test: /\.js$/,
exclude: /(node_modules)/,
include: /src/, //限制范围,提高打包速度
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env',],
plugins: ['@babel/transform-runtime']
}
}
]
},
然后在根目录新建一个babel配置文件 .babelrc:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"modules": false
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": false,
"helpers": false,
"regenerator": false,
"useESModules": false
}
]
],
"comments": false
}
2.使用scss编译css,自动添加前缀
安装依赖
cnpm i mini-css-extract-plugin css-loader style-loader postcss-loader sass-loader node-sass --save-dev
//分离css,webpack4推荐的分离css的插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
在webpack.rules.conf.js中添加如下配置
{
test: /\.(css|scss|sass)$/,
use: process.env.NODE_ENV === "development" ? ["style-loader", "css-loader", "sass-loader", "postcss-loader"] :
[MiniCssExtractPlugin.loader, "css-loader", "postcss-loader", "sass-loader"],
include: /src/, //限制范围,提高打包速度
exclude: /node_modules/
},
然后在根目录新建一个配置文件 postcss.config.js:
module.exports = {
plugins: [
require('autoprefixer')
]
};
3.消除冗余的css(需要引入一个额外包glob用于扫描路径)
cnpm i purifycss-webpack purify-css -D
const PurifyCssWebpack = require('purifycss-webpack');
// 在plugins中配置
new purifyCssWebpack({
paths: glob.sync(path.join(__dirname, "../src/pages/*/*.html"))
}),
4.压缩 js
cnpm install uglifyjs-webpack-plugin --save-dev
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
// 在optimization中配置
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
// sourceMap: true // set to true if you want JS source maps
}),
]
},
5.压缩 CSS
cnpm i -D optimize-css-assets-webpack-plugin
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
// 在optimization中配置
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})]
}
6.清理 dist 目录
每次构建,我们的 /dist 文件夹都会保存生成的文件,然后就会非常杂乱。
通常,在每次构建前清理 /dist 文件夹,是比较推荐的做法
cnpm install clean-webpack-plugin --save-dev
const CleanWebpackPlugin = require('clean-webpack-plugin');
// 在plugins中配置
new cleanWebpackPlugin(['dist'], {
root: path.resolve(__dirname, '../'), //根目录
// verbose Write logs to console.
verbose: true, //开启在控制台输出信息
// dry Use boolean "true" to test/emulate delete. (will not remove files).
// Default: false - remove files
dry: false,
}),
7.加载图片与图片优化
在css引入图片运行打包发现如下错误:
ERROR in ./src/assets/images/test.jpg 1:0
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
解决方案:file-loader处理文件的导入
cnpm install --save-dev file-loader
// 在rules中配置
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
更进一步处理图片成 base64
cnpm install --save-dev url-loader
cnpm install image-webpack-loader --save-dev
// 在rules中配置
{
test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: "url-loader",
options: {
limit: 5 * 1024, //小于这个时将会已base64位图片打包处理
// 图片文件输出的文件夹
publicPath: "../images",
outputPath: "images"
}
},
{
loader: 'image-webpack-loader', // 进行图片优化
}
]
}
8.字体的处理(同图片)
由于 css 中可能引用到自定义的字体,处理也是跟图片一致。
// 在rules中配置
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
9.webpack4.x 提取公共代码
当一部分代码需要反复被用到,反复请求浪费资源,将公共代码 抽离,需要时读取缓存即可
webpack4 最大的改动就是废除了CommonsChunkPlugin 引入了 optimization.splitChunks
//splitChunks//常用配置
splitChunks: {
chunks: "async”,//默认作用于异步chunk,值为all/initial/async/function(chunk),值为function时第一个参数为遍历所有入口chunk时的chunk模块,chunk._modules为chunk所有依赖的模块,通过chunk的名字和所有依赖模块的resource可以自由配置,会抽取所有满足条件chunk的公有模块,以及模块的所有依赖模块,包括css
minSize: 30000, //表示在压缩前的最小模块大小,默认值是30kb
minChunks: 1, // 表示被引用次数,默认为1;
maxAsyncRequests: 5, //所有异步请求不得超过5个
maxInitialRequests: 3, //初始话并行请求不得超过3个
automaticNameDelimiter:'~',//名称分隔符,默认是~
name: true, //打包后的名称,默认是chunk的名字通过分隔符(默认是~)分隔
cacheGroups: { //设置缓存组用来抽取满足不同规则的chunk,下面以生成common为例
common: {
name: 'common', //抽取的chunk的名字
chunks(chunk) { //同外层的参数配置,覆盖外层的chunks,以chunk为维度进行抽取
},
test(module, chunks) { //可以为字符串,正则表达式,函数,以module为维度进行抽取,只要是满足条件的module都会被抽取到该common的chunk中,为函数时第一个参数是遍历到的每一个模块,第二个参数是每一个引用到该模块的chunks数组。自己尝试过程中发现不能提取出css,待进一步验证。
},
priority: 10, //优先级,一个chunk很可能满足多个缓存组,会被抽取到优先级高的缓存组中
minChunks: 2, //最少被几个chunk引用
reuseExistingChunk: true,// 如果该chunk中引用了已经被抽取的chunk,直接引用该chunk,不会重复打包代码
enforce: true // 如果cacheGroup中没有设置minSize,则据此判断是否使用上层的minSize,true:则使用0,false:使用上层minSize
}
}
}
-
chunks: 表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all;
-
minSize: 表示在压缩前的最小模块大小,默认是30kb;
-
minChunks: 表示被引用次数,默认为1;
-
maxAsyncRequests: 最大的按需(异步)加载次数,默认为1;
-
maxInitialRequests: 最大的初始化加载次数,默认为1;
-
name: 拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成,如果是true,将自动生成基于块和缓存组键的名称。如果是字符串或函数将允许您使用自定义名称。如果名称与入口点名称匹配,则入口点将被删除。
-
automaticNameDelimiter:'',名称分隔符,默认是
-
cacheGroups: 缓存组。
在此次多页配置中配置如下:
optimization: {
splitChunks: { //分割代码块
cacheGroups: {
//抽离自己编写的脚本的公共代码(css,js)
commons: { //公共模块
name: "commons",
chunks: "initial", //入口处开始提取代码
minSize: 0, //代码最小多大,进行抽离
minChunks: 2, //代码复 2 次以上的抽离
},
vendor: {
// 抽离第三方插件
test: /node_modules/, // 指定是node_modules下的第三方包
chunks: 'initial',
name: 'vendor', // 打包后的文件名,任意命名
// 设置优先级,防止和自定义的公共代码提取时被覆盖,不进行打包
priority: 10
}
}
}
},
修改多页面配置的chunks为
Object.keys(entrys).forEach(function (element) {
htmlArray.push({
_html: element,
title: '',
//增加'vendor','commons'
chunks: ['vendor','commons', element]
})
})
10.在webpack中使用jquery
安装依赖
cnpm i expose-loader --save-dev
cnpm i jquery --save
在webpack.rules.conf.js中添加如下配置
//把关于jquery和expose-loader的配置放在所有的Loader之前,也就是第一个加载
{
// 得到jquery模块的绝对路径
test: require.resolve('jquery'),
// 将jquery绑定为window.jQuery
loader: 'expose-loader?jQuery!expose-loader?$'
}
在想引入jquery的页面加入如下代码
import $ from 'expose-loader?$!jquery'
注意:expose-loader的写法已经有了更新,之前的写法是
{
test: require.resolve('jquery'),
loader: 'expose?jQuery!expose?$'
},
网友评论