• webpack4的知识总结


    一 环境搭建

    webpack其实就是一个JavaScript应用程序的静态模块打包器。

    webpack会将项目的资源文件当成一个一个模块,模块之间会有依赖关系,
    webpack将会对这些有依赖关系的文件进行处理,让浏览器能够识别,
    最后将应用程序需要的每个模块打包成一个或者多个bundle
    

    1.安装node

    node官网地址:  https://nodejs.org/zh-cn/
    

    2.创建package.json文件

    npm init
    

    3.安装webpack

    本地安装:(推荐)

    npm install --save-dev webpack
    npm install --save-dev webpack-cli
    

    全局安装:

    npm install --global webpack webpack-cli
    

    4.打包

    默认配置

    entry:"src/index.js"
    output:"dist/main.js"
    

    package.json文件下添加scripts,配置打包模式

    {
    	"scripts":{
    	    "dev":"webpack --mode development",
    	    "prod":"webpack --mode production"	
    	}
    }
    
    npm run dev
    npm run prod
    

    二 基础配置webpack.config.js

    1.新建文件 webpack.config.js

    2.配置入口entry和output

    (1)path指文件打包后的存放路径
    (2)path.resolve()方法将路径或路径片段的序列处理成绝对路径
    (3)__dirname 表示当前文件所在的目录的绝对路径
    (4)filename是打包后文件的名称
    

    示例代码:

    const path = require('path');
    
    
    module.exports = {
    	entry:'./public/index.js',
    	output:{
    		path:path.resolve(__dirname,'build'),
    		filename:"bundle.js"
    	}
    }
    

    示例代码2:

    const path = require('path');
    module.exports = {
    // 多文件单出口
    // entry:['./public/index.js','./public/index2.js'],
    // output:{
    // 	path:path.resolve(__dirname,'build'),
    // 	filename:"bundle.js"
    // }
    
    //多入口多出口
    entry:{
    	pageOne: './public/pageOne/index.js',
    	pageTwo: './public/pageTwo/index.js',
    	pageThree: './public/pageThree/index.js'
    },
    output:{
    	path:path.resolve(__dirname,'build'),
    	filename:"[name].js"
    }
    

    }

    3.配置webpack-dev-server

    npm install --save-dev webpack-dev-server
    

    配置webpack.config.js文件

    devServer:{
    	contentBase:"./build",
    	host:"localhost",
    	port:8080,
    	open:true //自动打开页面
    }
    

    配置package.json

    "scripts": {
    	"start": "webpack-dev-server --mode development"
     }
    

    在build文件夹下新建index.html文件,在html中引入bundle.js

    npm run start
    

    二 loader加载组件

    1.加载css

    npm install style-loader css-loader --save-dev
    

    在webpack.config.js文件里配置module中的rules

    module:{
    	rules:[
    		{
    			test:/.css$/,
    			use:['style-loader','css-loader']
    		}
    	]
    }
    

    创建index.css文件并import进index.js文件中

    import './index.css';
    

    2.加载编译less和sass

    安装less-loader和less 和 安装sass-loader和node-sass

    npm install less-loader less --save-dev
    npm install sass-loader node-sass --save-dev
    

    在webpack.config.js文件里配置module中的rules

    module:{
    	rules:[
    		{
    			test:/.less$/,
    			use:['style-loader','css-loader','less-loader']
    		},
    		{
    			test:/.scss$/,
    			use:['style-loader','css-loader','sass-loader']
    		}
    	]
    }
    

    3.使用PostCSS添加浏览器前缀

    npm install --save-dev  postcss-loader autoprefixer
    

    需要和autoprefixer一起用,在webpack.config.js文件里配置module中的rules

    module:{
    	rules:[
    		{
    			test:/.css$/,
    			use:['style-loader','css-loader',{
    				loader:'postcss-loader',
    				options:{
    					plugins:[require("autoprefixer")()]
    				}
    			}]
    		}
    	]
    }
    

    4 文件处理

    npm install --save-dev file-loader
    

    图片module中的rules

    module:{
    	rules:[
    		{
    			test:/.(png|jpg|gif|jpeg)$/,
    			use:[{
    				loader:'file-loader',
    				options:{
    					name:'[hash]wangou.jpg',
    					outputPath:'./img'
    				}
    			}]
    		}
    	]
    }
    

    配置options:

    name:为你的文件配置自定义文件名模板(默认值[hash].[ext])
    context:配置自定义文件的上下文,默认为 webpack.config.js
    publicPath:为你的文件配置自定义 public 发布目录
    outputPath:为你的文件配置自定义 output 输出目录
    
    [ext]:资源扩展名
    [name]:资源的基本名称
    [path]:资源相对于 context的路径
    [hash]:内容的哈希值
    

    字体module中的rules

    module:{
    	rules:[
    		{
    			test:/.(ttf|woff|woff2|eot|svg)$/,
    			use:[{
    				loader:'file-loader',
    				options:{
    					outputPath:'font/'
    				}
    			}]
    		}
    	]
    }
    

    js库module中的rules

    	 以jquery库为例子
    

    1)本地导入

    const webpack = require('webpack');
    
    module.exports = {
    	entry:'./public/index.js',
    	
    	resolve:{
    		alias:{
    			jQuery: path.resolve(__dirname,"public/js/jquery.min.js")
    		}
    	},
    	plugins:[
    		new webpack.ProvidePlugin({
    			jQuery:"jQuery"
    		})
    	]
    }
    

    2)npm安装模块

    安装jquery库:

    npm install jquery --save-dev
    

    直接在js里import引入

    import $ from 'jquery'
    

    5 HTML中引入图片

    cnpm install --save-dev html-loader
    

    module中的rules

    {
    	test:/.(html)$/,
    	option:{
    		attrs:['img:src', 'img:data-src']
    	}
    }
    

    6.babel编译ES6

    module:{
    		rules:[
    			{
    				test:/.js$/,
    				exclude:/node_modules/,
    				use:'babel-loader'
    			}
    		]
    	},
    

    webpack 插件

    1.生成HTML

    npm install html-webpack-plugin --save-dev
    

    module中的rules

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    plugins:[
    
    	new HtmlWebpackPlugin({
    		template:"./public/index.html",
    		filename:"webpack.html",
    		minify:{
    			minimize:true,
    			removeComments:true,
    			removeAttributeQuotes:true,
    			collapseWhitespace:true,
    			minifyCSS:true,
    			minifyJS:true,
    			removeEmptyElements:true
    		},
    		hash:true
    	})
    ]
    

    2.提取分离css

    npm install --save-dev mini-css-extract-plugin
    

    module中的rules

    const MiniCssExtractPlugin =  require("mini-css-extract-plugin")
    module:{
    	rules:[
    		
    		{
    			test:/.css$/,
    			use:[MiniCssExtractPlugin.loader,'css-loader',{
    				loader:'postcss-loader',
    				options:{
    					plugins:[require("autoprefixer")()]
    				}
    			}]
    		}
    	]
    },
    
    plugins:[
    	new MiniCssExtractPlugin({
    		filename:"./css/[name].css"
    	})
    ]
    

    3 压缩css及优化css结构

    npm install --save-dev optimize-css-assets-webpack-plugin
    

    module中的rules

    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    
    plugins:[	
    	new OptimizeCSSAssetsPlugin({
    		assetNameRegExp:/.css$/g,
    		cssProcessor:require('cssnano'),
    		cssProcessorPluginOptions:{
    			preset:['default',{discardComments:{removeAll:true}}]
    		},
    		canPrint:true
    	})
    ]
    

    4copy静态文件

    module中的rules

    const CopyWebpackPlugin = require('copy-webpack-plugin');
    
    plugins:[
    	new CopyWebpackPlugin([
    		{
    			from:__dirname+'/public/assets',
    			to:__dirname+'/build/assets'
    		}
    	])
    ]
    

    5清除垃圾文件

    npm install --save-dev clean-webpack-plugin
    

    module中的rules

    const CleanWebpackPlugin = require('clean-webpack-plugin');
    
    plugins:[
    	new CleanWebpackPlugin({
    		dry: false
    	}),
    ]
    

    6 SourceMap 调试代码

    1)js调试

    devtool:"source-map"
    

    2)css调试

    调试css时需要将压缩css的插件注释掉(optimize-css-assets-webpack-plugin)
    
    module:{
    	rules:[
    		{
    			test:/.css$/,
    			use:[{
    				loader:'css-loader',
    				options:{
    					source:true
    				}
    			}]
    		}
    	]
    },
    

    7模块热替换

    devServer:{
    	contentBase:'./build',  //设置服务器访问的基本目录
    	host:'localhost', //服务器的ip地址
    	port:8080,  //端口
    	open:true,  //自动打开页面
    	hot:true,
    	hotOnly:true
    },
    plugins:[
    	new webpack.NamedModulesPlugin(),
    	new webpack.HotModuleReplacementPlugin(),
    ]
    

    entry文件js

    if(module.hot){
    	module.hot.accept()
    }
    

    8区分生产环境和开发环境

    npm install --save-dev webpack-merge
    

    将webpack.config.js拆分为三个文件,分别是webpack.common.conf.js、webpack.dev.conf.js和webpack.prod.conf.js。
    webpack.common.conf.js是放一些我们公用的配置,比如入口entry、出口output、常用loader以及插件等。
    webpack.dev.conf.js是在开发环境上的配置,比如devServer配置、模块热替换等方便开发的配置
    webpack.prod.conf.js是在生产环境上的配置,比如提取分离css、压缩css和js等

    webpack.common.conf.js

    const path = require('path');
    const webpack = require('webpack');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    module.exports = {
    	entry:'./public/index.js',
    	output:{
    		path:path.resolve(__dirname,'../build'),
    		filename:"bundle.js"
    	},
    	module:{
    		rules:[
    			{
    				test:/.css$/,
    				use:['style-loader','css-loader',{
    					loader:'postcss-loader',
    					options:{
    						plugins:[require("autoprefixer")()],
    						sourceMap:true
    					}
    				}]
    			},
    			{
    				test:/.less$/,
    				use:['style-loader','css-loader','less-loader']
    			},
    			{
    				test:/.scss$/,
    				use:['style-loader','css-loader','sass-loader']
    			},
    			{
    				test:/.(png|jpg|gif|jpeg)$/,
    				use:[{
    					loader:'file-loader',
    					options:{
    						name:'[hash]wangou.jpg',
    						outputPath:'./img'
    					}
    				}]
    			},
    			{
    				test:/.(ttf|woff|woff2|eot|svg)$/,
    				use:[{
    					loader:'file-loader',
    					options:{
    						outputPath:'font/'
    					}
    				}]
    			},
    			{
    				test:/.js$/,
    				exclude:/node_modules/,
    				use:'babel-loader'
    			},
    			{
    				test:/.(html)$/,
    				use:{
    					loader:'html-loader',
    					options: {
    						attrs: ['img:src','img:data-src']
    					}
    				}
    			}
    		]
    	},
    	resolve:{
    		alias:{
    			jQuery: path.resolve(__dirname,"../public/js/jquery.min.js")
    		}
    	},
    	plugins:[
    		new CleanWebpackPlugin(['build'],{
    			root:path.resolve(__dirname,'../')
    		}),
    		new webpack.ProvidePlugin({
    			jQuery:"jQuery"
    		}),
    		new HtmlWebpackPlugin({
    			template:"./public/index.html",
    			filename:"webpack.html",
    			minify:{
    				minimize:true,
    				removeComments:true,
    				removeAttributeQuotes:true,
    				collapseWhitespace:true,
    				minifyCSS:true,
    				minifyJS:true,
    				removeEmptyElements:true
    			},
    			hash:true
    		}),
    		// 分离css
    		// new ExtractTextPlugin("./css/[name].css")
    		new MiniCssExtractPlugin({
    			filename:"./css/[name].css"
    		}),
    	]
    }
    

    webpack.dev.conf.js

    const webpack = require('webpack');
    const merge = require('webpack-merge');
    const common = require('./webpack.common.conf.js');
    module.exports = merge(common,{
    	devtool:'cheap-module-eval-source-map',
    	devServer:{
    		contentBase:'./build',  //设置服务器访问的基本目录
    		host:'localhost', //服务器的ip地址
    		port:8080,  //端口
    		open:true,  //自动打开页面
    		hot:true,
    		hotOnly:true
    	},
    	plugins:[
    		new webpack.NamedModulesPlugin(),
    		new webpack.HotModuleReplacementPlugin()
    	]
    }) 
    

    webpack.prod.conf.js

    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    const common = require('./webpack.common.conf.js');
    const merge = require('webpack-merge');
    const path = require('path');
    
    module.exports = merge(common,{
    	devtool:'source-map',
    	plugins:[
    		new CopyWebpackPlugin([
    				{
    					from:path.resolve(__dirname,'../public/assets'),
    					to:path.resolve(__dirname,'../build/assets')
    				}
    		])
    	]
    })
    

    配置文件package.json

    "scripts": {
        "dev": "webpack --mode development --config ./config/webpack.dev.conf.js",
        "build": "webpack --mode production --config ./config/webpack.prod.conf.js",
        "start": "webpack-dev-server --mode development --config ./config/webpack.dev.conf.js"
    },
    

    四 优化打包的速度

    1.减少文件搜索范围

    1)优化resolve.extensions配置

    在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试询问文件是否存在。

    在配置 resolve.extensions 时你需要遵守以下几点,以做到尽可能的优化构建性能:

    	后缀尝试列表要尽可能的小,不要把项目中不可能存在的情况写到后缀尝试列表中。
    	频率出现最高的文件后缀要优先放在最前面,以做到尽快的退出寻找过程。
    	在源码中写导入语句时,要尽可能的带上后缀,从而可以避免寻找过程。例如在你确定的情况下把 require('./data') 写成 require('./data.json') 。
    

    2)优化 resolve.modules 配置

    resolve.modules 用于配置 Webpack 去哪些目录下寻找第三方模块。
    resolve.modules 的默认值是 ['node_modules'],会采用向上递归搜索的方式查找

    (3)优化resolve.alias配置

    resolve.alias 配置项通过别名来把原导入路径映射成一个新的导入路径。

    (4)缩小文件匹配范围

    Include:需要处理的文件的位置
    Exclude:排除掉不需要处理的文件的位置

    2.设置noParse

    防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。比如jquery、elementUI等库

    3.给babel-loader设置缓存

    babel-loader 提供了 cacheDirectory特定选项(默认 false):设置时,给定的目录将用于缓存加载器的结果。

    4.使用happyPack

    HappyPack的基本原理:在webpack构建过程中,我们需要使用Loader对js,css,图片,字体等文件做转换操作,并且转换的文件数据量也是非常大的,且这些转换操作不能并发处理文件,而是需要一个个文件进行处理,HappyPack的基本原理是将这部分任务分解到多个子进程中去并行处理,子进程处理完成后把结果发送到主进程中,从而减少总的构建时间。

  • 相关阅读:
    看《长安十二时辰》可以了解哪些算法知识
    面试官,我会写二分查找法!对,没有 bug 的那种!
    毕业十年后,我忍不住出了一份程序员的高考试卷
    扫雷与算法:如何随机化的布雷(一)
    降维打击!为什么我认为数据结构与算法对前端开发很重要
    盖尔-沙普利算法告诉你,你的对象在哪里?
    这道算法题太太太太太简单啦
    有点难度,几道和「滑动窗口」有关的算法面试题
    几道和「黑洞照片」那种海量数据有关的算法问题
    LeetCode 上最难的链表算法题,没有之一!
  • 原文地址:https://www.cnblogs.com/sentangle/p/12462417.html
Copyright © 2020-2023  润新知