基础概念
- webpack是一个前端打包工具
- 用它来处理现代前端错综复杂的依赖关系(A插件需要B插件,B插件需要D插件)
- 生成浏览器可以识别的静态资源
- Vue前期的脚手架就是用webpack制作的
- react、angular等现代框架脚手架
- 总结:本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。
webpack的核心概念
入口(entry)
- 项目运行的起点,告诉webpack从那开始打包
module.exports = {
entry:"./src/index.js",//入口
}
出口(output)
- 打包好放哪
- filename:文件名
- path:路径
module.exports = {
output:{//出口
filename:"main-[hash].js",//文件名
path:__dirname+"/dist",//__dirname当前目录
},
}
模式(mode)
- 产品模式(production)
- 开发模式(development)
module.exports = {
mode:"development",//模式:开发模式 production产品模式
}
加载器(loader)
- 默认只能加载处理js文件
- 让webpack拥有能处理其他文件的能力
插件(plugin)
- webpack运行生命周期过程中做一些其他任务(压缩,清理)
plugins:[
//实例化插件,指定template模板的位置
new HtmlWebpackPlugin({
template:"./public/index.html"
}),
//实例化清理
new CleanWebpackPlugin()
],
准备工作
- 初始化
npm init -y
- 安装webpack与webpack脚手架
npm i webpack webpack-cli -D
配置
- 默认在webpack.config.js配置文件中
devServer
- 安装
npm i webpack-dev-server -D
- 作用:开启一个本地服务器
- 具体项
- port:8080,//端口号
- hot:true,//热更新(文件保存,网页自动更新)
- host:“localhost”,//域名
- open:true,//默认自动打开浏览器
- proxy:{},//代理 与vue.config.js一致
- package.json:“scripts”: {“serve”: “webpack serve”,}
- 运行项目
npm run serve
//安装本地服务器 npm i webpack-dev-server -D
devServer:{
port:8080,
hot:true,//更新
host:"localhost",//域名
open:true,//默认自动打开浏览器
proxy:{},//代理 与vue.config.js一致
}
loader加载器
css处理
- 安装
npm i css-loader style-loader -D
- 作用:css-loader处理css文件 style-loader把加载好的css放入style标签
- 使用
module:{
rules:[
//当文件名test通过,使用如下插件
{
test:/\.css$/,
use:["style-loader","css-loader"]
},
]
}
处理文件(图片文件等)
- 安装
npm i file-loader url-loader -D
- 作用:加载图片和文件
- 使用:
//安装图片插件:npm i file-loader url-loader -D
{
test:/\.(png|jpg|jpeg|webp|ico|gif|bmp)$/,
use:[{
loader:"url-loader",
options:{
limit:5000,
name:"images/[hash].[ext]",//hash值 计算出图片的名称,ext后缀名
//选项,当图片小于5000字节的时候转换为base64编码(小图片减少一次http请求)
}
}]
},
处理css
- 安装
npm i sass sass-loader -D
- 作用:处理scss文件
- 使用:
module: {
rules: [
{
test: /\.scss$/,
use: [
/*"style-loader"*/ MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader",
],
},
]
}
plugin插件
html模板插件
- 安装
npm i html-webpack-plugin -D
- 在webpack.config.js中导入
const HtmlWebpackPlugin = require("html-webpack-plugin")
- 作用:生成html模板文件,自动把打包好的js插入到模板文件
- 使用:
plugins:[
//实例化插件,指定template模板的位置
new HtmlWebpackPlugin({
template:"./public/index.html"
}),
],
清理dist目录
- 安装
npm i clean-webpack-plugin -D
- 作用:打包前删除dist目录
- 使用:
const {CleanWebpackPlugin} = require("clean-webpack-plugin")
plugins:[
//实例化清理
new CleanWebpackPlugin()
],
抽出插件
- 安装
npm i mini-css-extract-plugin -D
- 作用:把css抽出作为一个单独的文件
- 导入
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
- 实例化
new MiniCssExtractPlugin()
- 配置loader
关于webpack的一些特殊标识
- [hash]:把内容通过hash算法算出来的一串字符
- [hash:7]:取hash字符串前7个
- [name]:原文件名称
- [ext]:文件的后缀名
目录别名
- 设置@为src目录的别名
resolve: {
alias: {
'@': path.resolve(__dirname, './src'), //设置@为src目录的别名
}
},
优化
css压缩
- 安装
npm i css-minimizer-webpack-plugin -D
- 导入
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
js压缩
- 安装
npm i terser-webpack-plugin -D
- 导入
const TerserPlugin = require("terser-webpack-plugin");
实现压缩与优化
optimization: {
//优化选项
minimize: true, //默认压缩
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin({
extractComments: false, //不将注释提取到单独的文件中
}),
], //压缩器
},
代码分割
splitChunks: {
//代码分割
chunks: "all",
},
开发工具
- 作用:错误与源代码有个一一对应关系(方便查找错误是哪个文件哪一行)
devtool:"eval-cheap-source-map"
html新增(link与script)
- < script defer src=“”></ script>:等待页面内容加载好再去加载js
- < link href=“” rel=“prefetch”>:提前预加载css
webpack中的魔法注释
- webpackChunkName:“jquery”:给当前加载的js命名
- webpackPrefetch: true:提前预加载js (等网络有空闲的时候)
import "./assets/my.scss";
var big = document.createElement("div");
big.innerHTML = `<span class="item">小淘气包</span>前端月薪过万`;
big.className = "big";
document.body.appendChild(big);
//安装 npm i jquery -S
//导入jQuery
import $ from "jquery"
//big被点击的时候才导入jQuery
big.onclick = function(){
//webpack魔法注释,给这个文件命名
//prefetch 提前预加载jquery (等网络有空闲的时候)
import(/* webpackChunkName:"jquery" , webpackPrefetch: true */"jquery")
.then(({default:$})=>{
console.log($);
})
}
哈希命名
作用
- 1、可以控制浏览器的缓存,当文件发生变化的时候,hash变化,文件名也就发生变化,浏览器就不缓存,当文件名保持不变,浏览器二次请求会从缓存里去请求内容
- 2、提供二次加载的速度(有效的控制缓存)
hash类型
- hash:只要项目内容发生变化,hash就会发生变化
- chunkhash:入口发生变化,当前的文件chunkhash会变化
- contenthash:内容发生变化contenthash值才发生变化
- 具体:
环境变量
-
配置:通过环境命令,产品环境压缩代码,是生产环境不压缩代码,打开devtool
-
项目开发中
产品环境baseURL http://dida100.com:8888, 生产环境baseURLhttp://localhost:8080
-
安装
npm i cross-env -D
- package.json传参
"build": "cross-env NODE_ENV=production webpack",
"serve": "cross-env NODE_ENV=development webpack serve",
- 在webpack.config.js中使用
mode:process.env.NODE_ENV
devtool:process.env.NODE_ENV==="pruction"?false:'eval-cheap-source-map'
- js文件中使用
var baseURL = "";
if (process.env.NODE_ENV == "production") {
var baseURL = "http://dida100.com";
} else {
var baseURL = "http://localhost";
}
console.log("当前环境变量", process.env.NODE_ENV, baseURL);
不要vue脚手架搭建项目
- 安装
npm i vue -S
npm i vue-loader -D
npm i vue-template-compiler -D
npm i vue-style-loader -D
npm i vue-hot-reload-api -D
- 或者一次性安装所有:
npm i vue-loader vue-template-compiler vue-style-loader vue-hot-reload-api -D
配置
- 导入
const { VueLoaderPlugin } = require("vue-loader");
- 配置
module: {
rules: [
{
test: /\.vue$/,
use: ["vue-loader"],
},
]
}
- 插件
plugins: [new VueLoaderPlugin(),]
js
- public/main.html:< div id=“app”></ div>
- main.js
- import { createApp } from “vue”;//导入创建app的方法
- import App from “./App.vue”;//导入App.vue
- createApp(App).mount(“#app”);//创建App并挂载
- App.vue
附页(webpack.config.js)
//导入html-webpack-plugin插件处理html目标
//提前安装npm i html-webpack-plugin -D
const HtmlWebpackPlugin = require("html-webpack-plugin");
//使用loader npm i css-loader style-loader -D
//作用:css-loader处理css文件 style-loader把加载好的css放入style标签
//npm i clean-webpack-plugin -D
//作用:清理dist目录(执行npm run build 需要清理上一次生成的内容)
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
//安装抽出插件 npm i mini-css-extract-plugin -D
//导入css抽出插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
//安装 npm i css-minimizer-webpack-plugin -D
//导入css优化插件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
//安装 npm i terser-webpack-plugin -D
//js压缩
const TerserPlugin = require("terser-webpack-plugin");
//安装npm i vue-loader vue-template-compiler vue-style-loader vue-hot-reload-api -D
//导入vue-loader
const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
optimization: {
//优化选项
minimize: true, //默认压缩
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin({
extractComments: false, //不将注释提取到单独的文件中
}),
], //压缩器
splitChunks: {
//代码分割
chunks: "all",
},
},
// resolve: {
// alias: {
// '@': path.resolve(__dirname, './src'), //设置@为src目录的别名
// }
// },
entry: {
main: "./src/main.js", //多入口
index: "./src/index.js",
}, //入口
output: {
//出口
filename: "[name]-[chunkhash].js", //文件名
path: __dirname + "/dist", //__dirname当前目录
},
mode: process.env.NODE_ENV, //模式:开发模式 production产品模式
// mode:"development",//模式:开发模式 production产品模式
// mode:"production",//模式:开发模式 production产品模式
plugins: [
//实例化插件,指定template模板的位置
new HtmlWebpackPlugin({
template: "./public/index.html", //模板
chunks: ["index"], //入口
filename: "index.html", //文件名
}),
new HtmlWebpackPlugin({
template: "./public/main.html", //模板
chunks: ["main"], //入口
filename: "main.html", //文件名
}),
//实例化清理
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "style-[contenthash:7].css",
}),
new VueLoaderPlugin(),
],
module: {
rules: [
{
test: /\.vue$/,
use: ["vue-loader"],
},
//当文件名test通过,使用如下插件
{
test: /\.css$/,
use: [/*"style-loader"*/ MiniCssExtractPlugin.loader, "css-loader"],
},
//需要提前安装 npm i sass sass-loader -D
{
test: /\.scss$/,
use: [
/*"style-loader"*/ MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader",
],
},
//安装图片插件:npm i file-loader url-loader -D
{
test: /\.(png|jpg|jpeg|webp|ico|gif|bmp)$/,
use: [
{
loader: "url-loader",
options: {
limit: 5000,
name: "images/[hash].[ext]", //hash值 计算出图片的名称,ext后缀名
//选项,当图片小于5000字节的时候转换为base64编码(小图片减少一次http请求)
},
},
],
},
{
test: /\.(ttf|json|svg)$/,
use: [
{
loader: "url-loader",
options: {
limit: 500,
name: "font/[hash].[ext]",
},
},
],
},
],
},
//安装本地服务器 npm i webpack-dev-server -D
devServer: {
port: 8080,
hot: true, //更新
host: "localhost", //域名
open: true, //默认自动打开浏览器
proxy: {}, //代理 与vue.config.js一致
},
// devtool:"eval-cheap-source-map",//错误与源代码有个一一对应关系(方便查找错误是哪个文件哪一行)
devtool:
process.env.NODE_ENV === "pruction" ? false : "eval-cheap-source-map", //错误与源代码有个一一对应关系(方便查找错误是哪个文件哪一行)
};
具体webpack使用api详情请参考:webpack有道笔记