黑马2021-8Vue教程学习笔记
为什么b站上面有视频还去搞这个自学笔记呢,因为看视频是巨浪费时间的,看视频学习过的都知道,
视频中难免也会遇到一些坑,因为编程技术尤其是前端在不断更新,这个自学笔记就是以一种大白话的形式详细的以我自己学习的角度展现出来,并且会不断更新
代码和笔记不断更新
gitee代码仓库地址
https://gitee.com/hanming886677/hanm-heima-vue
如果直接克隆项目 cnpm install 下载项目所需依赖
备用前端gei忽略提交文件
.gitignore文件
.DS_Store
change-rows-color/node_modules
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
package-lock.json
yarn.lock
webpack的使用
jquery隔行变色案例不兼容问题引入webpack
初始化包管理配置文件 package.json
npm init -y
这个时候就可以使用npm下载非全局js框架来使用,以往都是使用链接形式引入cdn或者去网上找源代码复制下来使用
现在使用包管理配置文件就很方便
npm i jquery -S
npm i jquery --save
这个s的作用就是将下载的包名还有版本号记录到 packae.json里面的dependencies
对象里面
–save 和 -S的作用是完全一样的
下载webpack解决问题
下载webpack解决使用es6导入导出语法在index.html中引入
<script src="index.js"></script>
浏览器不兼容问题导致的报错
npm install webpack@5.42.1 webpack-cli@4.7.2 -D
npm install webpack@5.42.1 webpack-cli@4.7.2 -save-dev
-D 的作用是将下载的webpack@5.42.1 webpack-cli@4.7.2的包名和版本号记录到packae.json里面的devDependencies
对象里面
-D 是 --save-dev的简写
dependencies 和 devDependencies区别:
dependencies 是用来记录开发阶段和项目上线阶段都要用到的包名称或者包的版本号
devDependencies 是只记录项目开发阶段要用到的包名称或者包的版本号
在项目中配置webpack
①
在项目根目录中,创建名为 webpack.config.is 的 webpack 配置文件,并初始化如下的基本配置
//使用Node.js中的导出语法,向外导出一个webpack的配置对象
model.exports={
//development是开发阶段
//production 是生产阶段
//代表 webpack 运行的模式, 可选值有两个 development和production
model:'development'
}
②
在 package.json 的 scripts 节点下,新增 dev 脚本如下
"scripts": {
"dev": "webpack" //script 节点下的脚本,可以通过 npm run 执行。例如 npm run dev
},
③
在终端(就是项目根目路下使用命令行)中运行
npm run dev
命令,启动 webpack 进行项目的打包构建
运行完毕后,webpack就对我们的项目进行了一次操作,解决掉不兼容的问题
项目中会多出一个main.js文件,这个时候把index.html中的<script src="index.js"></script>
改为<script src="main.js"></script>
就完成了,彻底没有问题了
注意:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
}
"test": "echo \"Error: no test specified\" && exit 1"
, 可以删掉没有用
webpack 运行的模式使用production,dist文件夹下的打包的文件体积就会少,适用于生产环境
Webpack 中的默认约定
在 webpack 4.x和5x的版本中,有如下的默认约定
①默认的打包入口文件为 src -> index.js
②默认的输出文件路径为 dist -> main.js
注意: 可以在webpack.config.js中修改打包的默认约定
自定义打包的入口与出口
在 webpack.config.js 配置文件中,通过 entry 节点指定打包的入口。通过 output 节点指定打包的出口示例代码如下:
webpack.config.js文件
// 导入Node里面的模块
const path = require('path')
//使用Node.js中的导出语法,向外导出一个webpack的配置对象
module.exports={
//development是开发阶段
//production 是生产阶段
//代表 webpack 运行的模式, 可选值有两个 development和production
//结论: 开发时候一定要用 devlopment,因为追求的是打包的速度,而不是体积
//反过来,发布上线时候一定要用production 因为上线追求的是体积小,而不是打包速度快
mode:'development',
// entry:'指定要处理那个文件为打包的入口'
// __dirname 代表当前文件(webpack.config.js)所处的目录也就代表项目中的根目录
// path.join(__dirname,'./src/index1.js') 拼接路径
entry: path.join(__dirname,'./src/index1.js'),
// 指定打包的出口就是生成的文件要存放到哪里
// 记得重新生成 npm run dev,并更改最新生成的打包文件index1.html里面的script标签 src路径指定的内容
output:{
// 存放目录
// __dirname 代表当前文件(webpack.config.js)所处的目录也就代表项目中的根目录
// path.join(__dirname,'dist') 拼接路径
path: path.join(__dirname,'dist'),
//生成的文件名
filename:'bundle.js'
}
}
隔行变色案例代码+上面的webpack.config.js文件
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
ul li{
list-style-type: none;
}
</style>
<!--<script src="../dist/main.js"></script>-->
<script src="../dist/bundle.js"></script>
</head>
<body>
<ul>
<li>这是第1个li</li>
<li>这是第2个li</li>
<li>这是第3个li</li>
<li>这是第4个li</li>
<li>这是第5个li</li>
<li>这是第6个li</li>
<li>这是第7个li</li>
<li>这是第8个li</li>
<li>这是第9个li</li>
</ul>
</body>
</html>
index.js和index1.js的区别
最开始使用的Webpack 中的默认约定所以是index.js文件
之后自定义打包的入口与出口就有了新文件
index.js
// 1. 使用ES6导入语法,导入jQuery
import $ from 'jquery'
// 2. 定义jquery的入口函数
/**
* 入口函数的解释 :
* 入口函数1:
* $(function(){
*
* });
* 入口函数2:
* $(document).ready(function(){
*
* });
* 意思是:一旦dom结构渲染完毕即可执行内部代码。
*
* 二、和window.onload的区别
* 区别1:jQuery入口函数可以书写多次,window.onload只能书写一次;
* 区别2:执行的时机不同,jQuery的入口,一旦我dom结构渲染完毕即可执行内部代码,不必等到所有外部资源加载完成;window.onload 的是等页面文档、外部的js文件、css文件、图片加载完毕才执行内部代码。
*/
$(function (){
//3. 实现奇偶行变色
// 奇数行为红色
$('li:odd').css("background-color",'red')
$('li:even').css("background-color",'pink')
})
index1.js
// 1. 使用ES6导入语法,导入jQuery
import $ from 'jquery'
// 2. 定义jquery的入口函数
/**
* 入口函数的解释 :
* 入口函数1:
* $(function(){
*
* });
* 入口函数2:
* $(document).ready(function(){
*
* });
* 意思是:一旦dom结构渲染完毕即可执行内部代码。
*
* 二、和window.onload的区别
* 区别1:jQuery入口函数可以书写多次,window.onload只能书写一次;
* 区别2:执行的时机不同,jQuery的入口,一旦我dom结构渲染完毕即可执行内部代码,不必等到所有外部资源加载完成;window.onload 的是等页面文档、外部的js文件、css文件、图片加载完毕才执行内部代码。
*/
$(function (){
//3. 实现奇偶行变色
// 奇数行为红色
$('li:odd').css("background-color",'red')
$('li:even').css("background-color",'cyan')
})
webpack插件的使用
webpack 插件有如下两个:
通过安装和配置第三方的插件,可以拓展 webpack 的能力,从而让 webpack 用起来更方便。最常用的webpack 插件有如下两个: ① webpack-dev-server
类似于 nodejs 阶段用到的 nodemon 工具
每当修改了源代码,webpack 会自动进行项目的打包和构建
② html-webpack-plugin
webpack 中的 HTML 插件(类似于一个模板引擎插件)
可以通过此插件自定制index.html页面的内容
安装和配置webpack-dev-server插件
运行此命令安装
npm install webpack-dev-server@3.11.2 -D
配置 webpack-dev-server
① 修改 package.json -> scripts 中的 dev 命令如下:
"scripts": {
"dev": "webpack serve" //script 节点下的脚本,可以通过 npm run 执行
},
② 再次运行 npm run dev 命令,重新进行项目的打包
这里运行的时候出现了报错: TypeError: options.forEach is not a function
这个原因是webpack-cli版本旧的问题, cnpm install webpack-cli -D
重新下载一下,就到了最新版本,就没问题了
之后又出现爆红:
[webpack-cli] webpack Dev Server Invalid Options
options should NOT have additional properties
options should NOT have additional properties解决方案就是:
不要加版本号,一律下载最新版就没有那么多问题
cnpm install webpack-dev-server -D
注意: webpack-dev-server 会启动一个实时打包的 http 服务器
③ 在浏览器中访问 http://localhost:8080 地址,查看自动打包效果
如果你是跟着我这个教程一步一步走的,这里你会发现这样的错误
那么这里是为什么呢,之前项目中源代码是存放在src文件架下的
但是下载的最新的
webpack-dev-server
它默认访问的是项目根目录下的public文件夹也就是存放公开的html文件
所以呢这里我们要去修改src文件夹重命名为 public
但是注意注意注意最新版的
webpak-dev-server
官方默认的webpack.config.js配置文件,配置已经改动了官方文档地址 : https://webpack.docschina.org/configuration/dev-server/
他是这样的:
const path = require('path'); module.exports = { //... devServer: { static: { // 通过这里指定静态文件夹资源的访问路径 directory: path.join(__dirname, 'public'), }, compress: true, port: 9000, }, };
大家可以直接使用我的:
// 导入Node里面的模块 const path = require('path') //使用Node.js中的导出语法,向外导出一个webpack的配置对象 module.exports={ devServer: { static: { // 通过这里指定静态文件夹资源的访问路径 directory: path.join(__dirname, 'public'), }, compress: true, port: 8080, }, //development是开发阶段 //production 是生产阶段 //代表 webpack 运行的模式, 可选值有两个 development和production //结论: 开发时候一定要用 devlopment,因为追求的是打包的速度,而不是体积 //反过来,发布上线时候一定要用production 因为上线追求的是体积小,而不是打包速度快 mode:'development', // entry:'指定要处理那个文件为打包的入口' // __dirname 代表当前文件(webpack.config.js)所处的目录也就代表项目中的根目录 // path.join(__dirname,'./public/index1.js') 拼接路径 entry: path.join(__dirname,'./public/index1.js'), // 指定打包的出口就是生成的文件要存放到哪里 // 记得重新生成 npm run dev,并更改最新生成的打包文件index1.html里面的script标签 src路径指定的内容 output:{ // 存放目录 // __dirname 代表当前文件(webpack.config.js)所处的目录也就代表项目中的根目录 // path.join(__dirname,'dist') 拼接路径 path: path.join(__dirname,'dist'), //生成的文件名 filename:'bundle.js' } }
此刻你会发现index.html没有任何js或者css效果,这是因为index.html中script文件引入路径有问题
改为
<script src="/bundle.js"></script>
就好了我们应该的路径是 …/dist/bundle.js 为什么变成了 /bundle.js呢?
这里如果你对script里的路径感觉到迷惑的话可以使用:
如果你碰到了问题,请将路由导航至
/webpack-dev-server
将会为你展示服务文件的位置。例如:http://localhost:9000/webpack-dev-server
。Warning
webpack-dev-server 在编译之后不会写入到任何输出文件。而是将 bundle 文件保留在内存中,然后将它们 serve 到 server 中,就好像它们是挂载在 server 根路径上的真实文件一样。如果你的页面希望在其他不同路径中找到 bundle 文件,则可以通过 dev server 配置中的
devMiddleware.publicPath
选项进行修改。为什么放在虚拟磁盘中?
因为程序员频繁按ctrl+s 的话那么webpack-dev-server,就会进行更新代码打包一次,如果频繁去按
ctrl+s并且文件是放在物理磁盘中,那么就会频繁的读写磁盘,对于磁盘的寿命和性能影响都非常大
④ 补充一种启动devserver的启动方式:
通过 Webpack-CLI 调用 webpack-dev-server[官方推荐]
CLI 配置项列表可以在 这里 查询。
npx webpack serve
安装 html-webpack-plugin
安装命令
cnpm install html-webpack-plugin@5.3.2 -D
配置 html-webpack-plugin
// 导入Node里面的模块
const path = require('path')
//1 导入html-webpack-plugin这个插件,得到插件的构造函数
const HtmlPlugin=require("html-webpack-plugin")
//2. new 构造函数, 创建插件的实例对象[所谓实例对象,是指实际对象的运用]
const htmlPlugin=new HtmlPlugin({
/// 指定要复制那个页面
template: './public/index.html',
//指定复制出来的文件名和存放路径
//文件也是没有实际存在的,放在内存当中使用,和webpack-dev-server的指定打包的出口会默认挂载到服务器根路径下
//编译之后不会写入到任何输出文件
filename:'./index.html'
})
//使用Node.js中的导出语法,向外导出一个webpack的配置对象
module.exports={
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 8080,
},
//development是开发阶段
//production 是生产阶段
//代表 webpack 运行的模式, 可选值有两个 development和production
//结论: 开发时候一定要用 devlopment,因为追求的是打包的速度,而不是体积
//反过来,发布上线时候一定要用production 因为上线追求的是体积小,而不是打包速度快
mode:'development',
// entry:'指定要处理那个文件为打包的入口'
// __dirname 代表当前文件(webpack.config.js)所处的目录也就代表项目中的根目录
// path.join(__dirname,'./public/index1.js') 拼接路径
entry: path.join(__dirname,'./public/index1.js'),
// 指定打包的出口就是生成的文件要存放到哪里
// 记得重新生成 npm run dev,并更改最新生成的打包文件index1.html里面的script标签 src路径指定的内容
output:{
// 存放目录
// __dirname 代表当前文件(webpack.config.js)所处的目录也就代表项目中的根目录
// path.join(__dirname,'dist') 拼接路径
path: path.join(__dirname,'dist'),
//生成的文件名
filename:'bundle.js'
},
//3. 插件的数组,将来webpack在运行时,会加载并调用这些指定的插件[就是创建的对象实例]
plugins:[htmlPlugin]
}
解惑 html-webpack-plugin
- 通过 HTML 插件复制到项目根目录中的 index.html 页面,也被放到了内存中
- HTML 插件在生成的 index.html页面,自动注入了打包的 bundle.js 文件
- 假如有一个需求,我不想自己去配置webpack,但是我还想体验到webpack带来的好处,这个时候就可以使用vue-cli,这个工具会自动帮我们生成一个配置好的webpack项目,但是webpack的各项配置要理解,在vue的学习中后边不需要自己去配
devServer中常用的选项配置
webpack.config.js中配置的
//使用Node.js中的导出语法,向外导出一个webpack的配置对象
module.exports={
mode.... ,
entry.... ,
output... ,
plugins... ,
// devServer中常用的选项配置
devServer: {
static: {
// 通过这里指定静态文件夹资源的访问路径
directory: path.join(__dirname, 'public'),
},
compress: true,
//指定运行的主机地址 127.0.0.1 就是hppt协议中默认的本机地址
port: 80,
//指定运行的主机地址
host:'127.0.0.1',
open:true
}
}
webpack中的loader
在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 js 后名结尾的模块,webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错!
loader 加载器的作用: 协助 webpack 打包处理特定的文件模块。比如:
- css-loader 可以打包处理Icss 相关的文件
- less-loader 可以打包处理less 相关的文件
- babel-loader 可以打包处理 webpack 无法处理的高级JS 语法
目录结构
创建css文件:
css文件代码:
/*去除列表中每一行的小圆点*/
ul li{
list-style-type: none;
}
在index1.js中引入css
// 1. 使用ES6导入语法,导入jQuery
import $ from 'jquery'
//导入样式 (在webpack中,一切皆模块,都可以通过es6导入语法进行导入和使用)
import './css/index.css'
// 2. 定义jquery的入口函数
/**
* 入口函数的解释 :
* 入口函数1:
* $(function(){
*
* });
* 入口函数2:
* $(document).ready(function(){
*
* });
* 意思是:一旦dom结构渲染完毕即可执行内部代码。
*
* 二、和window.onload的区别
* 区别1:jQuery入口函数可以书写多次,window.onload只能书写一次;
* 区别2:执行的时机不同,jQuery的入口,一旦我dom结构渲染完毕即可执行内部代码,不必等到所有外部资源加载完成;window.onload 的是等页面文档、外部的js文件、css文件、图片加载完毕才执行内部代码。
*/
$(function (){
//3. 实现奇偶行变色
// 奇数行为红色
$('li:odd').css("background-color",'red')
$('li:even').css("background-color",'yellow')
//0是偶数 even代表偶数行
//1是奇数 odd代表奇数行
})
这时候运行项目会出现报错:
ERROR in ./public/css/index.css 1:3
Module parse failed: Unexpected token (1:3)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.[您可能需要一个适当的加载器来处理此文件类型,当前没有配置任何加载器来处理该文件。]
配置loader 打包处理css文件
-
运行命令,安装处理css文件的loader
cnpm i style-loader@3.0.0 css-loader@5.2.6 -D
-
在 webpack.config.js 的 module -> rules 组中,添加 loader 规则如下:
//使用Node.js中的导出语法,向外导出一个webpack的配置对象 module.exports={ mode.... , entry.... , output... , plugins... , // devServer中常用的选项配置 devServer:.... , module:{ rules:[ //定义了不同模块对应的loader 成功实现css文件的处理 // test:/\.css$/ 匹配以.css结尾的文件 \是转义的用法 因为 .在正则中是元字符 {test:/\.css$/,use:['style-loader','css-loader']} ] } }
-
了解loader调用的过程
配置loader 打包处理less文件
-
运行命令
cnpm i less-loader@10.0.1 less@4.1.1 -D
-
在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下: index1.js中导入对应的less模块
// 1. 使用ES6导入语法,导入jQuery import $ from 'jquery' //导入样式 (在webpack中,一切皆模块,都可以通过es6导入语法进行导入和使用) import './css/index.css' //不使用对应的loader一样会出现报错提示 import './css/index.less' // 2. 定义jquery的入口函数 /** * 入口函数的解释 : * 入口函数1: * $(function(){ * * }); * 入口函数2: * $(document).ready(function(){ * * }); * 意思是:一旦dom结构渲染完毕即可执行内部代码。 * * 二、和window.onload的区别 * 区别1:jQuery入口函数可以书写多次,window.onload只能书写一次; * 区别2:执行的时机不同,jQuery的入口,一旦我dom结构渲染完毕即可执行内部代码,不必等到所有外部资源加载完成;window.onload 的是等页面文档、外部的js文件、css文件、图片加载完毕才执行内部代码。 */ $(function (){ //3. 实现奇偶行变色 // 奇数行为红色 $('li:odd').css("background-color",'red') $('li:even').css("background-color",'yellow') //0是偶数 even代表偶数行 //1是奇数 odd代表奇数行 })
webpack.config.js
//使用Node.js中的导出语法,向外导出一个webpack的配置对象 module.exports={ mode.... , entry.... , output... , plugins... , // devServer中常用的选项配置 devServer:.... , module:{ rules:[ //定义了不同模块对应的loader 成功实现css文件的处理 // test:/\.css$/ 匹配以.css结尾的文件 \是转义的用法 因为 .在正则中是元字符 {test:/\.css$/,use:['style-loader','css-loader']}, //处理 .less文件的loader {test: /\.less$/,use:['style-loader','css-loader','less-loader']} ] } }
index.less文件
html, body, ul{ margin: 0; padding: 0; li{ line-height: 30px; padding-left: 20px; font-size: 12px; } }
项目结构
loader-回顾base64图片的优缺点
结构:
随便找一张图片转为base64
可以百度搜索base64进行转换
也可以直接通过下方链接网站
https://www.sojson.com/image2base64.html
图片转化为Base64的代码粘贴到下方代码块第二个Img标签的src属性中
由于内容过长我这里就没有粘贴全部
test.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--这种方式需要发起请求才能拿到图片 每展示一个就要发起一次请求-->
<img src="./美女图.png" alt="">
<img src="./美女图.png" alt="">
<img src="./美女图.png" alt="">
<img src="./美女图.png" alt="">
<!--
优点:
把图片转为base64而这种方式,直接顺手就把图片拿下来了,不需要发起请求
算是性能优化的小手段
缺点:
转为base64后体积会增大一点点, 比如原本图片10kb 转为base64他的体积就编程13kb或15kb
那如果是轮播图那种大图片轮播图那种图片,那原本200kb转后就会更大了,所以不建议大图片转为base64
小图片适合转为base64
-->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABkAAAAOECAYAAAD5Tf......."
alt=""/>
</body>
</html>
loader-演示图片loader加载问题
添加图片
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--加载和引用物理磁盘中的main.js-->
<!--<script public="../dist/main.js"></script>-->
<!--
加载和引用内存中的bundle.js
使用了webpack-dev-server插件后
在编译之后不会写入到任何输出文件。
而是将 bundle 文件保留在内存中,然后将它们 serve 到 server 中,
就好像它们是挂载在 server 根路径上的真实文件一样。
如果你的页面希望在其他不同路径中找到 bundle 文件,
则可以通过 dev server 配置中的 [`devMiddleware.publicPath`](https://webpack.docschina.org/configuration/dev-server/#devserverdevmiddleware) 选项进行修改。
为什么放在虚拟磁盘中? 因为程序员频繁按ctrl+s 的话那么webpack-dev-server,就会进行更新代码打包一次,如果频繁去按
ctrl+s并且文件是放在物理磁盘中,那么就会频繁的读写磁盘,对于磁盘的寿命和性能影响都非常大
-->
<script src="/bundle.js"></script>
</head>
<body>
<ul>
<li>这是第1个li</li>
<li>这是第2个li</li>
<li>这是第3个li</li>
<li>这是第4个li</li>
<li>这是第5个li</li>
<li>这是第6个li</li>
<li>这是第7个li</li>
<li>这是第8个li</li>
<li>这是第9个li</li>
</ul>
<!-- 需求: 把src/images/logo.jpg 设置给src 属性-->
<img src="" alt="" class="box">
</body>
</html>
index1.js
// 1. 使用ES6导入语法,导入jQuery
import $ from 'jquery'
//导入样式 (在webpack中,一切皆模块,都可以通过es6导入语法进行导入和使用)
import './css/index.css'
//不使用对应的loader一样会出现报错提示
import './css/index.less'
//1. 导入图片,得到图片文件
// webpack中一切皆模块
import logo from './images/logo.jpg'
//2. 给img标签的src动态赋值
//不配置图片加载的Loader一样会出现问题
$('.box').attr('src',logo)
// 2. 定义jquery的入口函数
/**
* 入口函数的解释 :
* 入口函数1:
* $(function(){
*
* });
* 入口函数2:
* $(document).ready(function(){
*
* });
* 意思是:一旦dom结构渲染完毕即可执行内部代码。
*
* 二、和window.onload的区别
* 区别1:jQuery入口函数可以书写多次,window.onload只能书写一次;
* 区别2:执行的时机不同,jQuery的入口,一旦我dom结构渲染完毕即可执行内部代码,不必等到所有外部资源加载完成;window.onload 的是等页面文档、外部的js文件、css文件、图片加载完毕才执行内部代码。
*/
$(function (){
//3. 实现奇偶行变色
// 奇数行为红色
$('li:odd').css("background-color",'red')
$('li:even').css("background-color",'yellow')
//0是偶数 even代表偶数行
//1是奇数 odd代表奇数行
})
loader-配置加载图片的loader
-
运行命令
cnpm i url-loader@4.1.1 file-loader@6.2.0 -D
-
在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
webpack.config.js中的配置,沾取下方代码添加到webpack.config.js的代码中,不要ctrl+a 然后 ctrl+v把代码全部覆盖掉
module:{ rules:[ //定义了不同模块对应的loader 成功实现css文件的处理 // test:/\.css$/ 匹配以.css结尾的文件 \是转义的用法 因为 .在正则中是元字符 {test:/\.css$/,use:['style-loader','css-loader']}, //处理 .less文件的loader {test: /\.less$/,use:['style-loader','css-loader','less-loader']}, //处理图片文件的loader //如果需要调用的loader只有一个的时候use给一个字符串就可以了 //如果有多个loader,则必须指定数组 {test:/\.jpg|png|gif$/,use:'url-loader'} ] }
index1.js文件 新添加内容
// 1. 使用ES6导入语法,导入jQuery import $ from 'jquery' //1. 导入图片,得到图片文件 // webpack中一切皆模块 import logo from './images/logo.jpg' //可以打印一下导入的模块,是一个base64的图片 //webpack将base64的图片放入了对应的img标签的src中 console.log(logo) //2. 给img标签的src动态赋值 //不配置图片加载的Loader一样会出现问题 $('.box').attr('src',logo)
index.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--加载和引用物理磁盘中的main.js--> <!--<script public="../dist/main.js"></script>--> <!-- 加载和引用内存中的bundle.js 使用了webpack-dev-server插件后 在编译之后不会写入到任何输出文件。 而是将 bundle 文件保留在内存中,然后将它们 serve 到 server 中, 就好像它们是挂载在 server 根路径上的真实文件一样。 如果你的页面希望在其他不同路径中找到 bundle 文件, 则可以通过 dev server 配置中的 [`devMiddleware.publicPath`](https://webpack.docschina.org/configuration/dev-server/#devserverdevmiddleware) 选项进行修改。 为什么放在虚拟磁盘中? 因为程序员频繁按ctrl+s 的话那么webpack-dev-server,就会进行更新代码打包一次,如果频繁去按 ctrl+s并且文件是放在物理磁盘中,那么就会频繁的读写磁盘,对于磁盘的寿命和性能影响都非常大 --> <script src="/bundle.js"></script> </head> <body> <ul> <li>这是第1个li</li> <li>这是第2个li</li> <li>这是第3个li</li> <li>这是第4个li</li> <li>这是第5个li</li> <li>这是第6个li</li> <li>这是第7个li</li> <li>这是第8个li</li> <li>这是第9个li</li> </ul> <!-- 需求: 把src/images/logo.jpg 设置给src 属性--> <img src="" alt="" class="box"> </body> </html>
-
到这里图片就可以正常显示了
loader-url-loader的limit选项
其中**?**之后的是 loader 的参数项:
- limit 用来指定图片的大小,单位是字节 (byte)
- 只有 slimit 大小的图片,才会被转为 base64 格式的图片
webpack.config.js中的配置
如果图片大小超过limit给定的大小,那么图片就会使用 http:xxxxx 链接的形式,而不是base64形式的图片
module:{
rules:[
//处理图片文件的loader
//如果需要调用的loader只有一个的时候use给一个字符串就可以了
//如果有多个loader,则必须指定数组
{test:/\.jpg|png|gif$/,use:'url-loader?limit=22229'}
]
}
loader-使用babel-loader转换处理高级的JS语法
-
运行命令
cnpm i babel-loader@8.2.2 @babel/core@7.14.6 @babel/plugin-proposal-decorators@7.14.5 -D
-
在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下: webpack.config.js文件 新添加内容
module:{ rules:[ //使用babel-loader处理高级的Js语法 //在配置babel-loader的时候,程序员只需要把自己的代码进行转换即可;一定要排除node_modules目录中的JS文件 //因为第三方包中的JS兼容性,不需要程序员关心 {test:/\.js$/,use:'babel-loader',exclude:/node_modules/} ] }
index1.js 新添加内容
webpack只能打包处理一部分高级的JavaScript 语法。
对于那些 webpack 无法处理的高级js语法,需要借助于 babel-loader 进行打包处理。
例如 webpack 无法处理下面的JavaScript 代码://定义装饰器函数 function info(target){ target.info='Person info.' } //定义一个普通的类 @info //装饰器语法 class Person{ } console.log(Person.info)
项目根目录新建babel.config.js文件:
文件内容:
声明babel可用的插件
将来,webpack在调用babel-loader的时候,会先加载plugins插件来使用module.exports={ //声明babel可用的插件 //将来,webpack在调用babel-loader的时候,会先加载plugins插件来使用 plugins:[['@babel/plugin-proposal-decorators',{legacy:true}]] }
-
运行项目,控制台查看效果
发布-配置build命令
假如项目开发完毕要发布上线了,现在我们的页面包括打包好的bundle.js,都在内存里面放着呢,我们要发布上线就要拿到这些文件发给后端,后端去部署去上线,那我们就要把内存里面的文件生成到实际的物理磁盘上,才可以找到这些文件发给后端
-
在 package.json 文件的 scripts 节点下,新增 build 命令如下:
"scripts": { "dev": "webpack serve", //开发环境中 运行dev命令 "build": "webpack --mode production" //项目发布时,运行build命令, 这里的--mode production会覆盖掉webpack.config.js中的mode选项,production比development优先级要高 }
–model 是一个参数项,用来指定 webpack 的运行模式。production 代表生产环境
进行代码压缩和性能优化
注意: 通过–model指定的参数项,会覆盖 webpack.config.js 中的 model选项
-
打包命令+运行
- 打包命令
npm run build
打包好后文件会生成在项目根目录下dist文件夹中 - 运行 在dist路径下 运行 npm run dev 命令,运行打包好后的项目
- 打包命令
发布-优化打包时候图片和js文件的存放路径
-
优化打包时候js文件的存放路径只需要在webpack.config.js中output选项的filename选项值中js文件前面加上js/就可以了
output:{ // 存放目录 // __dirname 代表当前文件(webpack.config.js)所处的目录也就代表项目中的根目录 // path.join(__dirname,'dist') 拼接路径 path: path.join(__dirname,'dist'), //生成的文件名 //优化打包时候js文件的存放路径只需要在webpack.config.js中output选项的filename选项值中js文件前面加上js/就可以了 filename:'js/bundle.js' }
-
优化打包时候图片文件存放路径,在webpack.config.js文件中做一下代码块中的改动
注意!!!
如果项目使用图片大小小于limit参数指定的大小,那么就是使用的base64形式的图片并不会在打包文件dist文件夹的images中出现,
如果项目中只有一张图片并且小于limit指定的大小那么images文件夹是不会生成的
module:{ //处理图片文件的loader //如果需要调用的loader只有一个的时候use给一个字符串就可以了 //如果有多个loader,则必须指定数组 //如果图片大小超过limit给定的大小,那么图片就会使用 http:xxxxx 链接的形式,而不是base64形式的图片 //在配置 url-loader 的时候多个参数之间,使用&符号进行分隔 //outputPath 选项可指定图片文件的输出路径 {test:/\.jpg|png|gif$/,use:'url-loader?limit=480&outputPath=images'}, ]
-
效果图
发布-配置和使用clean-webpack-plugin插件自动删除dist目录
-
运行命令安装插件
cnpm install --save-dev clean-webpack-plugin
-
在 webpack.config.js中添加以下代码
// 配置和使用clean-webpack-plugin插件在编译时自动删除dist目录 // es6语法解构赋值 //注意: 左侧的{} 是解构赋值 const { CleanWebpackPlugin } = require('clean-webpack-plugin'); //在插件数组中更新要使用的插件 plugins:[htmlPlugin,new CleanWebpackPlugin()],
-
如果重新build打包项目没有dist目录没有变化,想办法刷新一下项目文件夹,如果是webstorm右击项目从磁盘重新加载[Reload from disk]即可
SourceMap
开发模式下如何配置SourceMap
-
什么是 Source Map
-
Source Map 就是一个信息文件,里面储存着位置信息。也就是说,Source Map 文件中存储着压缩混淆后的代码,所对应的转换前的位置
有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。
-
-
默认 Source Map 的问题
-
开发环境下默认生成的 Source Map,记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。示意图如下:
-
-
解决默认 Source Map 的问题
-
开发环境下,推荐在 webpack.config.js 中添加如下的配置,即可保证运行时报错的行数与源代码的行数
保持一致:module.exports={ //使用SourceMap解决错的行数与源代码的行数不一致的问题 //在开发调试阶段,建议大家都把devtool的值设置为eval-source-map devtool: 'eval-source-map', }
-
webpack 生产环境下的 Source Map
在生产环境下,如果省略了 devtool 选项[注释掉devtool选项],则最终生成的文件中不包含 Source Map。这能够防止原始代码通
过 Source Map 的形式暴露给别有所图之人。
Source Map的最佳实践
在生产环境下,如果只想定位报错的具体行数,且不想暴露源码。此时可以将 devtool 的值设置为nosources-source-map。实际效果如图所示:
① 开发环境下:
- 建议把 devtool 的值设置为 eval-source-map
- 好处:可以精准定位到具体的错误行
② 生产环境下:
- 建议关闭 Source Map 或将 devtool 的值设置为 nosources-source-map
- 好处:防止源码泄露,提高网站的安全性
拓展- 讲解webpack中@的原理和好处
能够极限优化,模块化导入的路径
此时项目的结构
info1.js文件
// import msg from '../../msg'
import msg from '@/msg.js'
// 建议大家使用 @ 表示 src 源代码目录,从外往里查找,不要使用 ../ 从里往外查找
// @/msg.js
console.log(msg)
msg.js文件
export default {
msg:'hello Vue'
}
index1.js文件 新增内容
//导入 public/js/test/info1.js
import info1 from './js/test/info1.js'
webpack.config.js文件 新增内容
resolve:{
alias:{
//告诉webpack,程序员写的代码中,@符号表示public这一层目录
'@':path.join(__dirname,'./public/')
}
}