webpack5 入门学习笔记(三)生产环境配置

写在前面

生产环境中真的有很多需要注意的点,回顾的时候结合后面学的也更理解了。

webpack生产环境的基本配置

提取css成单独文件

定义
  • css 样式在打包后提取为单独文件,之前使用 style-loader 处理都是创建 style 标签,将样式放入
使用方法
  1. 安装插件
    	npm i mini-css-ectract-plugin -D
    
  2. module中配置
    	loader:MiniCssExtractPlugin.loader, //取代style-loader
    
  3. plugins配置
    	new MiniCssExtractPlugin({
            //对输出的css文件进行重命名
            filename:'css/built.css'
        })
    
要点记录
  1. css 文件成功提取为单独文件,但是多个 css 文件打包后只会输出一个文件

  2. 如果打包后样式无法正常显示,可以在 loader 处配置 options ,加上 publicPath:'./'

  3. 如果样式内容不是很多的话,提取到单个文件的效果不是很好。

  4. 建议 css 文件超过150kb左右,才考虑提取到单个文件中。
    css 嵌入到代码中,减少一次请求,效果可能更好。

代码实现
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
//将css提取为单独文件 下载插件mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/bundles.js',
        path: resolve(__dirname, 'dist'),
        clean:true //清理旧文件
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader, //取代style-loader,提取js中的css成单独文件
                    //创建style标签,将样式放入
                    //'style-loader'
                        options: {
                            publicPath:'./'
                        }
                    },
                    {
                        loader: 'css-loader', //将css文件整合到js文件中
                        options: {
                            import:true, //启用/禁用 @import 处理
                        }
                    }
                ]
            }
        ]
    },
    plugins:[ 
        new HtmlWebpackPlugin({
            template:'./src/index.html'
        }),
        new MiniCssExtractPlugin({
            //对输出的css文件进行重命名
            filename:'css/built.css'
        })
    ],
    mode:'development'
}

css 兼容性处理

定义
  • 不同的浏览器对同一段 css 代码有不同的解析,造成页面显示效果不统一的局面,这时候就需要对 css 代码进行兼容性处理
使用方法
  1. 安装插件
    	npm i postcss-loader postcss-preset-env -D
    
  2. package.jsonbrowserslist 配置
        //开发环境 默认是生产环境
    	"browserslist": {
    	    "development": [
    	      "last 1 chrome version",
    	      "last 1 firefox version",
    	      "last 1 safari version"
    	    ],
    	    "production": [
    	      ">0.2%",
    	      "not dead",
    	      "not op_mini all"
    	    ]
    	  }
    
  3. 使用
    	{
            loader: 'postcss-loader',//转换css
            options: {
                postcssOptions: {
                    ident: 'postcss',
                    plugins: [
                        require('postcss-preset-env')
                    ]
                }
                
            }
        }
    
要点记录
  1. browserslist 配置默认使用生产环境,可以通过设置 node 环境变量改变模式,决定使用 browserslist 的哪个环境:

       	 process.env.NODE_ENV = 'development'`
    
  2. webpack5 配置的时候,要将 postcss 配置放在 postcssOptions

  3. browserslist 是一个在不同的前端工具之间,共享目标浏览器和 Node.js 版本的配置

    • defaults Browserslist的默认配置(>0.5%,last 2 version, FireFox ESR, not dead)
    • 5% >= < <=全球超过5%人使用的浏览器
    • dead 24个月没有官方支持或者更新的浏览器
    • last 2 version 每个浏览器的最新的两个版本
    • node10 node14 针对node的版本
    • IOS7 直接使用ios7浏览器
    • not ie <=8 排除ie8以下
代码实现
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

//设置node环境变量:
//process.env.NODE_ENV = 'development'

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/bundles.js',
        path: resolve(__dirname, 'dist'),
        clean:true //清理旧文件
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader, //取代style-loader,提取js中的css成单独文件
                    //创建style标签,将样式放入
                    //'style-loader'
                        options: {
                            publicPath:'./'
                        }
                    },
                    {
                        loader: 'css-loader', //将css文件整合到js文件中
                        options: {
                            import:true, //启用/禁用 @import 处理
                        }
                    },
                    /**
                     * css兼容性处理:postcss --> postcss-loader postcss-preset-env 识别某些环境加载指定的配置,让兼容性更精确
                     * 帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式
                     * 
                     * "browserslist":{
                     * 开发环境-->设置node环境变量:process.env.NODE_ENV = development
                            "development":[
                            "last 1 chrome version",
                            "last 1 firefox version",
                            "last 1 safari version"
                            ],
                            开发环境 默认是生存环境
                            "production":[
                            ">0.2%",
                            "no dead",
                            "not op_mini all"
                            ]
                        }
                     * 
                     */
                    //使用loader的默认配置  
                    //'postcss-loader'
                    //修改loader配置
                    {
                        loader: 'postcss-loader',//转换css
                        options: {
                            postcssOptions: {
                                ident: 'postcss',
                                plugins: [
                                    //require('postcss-preset-env')()
                                    'postcss-preset-env'//效果一样,运行时还是会转化成requeire("")来运行。
                                    //但并不是所有的插件都可以简写,因为有些插件时需要传入额外的参数的,所以有些插件不能简写
                                ]
                            }
                            
                        }
                    }
                ]
                
            }
        ]
    },
    plugins:[ 
        new HtmlWebpackPlugin({
            template:'./src/index.html'
        }),
        new MiniCssExtractPlugin({
            //对输出的css文件进行重命名
            filename:'css/built.css'
        })
    ],
    mode:'development'
}

压缩css

定义
  • 最新方法查看 webpack 官网,压缩css
  • webpackproduction 模式下,会自动压缩优化打包的结果。
  • 但是单独提取的 css 文件并没有被压缩。
  • 这是因为 webpack 内置的压缩插件,仅仅支持 js 文件的压缩。
  • 对于其他类型的文件压缩,都需要额外的插件支持。
使用方法
  1. 安装插件
    	npm i css-minimizer-webpack-plugin -D
    
  2. 使用
    const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
    
    	optimization: {
    	    minimize: true, //默认在生产环境进行压缩,在开发环境要使用压缩就要设置minimize为true
    	    minimizer: [
    	      new CssMinimizerPlugin(),
    	    ],
    	  }
    
要点记录
  • 使用「css-minimizer-webpack-plugin」插件压缩样式文件
  • webpack官方文档介绍时并不是将「CssMinimizerPlugin」插件配置在「plugins」数组中。而是配置在 「optimization.minimizer」数组中。
  • 原因是:配置在「plugins」中,webpack就会在启动时使用这个插件。
  • 而配置在 「optimization.minimizer」 中,就只会在「optimization.minimize」这个特性开启(为true)时使用。
  • 所以webpack推荐,像压缩类的插件,应该配置在「optimization.minimizer」数组中。以便于通过「optimization.minimize」统一控制。(生产环境会默认开启minimize) 然而这样配置会导致JS不会被压缩。
  • 原因是webpack认为,如果配置了minimizer,就表示开发者自定义压缩插件
    -内部的JS压缩器就会被覆盖掉。所以后续压缩js时还需要手动将它添加回来。
  • webpack内部使用的JS压缩器是「terser-webpack-plugin」
  • 安装命令:npm i terser-webpack-plugin -D
  • 添加:
    const TerserWebpackPlugin = require('terser-webpack-plugin')
    minimizer: [ new TerserWebpackPlugin() ]

参照:webpack二刷之五、生产环境优化(5.提取压缩CSS)

代码实现
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

//设置node环境变量:决定使用browserslist的哪个环境
//process.env.NODE_ENV = 'development'
//默认在生产环境压缩

//最新压缩css插件
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/bundles.js',
        path: resolve(__dirname, 'dist'),
        clean:true //清理旧文件
    },
    //压缩css
    optimization: {
        minimize: true, //默认在生产环境,在开发环境要使用压缩就要设置minimize为true
        minimizer: [
            new CssMinimizerPlugin()
        ]
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader:MiniCssExtractPlugin.loader, //取代style-loader,提取js中的css成单独文件
                    //创建style标签,将样式放入
                    //'style-loader'
                        options: {
                            publicPath:'./'
                        }
                    },
                    {
                        loader: 'css-loader', //将css文件整合到js文件中
                        options: {
                            import:true, //启用/禁用 @import 处理
                        }
                    },
                    
                    //'postcss-loader'
                    //修改loader配置
                    {
                        loader: 'postcss-loader',//转换css
                        options: {
                            postcssOptions: {
                                ident: 'postcss',
                                plugins: [
                                    //require('postcss-preset-env')()
                                    'postcss-preset-env'//效果一样,运行时还是会转化成requeire("")来运行。
                                    //但并不是所有的插件都可以简写,因为有些插件时需要传入额外的参数的,所以有些插件不能简写
                                ]
                            }
                            
                        }
                    }
                ]
                
            }
        ]
    },
    plugins:[ 
        new HtmlWebpackPlugin({
            template:'./src/index.html'
        }),
        new MiniCssExtractPlugin({
            //对输出的css文件进行重命名
            filename:'css/built.css'
        })
    ],
    mode:'development'
}
 

js语法检查

使用方法
  • eslint-loader 被废弃,推荐使用 eslint-webpack-plugin
  • 安装命令
	npm install eslint eslint-webpack-plugin -D
  • 用法
	const ESLintPlugin = require('eslint-webpack-plugin');

	module.exports = {
	  // ...
	  plugins: [new ESLintPlugin(options)],
	  // ...
	}

js兼容性处理

定义
  • 不同的浏览器对同一段 js 代码有不同的解析,造成页面显示效果不统一的局面,这时候就需要对 js 代码进行兼容性处理
使用方法
  1. 安装插件
    	npm i babel-loader @babel/core @babel/preset-env core-js -D
    
  2. 基本 js 兼容性处理 --> @babel/preset-env 只能转换基本语法( es6->es5 ),如 promise 高级语法不能转换
    	{
           test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options:{//预设:指示babel做怎么样的兼容性处理
            	{//有.babelrc文件,优先使用文件配置
                    "presets": [
                        [
                            "@babel/preset-env",
                            { 
                                "debug": true,  //在cmd窗口打印对应引用信息
                                "useBuiltIns": "usage",  // 按需加载
                                "corejs":3  // 指定 corejs 版本
                            }
                        ]
                    ]
                }
            }
        }
    
  3. 全部 js 兼容性处理 --> 安装 core-js,配置 .babelrc文件 @babel/polyfill(废弃)
    
        {
    	    "presets": [
    	        [
    	            "@babel/preset-env",
    	            { 
    	                "debug": true,  //在cmd窗口打印对应引用信息
    	                "useBuiltIns": "usage",  // 按需加载 这里配置usage 会自动根据你使用的方法以及你配置的浏览器支持版本引入对应的方法。
    	                "corejs":3  // 指定 corejs 版本
    	            }
    	        ]
    	    ]
    	}
    
  4. 参照:【webpack5】低版本浏览器兼容ES6+解决方案
  5. 参考:https://www.babeljs.cn/
要点记录
  1. @babel/polyfill(废弃) 需另行安装 core-js
代码实现
	/**
	* js兼容性处理:babel-loader @babel/core @babel/preset-env
	* 1. 基本js兼容性处理 --> @babel/preset-env
	*    问题:只能转换基本语法(es6->es5),如promise不能转换
	* 2. 全部js兼容性处理 --> 安装core-js,配置.babelrc文件  @babel/polyfill(废弃) 
	*  options: { 预设:指示babel做怎么样的兼容性处理
	       "presets": [
	           [
	               "@babel/preset-env",
	               { 
	                   "debug": true,  //在cmd窗口打印对应引用信息
	                   "useBuiltIns": "usage",  // 这里配置usage 会自动根据你使用的方法以及你配置的浏览器支持版本引入对应的方法。
	                   "corejs":3  // 指定 corejs 版本
	               }
	           ]
	       ]
	   }
	*/
	const HtmlWebpackPlugin = require("html-webpack-plugin");
	const {resolve} = require('path')
	
	module.exports = {
	    entry: './src/js/index.js',
	    output: {
	        filename: 'js/bundles.js',
	        path: resolve(__dirname, 'dist'),
	        clean:true
	    },
	    module: {
	        rules: [
	            
	            {
	                test: /\.js$/,
	                exclude: /node_modules/,
	                loader: 'babel-loader'
	            }
	        ]
	    },
	    plugins: [
	        new HtmlWebpackPlugin({
	            template:'./src/index.html'
	        })
	    ],
	    mode:'development'
	}

html和js压缩

定义
  • 不同的浏览器对同一段 js 代码有不同的解析,造成页面显示效果不统一的局面,这时候就需要对 js 代码进行兼容性处理
使用方法
  1. 安装插件
    	npm i html-webpack-plugin -D
    
  2. 使用时将模式设置为生产模式 production
    	new HtmlWebpackPlugin({
            //在这个插件中实现压缩html和环境无关 无需做兼容性处理
            minify: {
                //移除空格
                collapseWhitespace: true,
                //移除注释
                removeComments:true
            }
        })
    
要点记录
  1. HtmlWebpackPlugin 插件中实现压缩 html 和环境无关,无需做兼容性处理
  2. 生产环境下回自动压缩 js 代码(此处未配置 optimization.minimizer ,所以无需手动添加内部 js 压缩器
代码实现
	const HtmlWebpackPlugin = require("html-webpack-plugin");
	const {resolve} = require('path')
	
	module.exports = {
	    entry: './src/js/index.js',
	    output: {
	        filename: 'js/bundles.js',
	        path: resolve(__dirname, 'dist'),
	        clean:true
	    },
	    
	    plugins: [
	        new HtmlWebpackPlugin({
	            template: './src/index.html',
	            //在这个插件中实现压缩html和环境无关 无需做兼容性处理
	            minify: {
	                //移除空格
	                collapseWhitespace: true,
	                //移除注释
	                removeComments:true
	            }
	            
	        })
	    ],
	    //生产环境下回自动压缩js代码
	    mode:'production'
	}

生产环境配置

定义
  • 能让代码优化上线运行的环境
要点记录
  1. 正常来讲,一个文件只能被一个 loader 处理,当一个文件(例如 js )要被多个 loader 处理,那么一定要指定 loader 执行的先后顺序, 在 loader 中设置 enforce:'pre' ,优先执行
  2. publicPath
  • 负责输出公共目录
  • 即打包后的写在磁盘的位置,输出解析文件的目录
  • url 相对于 HTML 页面(index.html所在文件夹的绝对路径 +值)(文件引用路径就是看这个
  • 如果 output 设置了 publicPath ,options也设置了publicPath,优先以 options 的 publicPath 为主
  • 是对页面引入资源的补充,比如img标签引入或者css引入等
  • 千万不能设错!!!!应该观察文件和HTML页面的存储地址位置,进行设置,否则引用时地址会错误,找不到文件
  • 一般只设置output的publicPath,方便统一管理
  • 例如: 打包字体图标时,与 iconfont.css 文件关联的.ttf 文件在 dist/fonts 文件夹下,则 .ttf 文件的 publicPath 要设置为 '../'
代码实现
	//绝对路径解析方法
	const { resolve } = require("path");
	
	//提取css成单独文件插件
	const MiniCssExtractPlugin = require('mini-css-extract-plugin')
	
	//最新压缩css插件
	const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
	
	//手动添加webpack内部js压缩器
	const TerserWebpackPlugin = require('terser-webpack-plugin');
	
	//对html文件处理
	const HtmlWebpackPlugin = require('html-webpack-plugin');
	
	//默认使用生产环境,定义nodejs环境变量:决定使用browserslist的哪个环境
	process.env.NODE_ENV = 'production'
	
	//复用loader
	const commonCssloader = [
	    {
	        loader: MiniCssExtractPlugin.loader,//提取css为单独文件
	        options: {
	            publicPath:'./'
	        }
	    },
	    'css-loader',
	    {//兼容性处理 还需要在package.json中定义browserslist
	        loader: 'postcss-loader',
	        options: {
	            postcssOptions: {
	                ident: 'postcss',
	                plugins: [
	                    'postcss-preset-env'
	                ]
	            }
	        }
	    }
	]
	
	module.exports = {
	    entry: './src/js/index.js',
	    output: {
	        filename: 'js/bundle.js',
	        path:resolve(__dirname,'dist'),
	        clean: true,
	        publicPath:'./'
	    },
	    //压缩css
	    optimization: {
	        minimize: true,
	        minimizer: [
	            new TerserWebpackPlugin(),
	            new CssMinimizerPlugin()
	        ]
	    },
	    module: {
	        rules: [
	            /**
	             *  正常来讲,一个文件只能被一个loader处理
	             *  当一个文件(例如js)要被多个loader处理,那么一定要指定loader执行的先后顺序
	             *  在loader中设置enforce:'pre',最先执行
	             */
	            {
	                //css兼容性处理
	                test: /\.css$/,
	                use: [...commonCssloader]
	            },
	            {
	                //less兼容性处理
	                test: /\.less$/,
	                use: [...commonCssloader,
	                    //use中loader执行从下往上,必须把这个处理放在css-loader与less-loader之间
	                    'less-loader'//将less转成css文件
	                ]
	            },
	            {
	                //js兼容性处理
	                test: /\.js$/,
	                exclude: /node_modules/,
					// 优先执行
					//enforce: 'pre',
	                loader:'babel-loader' //配置在.babelrc文件中
	            },
	            {
	                //图片处理
	                test: /\.(jpg|png|gif)$/,
	                loader: 'url-loader',
	                options: {
	                    limit: 8 * 1024,//对8kb以下的图片进行base64处理
	                    name: '[name].[hash:8].[ext]',//对处理后的图片重命名
	                    outputPath: 'img', //设置处理后的图片路径
	                    esModule:false //关闭es6模块化
	                }
	            },
	            {
	                //处理html中的图片问题
	                test: /\.html$/,
	                loader: 'html-loader',
	                options: {
	                    esModule:false
	                }
	            },
	            // 打包iconfont字体图标,和打包图片类似
	            {
	                test:/\.ttf$/,
	                use: {
	                loader: 'file-loader',
	                options: {
	                    esModule: false, // 新版本中esModule默认为true,会导致文件的地址变为[object Module],因此这里设置为false
	                    name: '[name]_[hash:6].[ext]', // 输出的文件名为[原名称]_[哈希值].[原后缀]
	                    outputPath: 'fonts/',       // 文件存储路径(output.path + 值)(物理路径, 存储路径)
	                    publicPath:'../fonts' ,    // 负责输出目录, 即打包后的写在磁盘的位置
	                     // 输出解析文件的目录,url 相对于 HTML 页面(index.html所在文件夹的绝对路径 + 值)(文件引用路径就是看这个)
	                    // 如果output设置了publicPath, options也设置了publicPath,优先以options的publicPath为主
	                    // 是对页面引入资源的补充,比如img标签引入或者css引入等.
	                    // 千万不能设错,应该观察文件和HTML页面的存储地址位置,进行设置,否则引用时地址会错误,找不到文件
	                    // 一般只设置output的publicPath,方便统一管理
	                    limit: 1024    // 限制当文件小于1KB的时候,就将文件转为base64存储于js中,以减少http请求次数,当文件大于1KB,则打包文件到指定目录,避免js过大
	                }
	                }
	            },
	            {
	                //处理其他文件
	                exclude: /\.(js|css|less|html|jpg|png|gif|ttf)$/,
	                loader: 'file-loader',
	                options: {
	                    name: '[name].[hash:8].[ext]',
	                    outputPath:'media'
	                },
	                // type: 'asset/resource',
	                // generator: {
	                //     filename: 'media/[name].[hash:6].[ext]'
	                // }
	            },
	        ]
	    },
	    plugins: [
	        //提取css为单独文件
	        new MiniCssExtractPlugin({
	            filename: 'css/built.css'
	        }),
	        //对html文件处理
	        new HtmlWebpackPlugin({
	            template: './src/index.html',
	            scriptLoading: 'blocking',//去除script defer模式
	            //html压缩
	            mimify: {
	                //移除空格
	                collaspeWhitespace: true,
	                //移除注释
	                removeComments:true
	            }
	        })
	        
	    ],
	    //mode为production,js就自动压缩了,但因为配置了optimization.minimizer,需要手动添加内部js压缩器
	    mode: 'production'
	}

写在后面

阳光斑驳,树影婆娑。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值