由于对于webpack的各项配置不是太熟悉,用到了都是百度抄作业,就想系统的学习一下,在b站找了学习视频,视频讲的很详细就做了做笔记。
我的webpack学习之路(webpack基础开发配置)
我的webpack学习之路(关于webpack的性能优化)
我的webpack学习之路(webpack配置详解)
文章目录
1、webpack
webpack设置一个入口文件
通过入口文件形成依赖关系图,根据先后顺序引入资源
形成chunk (代码块)
chunk根据不同资源进行不同处理
这个处理过程叫打包
打包完成后输出的文件为bundle
2、webpack的五个核心概念
-
Entry
入口(Entry)指示Webpack以哪个文件为入口起点开始打包,分析内部依赖图
-
Ouput
输出(Ouput)指示webpack打包后的资源bundles输出到哪里去,以及如何命名
-
Loader
Loader让Webpack能够出处理那些非JavaScript文件(webpack自身只理解JavaScript)
类似翻译官,将英文,日文等翻译成中文,这样中国人就能看懂了
-
Plugins
插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等
loader类似翻译官的工作,如果让他去开飞机,开大炮,疏通下水管道,它是做不了的。需要一些专业的人来做。而webpack就是将这些交给插件(开飞机的插件、开大炮的插件、疏通下水道插件)来做
-
Mode
模式(Mode)指示Webpack使用相应模式的配置
选项 | 描述 | 特点 |
---|---|---|
development(开发) | 会将process.env.NODE_ENV的值设为development。 启用NamedeChunksPlugin和NamedModulesPlugin。 | 能代码本地调试运行的环境 |
production(生产模式) | 会将process.env.NODE_ENV的值设为production。 启用FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenation,NoEmitOnErrorsPlugin, OccurrenceOrderPlugin,SideEffectFlagPlugin和 UgligyJsPlugin | 能让代码优化上线运行的环境 |
3、webpack初体验
全局安装webpack
npm i webpack webpack-cli -g
在本地安装
npm i webpack webpack-cli -D
根目录
---build
---node_modules
---src
|---index.js
---packages-lock.json
---packages.json
// index.js
// webpack入口文件
/*
1.运行指令
开发环境:webpack ./src/index.js -o ./build/built.js --mode=development
wabpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js
整体打包环境是开发环境
生产环境:webpack ./src/index.js -o ./build/built.js --mode=production
wabpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js
整体打包环境是生产环境
2.结论
1.webpack能处理js/json,不能处理css/img等资源
2.生产环境和开发环境将ES6模块化编译成浏览器能识别的模块化~
3.生产环境比开发环境多一个压缩js代码
*/
4、打包样式资源
新建一个文件
根目录
---src
---index.css
---index.js
首先在index.css写如一些css样式
body,html {
margin: 0;
padding: 0;
background-color: pink;
}
在index.js引入index.css
// 引入样式资源
import './index.css'
这里webpack不能打包css样式,需要借助loader(帮助webpack解析它不能识别的模块),使用loader就必须定义配置文件
这里在根目录下定义配置文件,新建一个webpack.config.js文件,与src同层级
/*
webpack.config.js webpack的配置文件
作用:指示webpack 干那些活(当你运行webpack指令的时候,会加载里面的配置,以里面的配置来干活)
所有的构建工具都是基于Nodejs平台运行的~模块化默认采用commomjs。
src是写项目代码 用的ES6模块化
webpack是写配置代码 基于node平台,所以用的commonjs模块化
这两个是两方面
*/
const { resolve } = reuqire('path') // 引入nodejs的path模块,通过解构赋值来提取reslove
// resolve是一个专门处理(拼接)绝对路径的一个方法
// commonjs 的 module.exports 去暴露一个对象
module.exports = {
// webpack配置
// 先写入上面五个核心配置
entry: './src/index.js', // 入口起点 指示从./src/index.js开始打包
output: { // 输出 注意:输出是一个对象,有两个属性
filename: 'build.js', // 输出的文件名
/*
path: ''输入的路径 这里输出的build文件下面, 需要在src同层级下新建一个build文件夹
通常来讲这里会写个绝对路径(避免出错),需要借助node的一个核心模块path
__dirname:nodejs的变量,代表当前文件(webpack.config.js)的目录的绝对路径(这里webpack路径就是 ./根目录)
*/
path: resolve(__dirname,'build') // 输出到webpack.config.js路径的build文件夹下面(./根目录/build)
},
// laoder配置
module: {
rules: [
// 详细的loader配置
]
},
// plugins的配置
plugins: [
// 详细plugins的配置
],
// 模式
mode: 'development' // 开发模式
// mode: 'production' // 生产
}
以上就做了一个简单的配置搭建,还不能处理css样式,需要使用一个东西css-loader
如何使用
// webpack.config.js
// laoder配置
module: {
rules: [
{
// 匹配那些文件 通常使用正则匹配
test: /\.css$/, // 匹配文件名以.css结尾,会遍历所有文件,一旦发现.css文件就会进行处理
// 使用use进行处理,使用那些loader进行处理
use: [
// use数组中loader执行顺序:从右到左,从下到上依次执行
// 处理样式文件需要以下两个loader
'style-loader', // 创建一个style标签,将js中的样式资源插入进去,添加到head中生效
'css-loader' // 将css文件变成commonjs模块加载js中,里面的内容是样式字符串
]
}
]
},
配置完成后下载依赖
首先我在根目录下npm init,初始化一个包描述文件
然后下载weback和webpack-cli开发依赖
npm i webpack webpack-cli -D
再下载style-loader和css-loader依赖
npm i style-loader css-loader -D
依赖下载完成后运行webpack命令,就会开始打包
webpack
在这里我运行webpack时报错
webpack : 无法将“webpack”项识别为 cmdlet、函数、脚本文件 或可运行程序的名称。请检查名称的拼写,如果包括路径,请确 保…
我的解决办法是将webpack和wabpack-cli全局安装,在运行webpack命令就顺利打包了
npm install webpack -g
npm install webpack-cli -g
运行完成之后,在build文件夹下会多出一个build.js文件
在build.js中会看到如上所示,写的样式,css-loader 将其变成commonjs模块加载js中,里面的内容是样式字符串
这时在build文件夹中添加一个index.html文件,引入build.js,在浏览器中的打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./build.js"></script>
</body>
</html>
这就是’style-loader’的作用: 创建一个style标签,将js中的样式资源插入进去,添加到head中生效
以上就是简单的webpack打包样式
5、webpack打包html资源
上面处理样式资源时使用的是loader,loader需要先下载,再使用(配置loader)
处理html资源时我们需要用到插件(plugins),plugins也是需要先下载,然后是需要引入,其次是使用
处理html资源所用的插件是html-webpack-plugin
npm i html-webpack-liugin -D // 下载
创建文件
根目录
---build
---src
---index.html
---index.js
---webpack.config.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hello html</h1>
</body>
</html>
function add(num,num2) {
return num + num2
}
console.log(add(3,3))
const { resolve } = reuqire('path')
// 下载后,这里引入htnml插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: 'build.js',
path: resolve(__dirname,'build')
},
module: {
rules: []
},
plugins: [
// html-webpack-plugin
// HtmlWebpackPlugin因为它是一个构造函数,使用new 调用
// 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(js/css)
new HtmlWebpackPlugin()
],
// 模式
mode: 'development' // 开发模式
// mode: 'production' // 生产
}
这样就简单的配置好了使用webpack命令,就会在build文件夹下多出两个文件,一个build.js和一个index.html,打开index.html文件会发现自动引入了build.js不需要再入上面一样,需要自己创建index.html文件,手动引入build.js
<!-- ./build/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 这就是自动添加的,不是手动添加的 -->
<script type="text/javascript" src="build.js"></script>
</body>
</html>
这里会发现src/index.html和build/index.html,除了build下自动引入了build.js,src/index.html的<h1>的内容在build/index.html中不存在 ,但add()方法还是会执行
需求:需要有结构的HTML文件。就是说不只要自动引入build.js。我们编写的html结构也要打包处理出来
plugins: [
new HtmlWebpackPlugin({
// 使用template属性,就会复制'./src/index.html'文件,并自动引入打包输出的所有资源
template: './src/index.html'
})
],
这样配置完成后运行webpack命令,在打开build/index.html文件,就会发现有src/index.html的结构了
<!-- ./build/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hello html</h1>
<!-- 这就是自动添加的,不是手动添加的 -->
<script type="text/javascript" src="build.js"></script>
</body>
</html>
这样结构既有了html结构,add()方法也会执行
6、webpack打包图片资源
打包图片资源需要用到两个loader: url-loader, file-loader
// webpack基本配置
const {resolve} = require('path')
const HtmlWebpackPlugin = reuqire('html-webpack-plugin')
module.exports = {
entry: './src/index',
output: {
fileaname: 'build.js',
path: resolve(__dirname, 'build')
},
module:{
rules: [
{
test: /\.(jpg|png|gif)$/,
// 这里只使用一个loader处理时,可以不用使用数组的形式,直接使用laoder:'loader名'的形式
// 这里能因为url-loader是依赖于file-loader的,所以需要下载两个loader
loader: 'url-loader',
//options是用于对loader进行配置
options: {
// 打包图片的时候不会原封不动的输出
// 这个limit配置是:当图片大小 小于 32kb,就会被base64处理
// 优点:减少请求数量(减轻服务器压力)
// 缺点: 图片体积会更大(base64)(文件请求变慢)
limit: 32 * 1024
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
}
这样就配置好了一个打包图片资源的loader,运行webpack命令后,会在build文件下看到处理后的打包文件,其中图片文件的名称是一串长字符,是hash值
但是这用配置只能处理css中的图片引入(backgroung-img:url(’…’)),对于html文件中的图片引入(img)是处理不了的,只会原封不动的复制过去
// build文件下的html文件
<img src="./01.html">
// 这里 如果说按上述配置了webpack,打包完成后,src就相对路径,这build文件下是找不到为01的图片的。
所以说要处理html文件中的图片引入问题,还需要借助一个loader来处理html-loader
module:{
rules: [
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 32 * 1024,
//关闭url-loader的es6模块化
esModule: false,
// 给图片重命名
// [hash:10] 去图片的hash前10位
// [ext] 文件的原扩展名
name: '[hash:10].[ext]'
}
},
{
test: /\.html$/,
// 处理html文件中的img图片引入(负责引入这个图片,从而能被url-loader处理)
laoder: 'html-loader'
}
]
}
这里运行webpack处理时,还会有一个问题,打包后img图片的src出错了,这是因为url-loader默认使用es6模块解析,而html-loader引入图片是commonjs,解决:关闭url-laoder的es6模块化,使用commonjs
<!--build/index.html-->
<img src="[object Moudle]">
7、如何打包其他资源
例如:字体资源,字体图标资源等等
这些资源不需要做其他处理,原封不动输出出去,这些资源就属于其他资源
处理其他资源统一使用file-loader处理
//在入口文件index.js中引入要处理的其他资源
import './index.css' // css中包含了字体资源
// webpack.config.js中的loadere配置
module: {
rules: [
{
test:/\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他资源(除了html/css/js资源以为的其他资源)
{
// 使用exclude排除css/html/js资源
exclude:/\.(html|css|js)$/,
loader: 'file-loader'
}
]
}
8、学习期间所有用到的依赖
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"babel-loader": "^8.1.0",
"core-js": "^3.6.5",
"css-loader": "^5.0.0",
"eslint": "^7.12.1",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.1",
"file-loader": "^6.2.0",
"html-loader": "^1.3.2",
"html-webpack-plugin": "^4.5.0",
"less": "^3.12.2",
"less-loader": "^7.0.2",
"mini-css-extract-plugin": "^1.2.1",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^4.0.4",
"postcss-preset-env": "^6.7.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"workbox-webpack-plugin": "^5.1.4"
},