webpack是什么
本质上,webpack 是一个用于现代 JavaScript 应用程序的_静态模块打包工具_。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
以上解释截图自官网
为什么要使用webpack
我们在平常开发过程中可能经常遇到以下问题
- 浏览器不支持less sass语法(缺乏样式编译功能)
- 不支持es6/es7(缺乏babel编译功能,把es6转成es5)
- 开发的时候要是我们修改一下代码保存之后浏览器就自动更新就好了(缺乏热更新功能)
- 本地请求远程接口会产生跨域问题(缺乏请求代理功能)
- 项目要上线了,要是能一键压缩代码啊图片什么的就好了(缺乏自动压缩打包功能)
webpack就是为了解决以上种种问题的
webpack的五个核心概念
1.入口(entry):入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
2.出口(output):output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中
3.loader:loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
4.插件(plugins):loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务
5.模式:通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化
新的改变
开始使用
1.使用 npm init 初始化一个项目,并安装webpack
2.npm i webpack webpack-cli -g // 全局安装
3.npm i webpack webpack-cli -D //写入到package.json的开发依赖中
4.按如下结构创建文件
|- package.json
+ |- index.html
+ |- /src
+ |- index.js
index.js文件
function add(x,y){
return x+y
}
console.log(add(1,2))
运行下面的指令就打包完成了
npx webpack
html文件引入打包后的main.js文件
html文件放在dist目录下
index.html
5.下面验证一下json文件是否能正常打包
src目录下新建data.json文件,内容如下
{
"name":"小明",
"age":18
}
index.js
import data from "./data.json";
console.log(data)
function add(x,y){
return x+y
}
console.log(add(1,2))
重新打包
npx webpack
执行结果没有问题
6.下面验证css文件是否能正常打包
src目录下新建index.css,内容如下
html,body{
height: 100%;
background-color: pink;
}
index.js
import "./index.css"
import data from "./data.json";
console.log(data)
function add(x,y){
return x+y
}
console.log(add(1,2))
重新打包
npx webpack
打包会报错,说明webpack不能处理css/img资源
打包样式资源
前面我们说过webpack无法处理样式资源,如果要处理,需要引入loader,写loader我们需要先写一下webpack的配置文件,配置一下webpack 作用就是指挥webpack怎么干活,干哪些活
webpack的配置文件要求必须在根目录下,名称必须为webpack.config.js
在根目录下创建webpack.config.js
//resolve是用来拼接绝对路径的方法,path是node自带的模块可以直接引入
const {
resolve} =require("path")
module.exports={
//入口,指示webpack从哪个文件开始打包
entry:"./src/index.js",
//出口,定义webpack的输出
output:{
//最终打包后输出的文件名
filename:"bundle.js",
//最终打包好的文件输出的位置 ,__dirname是node的一个变量,代表当前文件的目录的绝对路径
path:resolve(__dirname,"dist")
},
//loader的配置
module:{
//定义规则,遇到什么类型的文件应该调用 什么loader去处理
rules:[
{
//匹配哪些文件
test:/\.css$/,
//使用哪些loader进行处理
//use数组中loader执行顺序,从右到左,从下到上,依次执行
use:[
//style-loader的作用是创建一个标签,将js中的css样式资源插入进去,添加到页面中的head中生效
'style-loader',
//css-loader的作用是将css文件以字符串的形式变成common.js的模块加载到js中,内容是样式字符串
'css-loader'
]
}
]
},
//plugins的配置
plugins:[
],
//模式
mode:"development"
}
我们这里用到了css-loader和style-loader两个包,所以需要下载这两个包
npm i css-loader style-loader -D
重新打包,运行成功
这个时候dist目录下生成了一个bundle.js文件默认是main.js但是因为我们改了配置所以生成了bundle.js改一下html的引入文件,访问html文件,发现样式生效了
2.那么是否能解析less文件呢
src目录下新建index.less
#title{
color:yellow
}
src--index.js
import "./index.css"
import "./index.less"
打包–报错,因为没有配置less的loader
webpack.config.js配置一下,然后安装less-loader和less
npm i less-loader -D
npm i less -D
配置文件做如下修改
index.html
<div id="title">hello
</div>
重新打包,文字样式已经生效说明,less文件成功执行
插件
先安装插件
npm i html-webpack-plugin -D
引入webpack插件
功能:默认会创建一个新的html文件,自动引入打包输出的所有资源(js/css)
webpack.config.js添加如下配置,其他配置不用动
const HtmlWebpackPlugin=require("html-webpack-plugin")
//plugins的配置
plugins:[
new HtmlWebpackPlugin()
],
运行打包 npx webpack
会发现多了一个html文件
目前输出的是一个空的html文件,如果我需要一个有结构的html文件应该怎么办,
修改一下配置
这样重新打包,webpack生成的html会自动复制src里面的index.html的内容,并自动引入打包输出的所有资源(js/css)
打包图片资源
src目录下新建img文件夹,放入一张图片
src--index.html
src--index.css
运行 npx webpack打包会发现报错了
报错的原因正是因为我们引入的那种图片 ,因为webpack不能处理图片资源
所以我们需要对图片进行处理,同样也是用loader
1.先下载两个loader
npm i url-loader file-loader -D
2.修改webpack.config.js
运行打包 npx webpack
如果图片大于8kb会发现是正常打包的,如果图片小于8kb,会被base64处理,得到的路径是类似这样的
但是这种情况处理不了img标签引入的图片,因为打包之后文件名都变了,所以你引入的那个文件就找不到了
再加入一个loader
npm i html-loader -D
运行打包,发现还是不行,引入的路径是个对象
问题:
url-loader默认使用es6模块解析,
但是html-loader使用的是common.js,解析会出问题
解决:关闭url-loader的es6模块化,使用commonjs解析
重新运行 npx webpack就没问题了
如果嫌打包之后的图片名字太长,可以进行处理
devServer
目前我们的每次修改都需要重新打包,不然总是显示之前的效果。此时我们需要创建一个服务器帮助我们解决这个问题
1.先下载这个服务
npm i webpack-dev-server -D
2.webpack.config.js编写配置
3.启动服务器
npx webpack serve
此时如果修改别的文件,会发现页面自动就更新了不需要重新打包
打包优化
目前我们打包的html文件 css文件 img文件 js文件都直接存放到dist根目录了,很乱,能不能按照文件夹归类好
webpack.config.js
js输出优化:直接在filename后面加上文件夹的名字重新打包即可
img输出优化
css不需要优化,因为css都嵌入到js中了
重新运行npx webpack即可完成打包,就能看到打包好的文件就已经分类好了
提取css文件
1.首先下载插件
npm i mini-css-extract-plugin -D
2.修改配置vue.config.js
const MiniCssExtractPlugin=require("mini-css-extract-plugin");
3.删除style-loader 替换为我们的loader
因为style-loader的作用是创建style标签插入样式,但是我们现在是一个单独的css文件不需要style标签
4.运行打包
如果报错,加一个下面的配置
压缩css
1.下载插件
npm i optimize-css-assets-webpack-plugin -D
2.更改配置 webpack.config.js
const OptimizeCssAssetsWebpackPlugin=require("optimize-css-assets-webpack-plugin")
npx webpack
就能看到css代码经过了压缩
性能优化
开发环境优化
优化打包构建速度
示例
新建a.js和b.js文件,分别导出一个函数
在index.js文件中引入并调用
此时发现控制台输入了a和b,如果此时我修改了a.js文件的输出,那么会发现整个页面重新刷新了,b页面也重新执行了一次,那么问题来了,如果我这个项目有一百个js文件,当我修改了其中一个文件之后,其他99个文件并没有修改但也是重新执行了,这种效率肯定很浪费
引入一个新的东西来解决这个问题叫HMR
HMR:hot module replacement 热模块替换
作用:一个模块发生变化,只会重新打包这一个模块而不是所有模块
极大提升构建速度
使用方法,只需要在服务器配置加入hot:true就可以,注意需要重启服务
此时修改样式文件,会发现只有某个样式进行重新渲染了,如下
接下来修改js文件,改变a文件的输出,发现整个页面还是被重新加载了。
因为js文件默认不能使用HMR功能
添加支持HMR功能的代码
html文件也不能使用hmr功能(也不需要使用),并且也不能热更新,修改html文件并不会直接更新界面
解决:修改entry入口,将html文件引入,但是hmr还是不生效,因为我们的项目html文件
就只有一个,所以当html更改,这个文件一定会更新,不像是js文件有多个,可以单独
更新某一个
优化代码调试
source-map:一种提供源代码到构建后代码映射技术(如果构建后代码出错了,通过映射关系可以追踪到源代码错误),只需做下面配置即可
转载:https://blog.csdn.net/qq_40096030/article/details/114362529