webpack的使用详解

时间:2020-7-28 作者:admin


概念

本质上,webpack是一个现代javascript应用程序的静态模块打包器

核心webpack.config.js

  • 入口 entry
  • 出口 output
  1. filename 文件名称
  2. path 地址
  • mode模式
  1. development 开发模式
  2. production 产品模式
  • plugins 插件
  1. html-webpack-plugin 处理html文件
  2. 使用 –const htmlWebpackPlugin = require(“html-webpack-plugin”);—plugins:[new htmlWebpackPlugin({})]
  3. 配置 模板template:__dirname+”/public/index.html”;title:“firstPage”;minify:true压缩
  4. 模板语法 <%= htmlWebpackPlugin.options.title %>
  5. clean-webpack-plugin 清理dist目录
const { CleanWebpackPlugin }  = require("clean-webpack-plugin")
new CleanWebpackPlugin()
  1. copy-webpack-plugin 拷贝文件(设置静态资源目录)
const CopyWebpackPlugin = require('copy-webpack-plugin');
new CopyWebpackPlugin({
	patterns:[
	    {from:xxx,to:xxx},
	    {from:yyy,to:yyy}
	]		
})
  • devServer本地服务器
  1. host域名
  2. port端口
  3. hot热更新
  4. open 打开浏览器
  5. 安装 npm i webpack-dev-server -D
  6. 配置 “serve”:“webpack-dev-server –mode development”
//配置本地服务器
devServer:{
	host:"localhost",//域名
	port:8080,//端口
	hot:true,//热更新
	open:true //打开浏览
}
  • loader —module rules规则
module:{
	rules:[
		{
			test:/\.css$/,
			use:["style-loader","css-loader"]
		}
	]
},
  • resolve 配置
  1. alias别名
const path = require("path")
resolve:{
	alias:{
		'@':path.resolve(__dirname,'./src'),//设置@为src的别名
	}
},
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
	// mode:"development",//配置模式
	entry:"./src/index.js",//入口index.js文件
	output:{
		filename:"main.js",//文件名
		path:__dirname+"/dist" //地址
	},
	//定义出口
	plugins:[
		new htmlWebpackPlugin({
			title:"我的第一个webpack",
			minify:true,
			template:__dirname+"/public/index.html"
		})
	]
}

命令配置 在package.json下的script

  • “dev”:“webpack –mode development” 配置开发模式命令
  • “start”:“webpack” 运行
  • “build”:“webpack –mode production” 配置产品模式命令
  • 执行
  1. npm run dev
  2. npm run build
{
  "name": "mypack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
	"start":"webpack",
	"dev":"webpack --mode development",
	"build":"webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.12"
  }

loader和plugin的区别

  • loader让webpack有处理非js文件的能力
  • webpack运行时plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果

loader

处理css

  • css-loader 分析css关系,需要加载哪些css文件
  • style-loader 把css插入到html head标签里面
  • mini-css-extract-plugin.loader css抽取为单独文件
const minCssExtractPlugin = require("mini-css-extract-plugin");
plugins:[
	new htmlWebpackPlugin({
		title:"我的第一个webpack",
		minify:true,
		template:__dirname+"/public/index.html"
	}),
	new minCssExtractPlugin({
		filename:'style.css'
	})
],
  • optimize-css-assets-webpack-plugin 压缩css
const optimizeCss = require("optimize-css-assets-webpack-plugin");
optimization:{
	//压缩器
	minimizer:[new optimizeCss()]
},
  • less 处理less文件||less-loader 加载less文件
{
	test:/\.less$/,
	use:[minCssExtractPlugin.loader,"css-loader","less-loader"]
}
  • 处理css前缀

postcss-loader—autoprefixer

处理文件(图片)

  • file-loader
  • url-loader
  1. 将小的图片转换为base64格式
  2. 处理字体
{
test:/\.(eot|woff2|woff|ttf|svg)$/,
use:[{loader:'url-loader',options:{limit:10,name:'font/[name].[hash:5].[ext]'}}]
},
  1. 处理图片
{
test:/\.(png|gif|bmp|jpg|jpeg|svg|ico)$/,
use:[{loader:'url-loader',options:{limit:100000,name:'images/[name].[hash:5].[ext]'}}],
//使用url-loader (加载文件,渲染为低于1000b 就压缩为base64个)
//文件的名称 存放咋images文件夹名称原来一致[name].添加hash[hash:5].默认后缀ing.[ext]
//esModule:不采用模块
}

浏览器的缓存机制

文件名没有改变。默认浏览器会自动缓存这个文件,第二次去访问网站的时候,浏览器发起http请求前会先从缓存列表查询,如果有就直接从缓存读取,这样加快网页的加载

我的文件内容以及修改,浏览器还使用的缓存文件(会发生不可期的结果)

只有文件内容发生改变,修改下文件名称(文件指纹)通常hash算法

三个hash

  • hash 只要项目里有文件更改,整个项目构建的hash值都会更改
  • chunkhash 每一次构建后生成的哈希值都不一样
  • [name]默认的chunkname
  • [contenthash:7]截取7位

包版本管理

  • ^3.145不会超过4.0
  • ^0.2.3不会超过0.3
  • ~3.1.2不会超过3.2
  • @指定版本

npm安装

产品模式

  • npm install xxxx –save
  • npm i XXX -S
    开发模式
  • npm install xxx –save-dex
  • npm i xxx -D
  • devDependencies 开发依赖 工具文件不会被打包上传

react webpack环境

  • 安装
  1. babel-loader 处理es6文件
  2. @babel/core babel核心模块
  3. @babel/preset-env 环境预设
  4. @babel/preset-react react运行环境jsx语法支持
  5. babel/polyfill 把es6的方法转换为ES5
  6. @babel/plugin-transform-runtime”按需加载polyfill方法
  • 安装 -S
  1. react react方法
  2. react-dom 渲染dom
  3. babelrc配置
{
	"presets":["@babel/preset-env","@babel/preset-react"],
}
  1. 写index.js
import ReactDom from 'react-dom'
import React,{Component} from 'react'
//导入react reactdom
class App extends Component{//定义app组件
	constructor(props) {
	    super(props)
		this.state = {name:"mumu",age:18}
		//定义 状态state
	}
	render(){
		return (<div><h1>我的名字是:{this.state.name},今年{this.state.age}</h1>
		<button onClick={()=>{this.setState({age:this.state.age+1})}}>一年过去了</button>
		</div>
		)
	}
}

ReactDom.render(<App/>,document.getElementById("root"))
//把app组件渲染到 rootdiv里面

优化optimization

  • minimizer压缩
  1. new optimizeCSS()压缩优化css
  2. new UglifyjsWebpackPlugin()压缩优化js
  • 分割js代码

解释:把import导入的代码单独打一个文件,如果这个文件超过3k又会再被分割

splitChunk分割模块

  1. chunks模块名
  2. splitChunks:{chunks:“all”//“initial”}

devtools开发工具

  • cheap-module-eval-source-map 开发模式
  • cheap-module-source-map 产品模式

动态加载

import("xxx")
.then(({default:$})=>{})
  • webpack魔法注释
/*webpackChunkName:"jquery"*/
分割文件名
/*webpackPrefetch: true*/
提前加载

webpack环境变量 配置文件切换 动态加载

  • 关于目录
  1. path.resolve(__dirname,'../public/index.html')
  2. path解决路径的文件
  3. __dirname 当前所在目录
  4. ../public/index.html
  5. 结果 c:/mypack/public/index.html
  • 配置文件
  1. 基础 config/webpack.com.js
  2. 开发 config/webpack.dev.js
mode:"development"
devtool:"cheap-module-eval-source-map"
  1. 产品 config/webpack.prod.js
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
//导入基础配置
module.exports = {
	devtool:'cheap-module-source-map',
	mode:'production',
	plugins:[new CleanWebpackPlugin()]
}
  1. 配置入口文件 webpack.config.js
const {merge} = require("webpack-merge");
//两个配置 合并到一个配置文件里面

const commonConfig = require("./config/webpack.com.js");
//导入基础配置
const devConfig = require("./config/webpack.dev.js");
const prodConfig = require("./config/webpack.prod.js");

module.exports = (env,args)=>{
	console.log(args,"args");
	if(env.production){
		return merge(commonConfig,prodConfig);
	}else{
		return merge(commonConfig,devConfig);
	}
}
  • script的传值
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack",
    "dev": "webpack --env.development",
    "build": "webpack --env.production",
    "serve": "webpack-dev-server --env.production"
  },

webpack优化方式

  • 懒加载import,提前加载prefetch
  • 通过hash文件指纹增强浏览器缓存
  • 压缩图片、css、js
  • splitChunks 分割比较大的依赖包
  • 按需加载 treeshake

切换配置

  • script里面传递参数
  • merge导入合并 配置文件
  • 根据参数的不一致,实现生产环境,与产品环境配置的切换

如何传递参数

  • script –mode production
  • 如果想在前端代码中获取当前的开发环境
  1. process.env(只能在开发环境中)
  2. 根据env的不同,配置不同的http请求域名
  • 使用
  1. 安装cross-env 苹果系统和windows系统设置环境变量方式不一样
  2. script传递参数 "serve":"cross-env http_env=development webpack-dev-server --env.development"
  3. 设置哪些变量可以在前端访问
const webpack = require("webpack")
new webpack.DefinePlugin({
    'process.env':{
        'http_env':JSON.stringify(process.env.http_env)
    }
})
  1. 前端获取
const ENV = process.env.http_env
console.log("根据env",ENV,"切换域名实现相关业务")

vue运行环境

  • 安装
  1. vue
  2. vue-loader 处理.vue文件
  3. vue-style-loader 处理vue style样式
  4. vue-temolate-compiler 编译模块文件
  5. vue-hot-reload-api 热更新
  • babel
  1. babel es6转es5
  2. babel-loader@7 处理loader 指定版本7
  3. babel-core 核心
  4. babel-plugin-transform-runtime 按需加载
  5. babel-preset-es2015 es2015 ES6运行环境
  6. babel-runtime
  7. babel-polyfill es6-es5函数
  • .babelrc
{
	"presets":["@babel/preset-env","@babel/preset-react"],
}
  • loader
{
	test:/\.vue$/,
	loader:'vue-loader',
	options:{
		loaders:{
			css: [minCssExtractPlugin.loader,'style-loader', 'css-loader'],
			less: [minCssExtractPlugin.loader,'css-loader', 'less-loader'],
		}
	}
},
  • plugin
const UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin");
//获取vue-loader

new VueLoaderPlugin(),

多文件入口

  • entry入口
vue:path.resolve(__dirname,'../src/main.js'),
react:path.resolve(__dirname,'../src/index.js')
  • output出口
filename:"[name]-[hash:7].js",//文件名
path:path.resolve(__dirname,"../dist") //地址
  • plugin
new htmlWebpackPlugin({
	title:"vue,我的第一个webpack",//标题
	minify:true,//压缩
	chunks:['vue'],
	template:path.resolve(__dirname,"../public/index.html")
}),
new htmlWebpackPlugin({
	title:"react,我的第一个webpack",//标题
	minify:true,//压缩
	chunks:['react'],
	template:path.resolve(__dirname,"../public/react.html"),
	filename:'react.html'
}),
new VueLoaderPlugin(),
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。