准备:一些js文件、入口文件、html文件。npm init -y
初始化一个package.json文件
参考教程:尚某谷、 webpack官网
安装和运行
1.安装webpack和webpack-cli指令
npm webpack webpack-cli -D
解读:下载依赖包,webpack-cli是webpack 指令,-D 下载到开发依赖中
2.运行webpack
npx webpack ./src/main.js --mode=development
解读:运行webpack应用程序, 以./src/main.js为入口打包文件,--mode=development为开发模式,production为生产模式。
npx 可以使node_modules中的.bin文件夹临时添加为环境变量,就可以访问环境变量里面的应用程序,比如:webpack、webpack-cli等
npx webpack ./src/main.js --mode=production
解读:--mode=production为生产模式,打包后的代码会压缩,比开发模式少了很多代码。
3.打包后根目录下会出现dist目录,目录中是打包后的文件
4.在html文件中引入打包后的main.js文件,运行到浏览器中能正常使用。
要点:webpack本身功能比较少,只能处理js资源,一旦遇到css等其他资源就会报错。后续会学习如何处理其他资源。
开发模式基本配置
5大核心概念
1.entry(入口)
指示Webpack从哪个文件开始打包
2.output(输出)
指示Webpack打包完的文件输出到哪里去,如何命名等
3.loader(加载器)
webpack本身只能处理js、json、等资源,其他资源需要结组loader,Webpack才能解析
4.plugins(插件)
扩展Webpack的功能
5.mode(模式)
主要由两种模式:
- 开发模式:development
- 生产模式:production
提示:webpack是基于Node.js运行的,所以采用Common.js模块化规范
使用配置打包
1.根目录下创建webpack.config.js文件
const path=require('path');//path是nodejs核心模块,专门用来处理路径问题,这个模块提供了一些可使用的方法。
module.exports={
// 入口(相对路径)
entry:"./src/main.js",
// 输出
output:{
// 文件的输出路径(必须是绝对路径)
// __dirname nodejs的变量,代表当前文件的文件夹目录(webpack.config.js在哪个目录下)
path:path.resolve(__dirname,"dist"),
// 文件名
filename:'main.js'
},
// 加载器
module:{
rules:[
// loader的配置(可以使webpack处理其他资源,比如css文件等)
]
},
// 插件
plugins:[
//plugin的配置
],
// 模式
mode:'development',
}
2.终端输入命令进行打包
npx webpack
在终端中运行npx webpack指令,webpack会自动找到根目录下的webpack.config.js文件,webpack会按照这个文件里的配置进行打包。如果没有就会出错,除非在命令中写了配置。
开发模式介绍
开发模式顾名思义就是我们开发代码时使用的模式。
这个模式下主要做两件事:
1.编译代码,使浏览器 能识别运行
开发时我们有样式资源、字体图标、图片资源、html资源等。webpack默认都不能处理这些资源,所以我们要加载配置来编译这些资源。
2.代码质量检查,树立代码规范
提前检查代码的一些隐患,让代码运行时能更加健壮。
提前检查代码规范和格式,统一团队编译风格,让代码更优雅美观。
调用 require()
始终使用 CommonJS 模块加载器。 调用 import()
始终使用 ECMAScript 模块加载器。
处理css资源
webpack本身只能处理js、json、等资源,其他资源需要配置loader!
当你的项目中使用了css文件。这是webpack本身不能处理的。(流程:安装依赖->需要被处理的文件引入到->配置->运行指令)
1.首先安装css-loader和style-loader:
npm install --save-dev css-loader
npm i style-loader
2.然后把css引入到webpack入口文件中
import "./css/index.css";
3.在配置文件webpack.config.js中对下载的依赖进行配置
// 加载器
module:{
rules:[
// loader的配置(可以使webpack处理其他资源,比如css文件等)
{
test:/\.css$/, //test的意思是可以只检测xxx文件,$的意思是以什么为结尾
use:['style-loader','css-loader'] //use的执行顺序:从右到左(从下到上),先执行css-loader再执行style-loader
// css-loader可以将css资源编译成commonjs的模块到js中
// 将js中css通过创建style标签添加到html文件中生效
}
]
},
处理Less资源
less-loader 将less编译成css文件
1.首先安装css-loader、style-loader和less-loader:
npm install --save-dev css-loader
npm i style-loader
npm install less less-loader --save-dev
2.然后把less引入到webpack入口文件中
import "./less/index.less";
3.在配置文件webpack.config.js中对下载的依赖进行配置
// 加载器loader
module:{
rules:[
// loader的配置(可以使webpack处理其他资源,比如css文件等)
{
test:/\.css$/, //test的意思是可以只检测xxx文件,$的意思是以什么为结尾
use:['style-loader','css-loader'] //use数组里面是loader的执行顺序:从右到左(从下到上),先执行css-loader再执行style-loader
// css-loader可以将css资源编译成commonjs的模块到js中
// 将js中css通过创建style标签添加到html文件中生效
},
{
test:/\.less$/,
// loader:'xxx', //只能使用一个loader
use:['style-loader','css-loader','less-loader'] //use可以使用多个loader
//less-loader 将less编译成css文件
}
]
},
处理stylus资源
stylus-loader 将stylus编译成css文件
1.首先安装css-loader、style-loader和stylus-loader:
npm install --save-dev css-loader
npm i style-loader
npm install stylus-loader --save-dev
2.然后把less引入到webpack入口文件中
import "./stylus/index.less";
3.在配置文件webpack.config.js中对下载的依赖进行配置
// 加载器loader
module:{
rules:[
// loader的配置(可以使webpack处理其他资源,比如css文件等)
{
test:/\.styl$/, //stylus的文件名后缀是styl
// loader:'xxx', //只能使用一个loader
use:['style-loader','css-loader','stylus-loader'] //use可以使用多个loader
//stylus-loader 将stylus编译成css文件
}
]
},
处理图片资源
过去在Webpack4时,我们处理图片资源通过file-loader和url-loader进行处理
现在Webpack已经将两个Loader功能内置到Webpack里了,我们只需要简单配置即可处理图片资源
配置
不需要下载loader,使用asset类型,webpack自动处理图片资源
// 加载器loader
module:{
rules:[
// loader的配置(可以使webpack处理其他资源,比如css文件等)
{
test:/\.png|jpe?g|gif|webp$/, //stylus的文件名是styl
// loader:'xxx', //只能使用一个loader
type:'asset', //相当于使用了file-loader和url-loader进行处理图片
parser:{
dataUrlCondition:{
// 小于10kb的图片转base64
// 优点:减少请求数量 缺点:体积会更大
maxSize:10*1024,
}
},
generator: {
// 自定义输出图片文件名
// [hash]是文件名(hash是根据文字内容生成的id),[ext]是扩展名,[query]是url地址携带的参数
// [hash:10]在hash值后面写10代表只取前10位
filename: 'static/images/[hash:10][ext][query]'
}
}
]
},
当图片小于5kb时可以转化为base64格式的,这样可以减少向服务器请求图片的次数,但有一个缺点,转换后的文件会变大。
清空上次打包内容
每次运行webpack时,自动清空上次打包内容
在输出配置output中添加clean属性,值为true
output: {
// 文件的输出路径(必须是绝对路径)
// __dirname nodejs的变量,代表当前文件的文件夹目录(webpack.config.js在哪个目录下)
path: path.resolve(__dirname, "dist"),
// filename输出文件名
filename: 'static/js/main.js',
// clean把上一次打包的内容删除
// 原理:在打包前,将path整个目录内容清空,再进行打包
clean:true
},
处理字体图标资源
1.下载字体图标文件
- 打开 阿里巴巴矢量图标库
- 选择想要的图标添加到购物车,统一下载到本地
2.添加字体图标资源
-
src/fonts/iconfont.tff
-
src/fonts/iconfont.woff
-
src/fonts/iconfont.woff2
-
src/css/iconfont.css
// src里面的url是图标资源的路径位置,如果iconfont.css和图标资源不是同一个目录,要注意更改路径 @font-face { font-family: "iconfont"; /* Project id 3479021 */ src: url('../fonts/iconfont.woff2?t=1655868711636') format('woff2'), url('../fonts/iconfont.woff?t=1655868711636') format('woff'), url('../fonts/iconfont.ttf?t=1655868711636') format('truetype'); }
-
src/main.js
// 引入阿里巴巴图标库下载的css文件 import './css/iconfont.css';
-
webpack.config.js
{ test: /\.(ttf|woff2?)$/, //阿里巴巴矢量库的图标处理 // loader:'xxx', //只能使用一个loader type: 'asset/resource', //不会转base64 generator: { // 输出文件名 // [hash]是文件名(hash是根据文字内容生成的id),[ext]是扩展名,[query]是url地址携带的参数 // [hash:10]在hash值后面写10代表只取前10位 filename: 'static/media/[hash:10][ext][query]' } }
-
index/html
// 在网页中添加改图标 <span class="iconfont icon-a-zujiantianchong_huaban1fuben7"></span> <span class="iconfont icon-a-zujiantianchong_huaban1fuben17"></span>
处理其他资源
开发中可能还存在一些其他资源,如音视频等,可以在配置中设置类型值为asset/resource,就可以把资源原封不动的输出
{
test: /\.(ttf|woff2?|map3|map4|avi)$/, //阿里巴巴矢量库的图标和其他资源一并处理
// loader:'xxx', //只能使用一个loader
type: 'asset/resource', //不会转base64
generator: {
// 输出文件名
// [hash]是文件名(hash是根据文字内容生成的id),[ext]是扩展名,[query]是url地址携带的参数
// [hash:10]在hash值后面写10代表只取前10位
filename: 'static/media/[hash:10][ext][query]'
}
}
处理js资源
Webpack对js处理是有限的,只能编译js中ES模块化语法,不能编译其他语法,导致部分js不能在IE等浏览器运行,所以我们希望做一些兼容性处理。
其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检查代码格式,需要使用专业的工具来检测。
- 针对js兼容性处理,使用Babel来完成
- 针对代码格式,检测代码格式无误后,在由Babel做代码兼容性处理。
Eslint
可组装的javaScript和JSX检查工具
这句话意思就是:它是用来检测js和jsx语法的工具,可以配置各项功能
我们使用Eslint,关键是写Eslint配置文件,里面写上各种rules规则,将来运行Eslint时就会以写的规划对代码进行检查。
1.配置文件
配置文件由很多种写法:创建一个文件或者package.json中写配置。
- .eslintrc.*:新建文件,位于项目根目录
- .eslintrc
- .eslintrc.js
- .eslintrc.json
- 区别在于配置格式不一样,选其中一种即可
- package.json中eslintConfig:不需要创建文件,在原有文件基础上写
EsLint会查找和自动读取它们,所以以上配置文件值需要存在一个即可
2.具体配置
我们以.eslintrc.js
配置文件为例:
module.exports={
//解析选项
parserOptions:{},
//具体检查规则
rules:{},
//继承其他规则
extends:[],
// ...
// 其他规则详见:https://eslint.bootcss.com/docs/user-guide/configuring
}
(1).parserOptions解析选项
parserOptions:{
ecmaVersion:6, //ES语法版本
sourveType:"module", //ES模块化
ecmaFeatures:{ //ES其他特性
jsx:true //如果是React项目,就需要开启jsx语法
}
}
(2).rules具体规划
- "off"或0-关闭规则
- "warn"或1-开启规则,使用警告级别的错误:warn(不会导致程序退出)
- "error"或2-开启规则,使用错误级别的错误:error(当被触发的时候,程序会退出)
rules:{
semi:"error",// 禁止使用分号
"array-callback-return":'warn',// 强制数组方法的回调函数中有return语句,否则警告
'default-case':[
'warn',
{commentPattern:'^no default$'}// 允许在最后注释 no defult,就不会有警告了
],
eqeqeq:[
'warn',// 强制使用===和!==,否则警告
'smart'// https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
]
}
(3).extends继承
开发中一点点写rules规则太费劲了,所以有更好的办法,继承现有规则。
现有以下较为有名的规则:
- Eslint官方的规则:eslint:recommended
- Vue Cli官方的规则:plugin:vue/essential
- React Cli官方的规则:react-app
//例如在vue项目中,我们可以继承vue cli官方的规则
module.exports={
extends:"plugin:vue/essential",
rules:{
//自己写的规则会覆盖掉引用的规则,优先级更高
eqeqeq:["warn","smart"]
}
}
3.在Webpack中使用
(1).下载eslint包
npm i eslint-webpack-plugin eslint -D
(2).在webpack.config.js引入eslint-webpack-plugin依赖包,在plugins配置中使用插件
Eslint属于插件,在使用的时候需要引入
注:ESLint实例中的overrideConfig属性可以覆盖与此实例一起使用的所有配置。里面的rules也可以生效
const ESLintPlugin=require('eslint-webpack-plugin')
plugins: [
new ESLintPlugin({
context:path.resolve(__dirname,"src"),
overrideConfig:{
rules:{
// "no-var":2 //不能使用var定义变量
}
}
})
],
(2).定义Eslint配置文件
如果只是申明了一个ESlink实例,没有.eslintrc
配置文件,webapck是打包不了的。
新建一个名为.eslintrc.js
的配置文件
- .eslintrc.js
module.exports={
//继承Eslint规则
extends:["eslint:recommended"], //继承Eslint官方的规则
env:{
node:true, //启用node中全局变量
browser:true, //启用浏览器中全局变量
},
parserOptions:{
ecmaVersion:6,
sourceType:"module",
},
//rules中写规则
rules:{
"no-var":2 //不能使用var定义变量
}
}
(4)如果vscode安装了ESlink扩展,一些不需要检查的文件可以新建名为.eslintignore
的忽略文件,在这个文件中写入文件目录/文件名
dist
(3).在webpack入口文件中故意写一些不符合规则的语句,测试效果
- main.js
var a=0
console.log(a)
终端返回结果:ERROR in D:\vue_pro\webpack_test\src\main.js 13:1 error Unexpected var, use let or const instead no-var
ESlink生效!
babel
Javascript编译器
主要用于将ES6语法编写的代码转换为向后兼容的Javascript语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
1.配置文件
配置文件由很多种写法:
- babel.config.*:新建文件,位于项目根目录
- babel.config.js
- babel.config.json
- .babelrc.*:新建文件,位于项目根目录
- .babelrc
- .babelrc.js
- .babelrc.json
- package.json中babel:不需要创建文件,在原有文件基础上写
Babel会查找和自动读取它们,所以以上配置文件只需要存在一个即可
2.具体配置
创建babel.config.js配置文件
module.exports={
//预设
presets:[],
}
preset预设
简单理解:preset就是一组Babel插件,扩展Babel功能(需要npm下载插件)
@babel/preset-env
:一个智能预设,允许您使用最新的Javascript@babel/preset-react
:一个用来编译React jsx语法的预设@babel/preset-typescript
:一个用来编译TypeScript语法的预设
3.在webpack中使用
(1)下载依赖包
npm i babel-loader @babel/core @babel/preset-env -D
(2)定义babel配置文件
方法一:直接在webpack.config.js文件中写babel的配置
// 加载器loader
module: {
rules: [
// loader的配置(可以使webpack处理其他资源,比如css文件等)
{
test: /\.js$/, //查找文件名字
exclude: /node_modules/, //排除node_modules中的js文件(这些文件不处理)
// use: { //也可以不用写在use里
// loader: "babel-loader",
// options: {
// presets: ["@babel/preset-env"]
// }
// },
loader: "babel-loader",
options: { //options可以在单独的babel配置文件中写
presets: ["@babel/preset-env"]
}
},
]
},
方法二:新建一个babel.config.js文件,写入以下代码
module.exports={
// 智能预设:能够编译ES6语法
presets:['@babel/preset-env']
}
处理HTML资源
每次打包后,需要手动引入的打包好的js文件,使用插件自动引入js文件
1.下载依赖包
npm i html-webpack-plugin -D
2.配置
-
webpack.config.js
(1)引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
(2)调用插件
plugins: [ // HtmlWebpackPlugin 插件自动引入打包好的js资源 // 需要配置template才不会改变原有的html结构,模板:以public/index.html文件创建新的html文件 // 新的html文件特点:1.结构和原来的一致 2.自动引入打包输出的资源 new HtmlWebpackPlugin({ template: path.resolve(__dirname, "public/index.html"), }) ],
最后在输出文件中的main.js可以看到效果
开发服务器&自动化
每次写完代码都需要手动输入指令才能编译代码,开启自动化后,保存就能重新编译代码
1.下载依赖包
npm i webpack-dev-server -D
2.配置
module.exports = {
// 开发服务器:不会打包到输出文件中,是在内存中编译打包的
// 当我们把dist目录下的文件删除时,浏览器还是可以看到效果,说明dist目录下有没有文件不影响我们看的效果
devServer:{
host:"localhost", //启动服务器域名
port:"3000", //启动服务器端口号
open:true, //是否自动打开浏览器
},
}
生产模式介绍
生产模式是开发完成代码后,我们需要得到代码即将部署上线
这个模式下我们主要对代码进行优化,让其运行性能更好。
优化主要从两个角度出发:
1.优化代码运行性能
2.优化代码打包速度
生产模式和开发模式的对比
输出路径的区别:
开发模式可以不设置输出路径,但是生产模式必须设置。
开启服务器的区别:
开发模式需要开启服务器,生产模式不需要。
指令的区别:
启动开发模式的配置文件
npx webpack serve --config ./config/webpack.dev.js
启动生产模式的配置文件
npx webpack --config ./config/webpack.prod.js
指令压缩
每次运行webpack配置文件需要打一串长的代码,可以在package.json文件中配置scripts运行脚本命令,就可以实现指令缩写
前提准备:把开发模式的配置文件和生产模式的配置文件抽出来放在config文件,config文件放在根目录下,注意更改配置文件中的绝对路径。
"scripts": {
"start": "npm run dev",
"dev": "webpack serve --config ./config/webpack.dev.js",
"build": "webpack --config ./config/webpack.prod.js"
},
运行指令:
运行开发模式:npm run dev 或npm start
运行生产模式:npm run build
CSS处理
未处理前的加载方式:css文件目前被打包到js文件中,放js文件加载时,会创建一个Style标签来生产样式
缺点:这样对于网站来说,会出现闪屏现象,用户体验不好
提取css成单独文件
我们应该是单独的Css文件,通过link标签加载性能才好
1.下载依赖包
npm i mini-css-extract-plugin -D
2.配置
webpack.prod.js
(1)引入插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");//引入单独提取css的插件
(2)调用插件
plugins: [
//打包后的文件都会在main.js中
//new MiniCssExtractPlugin()
//设置filename属性,指定打包后的css文件
new MiniCssExtractPlugin({filename:"static/css/main.css"})
]
(3)配置
把rules中所有用到style-loader
加载器的地方替换成MiniCssExtractPlugin.loader
module.exports = {
//module加载器
module: {
rules: [
{
test: /\.css$/, //test的意思是可以只检测xxx文件,$的意思是以什么为结尾
use: [MiniCssExtractPlugin.loader, 'css-loader'] //use数组里面是loader的执行顺序:从右到左(从下到上),先执行css-loader再执行style-loader
// css-loader可以将css资源编译成commonjs的模块到js中
// 将js中css通过创建style标签添加到html文件中生效
},
]
}
}
兼容性处理
1.下载依赖包
下载三个依赖包:postcss-loader依赖postcss,postcss需要用postcss-preset-env智能预设来解决样式兼容性问题。
npm i postcss-loader postcss postcss-preset-env -D
2.配置
所有用到css-loader加载器的配置后面都加上postcss-loader加载器
module: {
rules: [
// loader的配置(可以使webpack处理其他资源,比如css文件等)
{
test: /\.css$/, //test的意思是可以只检测xxx文件,$的意思是以什么为结尾
use: [MiniCssExtractPlugin.loader, 'css-loader',
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", //能解决大多数样式兼容性问题
]
}
}
}] //use数组里面是loader的执行顺序:从右到左(从下到上),先执行css-loader再执行style-loader
// css-loader可以将css资源编译成commonjs的模块到js中
// 将js中css通过创建style标签添加到html文件中生效
},
]
}
3.配置兼容性程度
在package.json配置browserslist
//与scripts同级
"browserslist":{
"ie>=8"//兼容到ie8以上
}
//一般项目中的配置
"browserslist":[
"last 2 version","1%","not dead"
]
//last 2 version所有浏览器都只兼容最后两个版本
//1% 覆盖99%的浏览器
//not dead 有些版本凉了就不兼容
封装样式loader函数
1.封装
// 用来处理样式的loader
function getStyleLoader(pre) {
return [
MiniCssExtractPlugin.loader, 'css-loader',
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", //能解决大多数样式兼容性问题
]
}
}
},
pre
].filter(Boolean)
}
2.使用
rules: [
{
test: /\.less$/,
// loader:'xxx', //只能使用一个loader
use: getStyleLoader('less-loader') //use可以使用多个loader
//less-loader 将less编译成css文件
},
]
css压缩
1.下载依赖包
npm i css-minimizer-webpack-plugin -D
2.配置
plugins: [
new CssMinimizerPlugin()
]