webpack4--学习笔记

卫劲
2023-12-01

webpack4

loader

通过loader加载任何类型的资源

文件资源加载器
file-loader

大文件(大于10kb)单独提取存放,提高加载速度

npm i file-loader

yarn add file-loader

{

​ text:/.png$/

​ use:‘file-loader’

}

url-loader

需要用的话,首先需要先安装file-loader

可以将文件转换成base64 ,小文件(小于10kb)使用,减少请求次数

{

​ text:/.png$/

​ use:‘url-loader’

}

{

​	text:/\.png$/

​	use:{

​			loader:'url-loader'

​			options:{

​				limit:10*1024  //10KB

​			}

​	}

}

常用的loader (加载器)

常用加载器分类:

编译转换类(css-loader)

文件操作类(file-loader)

代码检查类(eslint-loader)

webpack与ES2015

转换es6语法—babel-loader

取代默认的加载器,处理代码中的新特性

yarn babel-loader @babel/core @babel/preset-env --dev

{

​	test:/.js$/

​	use:{

​		loader:'babel-loader',

​		options:{

​			presets:['@babel/preset-env']

​		}

​	}

}

webpack 只是打包工具

加载器可以用来编译转换代码(用于处理新特性)

webpack模块加载器

遵循Es module的import声明

遵循Common Js 标准的require函数

遵循AMD 标准的define函数和require函数

*样式代码中的@import指令和url函数

*html-loader 加载html代码中图片标签的src属性

webpack核心工作原理

找到打包的入口文件(一般是js文件)

根据import 生成依赖树

找到每个节点对应的资源文件

生成bundle.js文件

loader机制是webpack的核心

loader的工作原理

webpack开发一个Loader

开发一个markdown文件加载器

markdown-loader.js文件

const marked= require('marked')

module.exports = source=>{

​	const html = marked(source)
	// return `export default ${JSON.strigify(html)}` //返回的必须是js代码  也可以是

​	return `module.exports = ${JSON.strigify(html)}` //返回的必须是js代码

}
{

​	test :/.md$/,

​	use:'./markdown-loader'

}

总结 :

loader负责资源文件从输入到输出的转换,对于同一个资源可以依次使用多个;如:Loader css-loader->style-loader

Loader专注实现资源模块加载

plugin解决其他自动化工作(如:清除打包目录、拷贝静态文件至输出目录、压缩输出代码)

webpack常用插件

clean-webpack-plugin 自动清除输出目录插件

yarn add clean-webpack-plugin

const {CleanWebpackPlugin} = require('clean-webpack-plugin ')

pulgin:[
	new CleanWebpackPlugin()
]

自动生成使用bundle.js的HTML

html-webpack-plugin

yarn add html-webpack-plugin

const HtmlWebpackPlugin = require(html-webpack-plugin)

plugin:[
	//用于生成index.html
	new HtmlWebpackPlugin({
		title:'webpack pulgin sample',
		meta:{
			viewport:'width=device-width'
		},
		template:'./src/index.html' //指定模板 用于输出html文件
	})
	//用于生成about.html
	new HtmlWebpackPlugin({
		filename:'about.html',
		
	}
	//开发阶段最好不使用这个插件 
	new CopyWebpackPlugin([
		'public'  //指定目录  同时拷贝到输出目录
	])
]

webpack插件总结

copy-webpack-plugin

webpack插件机制的工作原理

相比于Loader,plugin拥有更宽的能力范围

plugin通过钩子机制实现

plugin必须是一个函数或者是一个包含apply方法的对象

通过在生命周期的钩子中挂载函数实现扩展

删除bundle.js中的注释

class MyPlugin{

​	apply(compiler){
		compiler.hooks.emit.tap('MyPlugin',compilation=>{
			//compilation  可以理解为此次打包的上下文
            for(const name in compilation.assets){
                console.log(compilation.assets[name].source())
                if(name.endsWith('.js')){
                    const contents = compilation.assets[name].source()
                    const withoutComments = contents.replace(/\/*\*+\*//g,'')
                    compilation.assets[name]={
                        source:()=>withoutComments,
                        size:()=>withoutComments.length
                    }
                }
            }
		})
​		

​	}

}

plugins:[
    new MyPlugin()
]

webpack增强开发体验

实现自动编译

watch 工作模式

监听文件变化 ,自动重新打包

yarn webpack --watch 以监视模式运行

实现自动刷新浏览器

browserSync

操作上麻烦,需要同时使用两个工具

效率上降低,会出现两次读写磁盘的操作

最终使用webpack-dev-server

集成【自动编译】和【自动刷新浏览器】等功能

会有一个http server

yarn add webpack-dev-server

直接使用yarn webpack-dev-server

将打包结果存放到内存中,再发给浏览器

webpack dev server 静态资源访问
module.exports = {

​	devServer:{

​		contentBase:'./public'  //路径  额外为开发服务器指定查找资源目录

​	}	

}


webpack dev server 支持配置代理

https://api.gitbug.com/api/users
module.exports = {

​	devServer:{

​		contentBase:'./public'  //路径  额外为开发服务器指定查找资源目录
		proxy:{
    		'/api':{
    			//http://local:8080/api/users-> https://api.gitbug.com/api/users
    			target:'https://api.gitbug.com'
    			pathRewrite:{
    				'^/api':''
				}
    			//不使用localhost:8080 作为请求gitHub的主机名
    			changeOrigin:true
			}
		}
​	}	

}


source map

source map 解决了源代码与运行代码不一致所产生的问题

devtool:‘source-map’

devtool有12种模式

每种方式的效率和效果各不相同(效率好的、生产代码时最慢;生产代码时最快的、效率最差)

devtool

HMR 热替换

webpack-dev-server
const webpack = require('webpack')
devServer:{

​	hot:true

}

plugins:[
	new webpack.HotModuleReplacementPlugin()
]

HMR需要手动处理模块热替换逻辑

js、图片并不是开箱即用

样式文件可以直接热更新

通过脚手架创建的项目内部都集成了HMR方案

在入口文件中增加如下代码(module.hot是由HMR开启的)

module.hot.accept(‘./editor’,()=>{

})

webpack不同的环境的配置文件

三个配置文件

webpack.common.js、webpack.dev.js、webpack.prod.js

合并配置文件

yarn add webpack-merge --dev

在webpack.prod.js 中

const common = require('./webpack.common')
const merge = require('webpack-merge')
module.exports = merge(common,{
	mode:'production'
})










webpack代码分割

多入口打包

适应于多页应用程序

一个页面对应对应一个打包入口,公共部分单独提取

module.exports = {
    mode:'none',
    entry:{

        index:'./src/index.js',

        album:'./src/album.js'

    }

    output:{

        filename:'[name].bundle.js'

    },
    optimization:{ 
    	splitChunks:{  
    		chunks:'all'  //提取公共模块
    	}
    }
    module:{
    	rules:[
            {
				test:/\.css$/,
				use:[
					'style-loader',
					'css-loader'
				]
            }
    	]	
    },
	plugins:[
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title:'Multi Entry',
            template:'./src/index.html',
            filename:'index.html',
            chunks:['index']        //多入口时需要配置
        })
        new HtmlWebpackPlugin({
            title:'Multi Entry',
            template:'./src/album.html',
            filename:'album.html',
            chunks:['album']
        })
    ]
}


动态导入(按需加载)

需要用到某个模块时去加载

动态导入的模块会被自动分包

提高响应速度

魔法注释

magic comment

import(/* webpackChunkName:‘album’ */‘./album.album’).then()

MiniCssExtractPlugin

提取css到单个文件(超过150KB才建议提取)

module:{

​	rules:[

​		{

​			test:/\.css$/,

​			use:[

​				//'style-loader',  //将样式通过style标签注入

​				MiniCssExtractPlugin.loader,  //提取css到单个文件

​				'css-loader'	

​			]

​		}

​	]

}
webpack OptimizeCssAssetsWebpackPlugin

压缩输出的css文件

npm i optimize-css-assets-webpack-plugin --dev

const OptimizeCssAssetsWebpackPlugin = require(‘optimize-css-assets-webpack-plugin’)

可配置到pulgins数组中,但通常是配置到minimizer数组中,只有配置了optimization时才会去压缩,同时也要单独为js去配置压缩,可通过terser-webpack-plugin来处理js压缩

const TerserWebpakcPlugin = require('terser-webpack-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimizer-css-assets-webpack-plugin')
optimization:{

​	minimizer:[
		new TerserWebpakcPlugin()
​		new OptimizeCssAssetsWebpackPlugin()

​	]

}

输出文件名hash substitutions

生产模式下,文件名使用hash值

filename:‘[name]-[hash].bundle.css’

filename:‘[name]-[chunkhash:8].bundle.css’ 一般用这个

filename:‘[name]-[contenthash].bundle.css’

hash、chunkhash(更精确定位到文件级别的hash)、contenthash(不同的文件就有不同的变化)

chunkhash

 类似资料: