前端基础功课复习手册

文章目录


前言

整理了我的前端路程,哈哈哈。一系列面试相关或者技术记录的文档

1. 一些面试题

1.1 seo搜索引擎优化

语义化书写html代码
少使用iframe(搜索引擎抓取不到)
为图片加上alt属性
页面尽量不要做flash,视频

1.2 网络相关

1.2.1 同一域名资源浏览器访问,最多6-8个解决方案
  • 域名分区:
    将资源分散到不同的域名下(如使用二级子域名),但是会增加DNS域名解析时长
  • Keep-Alive机制:
    保持TCP连接不立即关闭,可以在一个连接上发送多个请求
  • 通过优化前端性能优化减少请求
    懒加载,cdn等
1.2.2 性能优化
  • 减少htttp请求
  • 服务器缓存(强缓存,协商缓存)
  • 压缩格式化代码(减小请求体积)
  • 把css放在顶部,js放在底部(不让js阻塞ui渲染)
  • 资源外链(利于维护和缓存机制)
  • 利用cdn
    cdn一种虚拟网络,通过全国各地部署边缘服务器,利用中心平台的负载均衡,内容分发和调度。让用户可以访问距离他们最近的CDN节点获取所需内容。降低了网络阻塞,提高了网络速度和缓存命中率
  • 若还考虑seo,使用ssr服务端渲染
1.2.3 图片优化
  • img设置alt,提升用户体验
  • 避免src为空
  • 图片懒加载
  • 减小图片尺寸

1.3 线程和进程,异步编程

一个程序一定会开启一个进程
多个进程之间存储空间独立,线程是进程的基本执行单位,任务运行必须依赖与线程,同进程下的线程共享地址空间
例子:浏览器的一个窗口就是一个进程,浏览器会包含一个主进程
在这里插入图片描述
每个进程下面包含多个线程,其中主要包含GUI渲染线程和Js引擎线程,js是单线程,因为如果是多线程就会有如同时操作dom,锁逻辑之类的。但是js可以通过事件循环机制执行异步编程。
在这里插入图片描述
当Gui渲染线程碰到js线程的时候,会把GUI渲染线程挂起,不然当渲染线程渲染后在处理js就可能导致不一致。这也是为什么js会阻塞html解析的原因,也是为什么要把js代码放到body底部的原因

1.3.1同步任务,异步任务
  • 同步任务:自上向下运行,依赖于上一行执行结果。主线程首先执行同步代码
  • 异步任务:执行时不会等待上一行代码完成,而是将这部分代码放入异步队列,继续执行后续的代码。
1.3.3 宏任务,微任务

异步任务分了宏任务和微任务,微任务先执行,宏任务后执行

  • 宏任务:setTimeOut,setInterval,requestAnimationFrame,addEventLister
  • 微任务:promise回调
1.3.2 执行栈,任务队列,事件循环机制
  • 执行栈:先进后出
    比如多个函数嵌套使用a {b {c {,那么栈中顺序a在栈底,c在栈顶,当c执行完,弹出c。最后a执行完弹出a
  • 任务队列(消息队列):先进先出
    最先添加最先执行,任务队列就是用来存放异步方法的,分为了微任务队列和宏任务队列。
  • 事件循环机制(Event Loop):
    当主程序的执行栈(同步任务)执行完清空后。先去查询主程序执行(一个宏任务的调用)产生的微任务,执行微任务队列内的所有任务。执行后再去查询最先添加到宏任务队列里面的任务,将宏任务添加到执行栈中执行,执行完毕后立即去执行产生的微任务队列,微任务队列清空后再执行下一个宏任务。如此循环直到两个任务队列清空。

1.4 输入url到渲染界面过程

  • 浏览器接受到url后,开启一个进程
  • 提取url中协议,地址域名等,浏览器向dns服务器发送请求,dns进行解析。找到对应服务器ip地址
  • 浏览器与服务器创建tcp三次握手协议
  • 浏览器发送http请求,包含请求头等
  • 服务器接受并返回,包括响应数据状态码等
  • 浏览器分析状态码等,如果成功开始html解析(执行下述2.1流程)
  • 链接结束,断开tcp链接

1.5 回收机制垃圾

垃圾回收机制是js管理内存的一个过程,当一个变量赋值给一个对象的时候就会被标记引用,当赋值为null或者在作用域通过其他方式删除后,之前的引用计数就会被删除,当引用计数为的时候就会被回收。
常见导致内存泄漏的类型:

  • 全局对象不会被回收(var定义的变量
  • 闭包导致的(变量引用不会被回收

1.6 单页面spa与多页面mpa区别

  • 单页面是一个html,页面的跳转实际上是局部资源的刷新,不是整个界面的刷新。因为由js动态生成,不利于seo搜索殷勤优化
  • 多页面是多个独立的页面,每个页面需要加载完整的html,css,js资源。页面跳转的时候都会重新加载,会导致白屏现象

1.7 首页白屏优化

  • 按需加载,不要把加载的模块全部放到main.js
  • 压缩图片来减小图像文件的大小
  • 减少接口请求,压缩分割代码
  • 使用cdn引入第三方插件
  • 添加骨架屏和loading
    在这里插入图片描述

1.8 大文件上传,上万条数据

  • 大数据操作使用web Worker
  • 大文件上传:使用切片方式.slice
import axios from 'axios';
methods: {
  async uploadFile(file, uploadUrl, chunkSize = 1024 * 1024) {
    const totalChunks = Math.ceil(file.size / chunkSize);
    let uploadedChunks = 0;
 
    // 创建分块上传的promise数组
    const promises = [];
 
    while (uploadedChunks < totalChunks) {
      const chunk = file.slice(
        uploadedChunks * chunkSize,
        Math.min(file.size, (uploadedChunks + 1) * chunkSize)
      );
 
      const formData = new FormData();
      formData.append('file', chunk);
      formData.append('chunkIndex', uploadedChunks);
      formData.append('totalChunks', totalChunks);
 
      // 将每个分块的上传操作加入到promises数组中
      promises.push(
        axios.post(uploadUrl, formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        })
      );
 
      uploadedChunks++;
    }
 
    try {
      // 并行上传所有分块
      await Promise.all(promises);
      console.log('所有分块上传成功');
    } catch (error) {
      console.error('上传失败', error);
    }
  }
}

1.9 图片懒加载(进入可视区域时再加载)

等到浏览器视图到图片区域的时候在设置src,而不是一开始设置页面加载的时候就导入所有图片。
大多数的原理是:当图片到浏览器窗口的距离,小于浏览器的高度 window.innerHeight就证明图片到可视区域了。

  • 浏览器本身支持图片懒加载
<img src='xx.jpg' loading="lazy"/>
  • 插件:vue-lazyload
  • element的el-image:自带了懒加载属性lazy在这里插入图片描述

1.10 前端安全相关

前端大多数情况能做的是数据传输加密,登录相关就是token鉴权:

//base64加密
const Base64 = require('js-base64').Base64
//rsa加密
import JsEncrypt from 'jsencrypt/bin/jsencrypt'
//md5加密
import md5 from 'js-md5'
Vue.prototype.$base64 = Base64
Vue.prototype.$jsEncrypt = JsEncrypt
Vue.prototype.$md5 = md5

1.11 浏览器兼容问题

因为浏览器内核不一样,会导致相同的一段代码在不同浏览器中呈现不同的页面效果。一般在样式层面和js渲染层面。
js相关:

  • babel插件处理es6转es5
  • 取消冒泡,默认等方法
    // 取消冒泡
    if (e.stopPropagation) { 
    	e.stopPropagation()
    } else {
    	e.cancelBubble = true
    }
    

css相关:

  • 引入重置默认样式插件:ormalize.css
  • 引入添加默认前缀插件:postcss

ie浏览器的一些兼容问题:

  • IE下event对象有x, y属性但没有pageX, pageY属性,而Firefox有pageX, pageY属性但没有x, y属性
  • IE9以下版本不支持opacity属性,这需要在编写CSS时考虑到不同浏览器的支持情况‌
  • 在访问frame对象时,IE和Firefox有不同的访问方式。例如,IE可以使用window.frameId或window.frameName来访问frame对象,而Firefox只能使用window.frameName。同时,两者都可以使用window.document.getElementById(“frameId”)

1.12 高阶函数,函数的柯里化

1.12.1 高阶函数

如果一个函数满足下面2个情况之一,那么该函数就是高阶函数

  • 若函数a,接受的参数是一个函数
  • 若函数a,调用的返回值是一个函数

常见的高阶函数:

  • promise
  • settimeout
  • arr.map
1.12.2 高阶函数函数的柯里化

通过函数调用继续返回函数的方式,实现多次接受参数最后统一处理的函数编码形式

function sum(a){
	return (b)=>{
		return (c)=>{
			return a+b+c
		}
	}
}
sum(1)(2)(3)

2.HTML

2.1 浏览器加载页面的顺序

  1. 获取html,解析成dom树
  2. 解析css,生成cssom树。来源包含:浏览器样式,通过link或@import引入外部CSS,style标签内联样式
  3. 解析js(defer和async可以改变执行时间,defer是文档加载解析完后执行,async是文件加载后立即执行)
  4. 结合dom树和cssom树生成布局树
  5. 布局和绘制(重排,重绘),布局过程涉及到分层

2.2 html5常见新特性

2.3 画布,水印

/**
 * 设置水印
 * @param width 画布宽度
 * @param height 画布高度
 * @param fillStyle 文字颜色
 * @param font 字体样式
 * @param insertDom 插入dom
 * @param ZIndex 层级
 * @param className 添加节点的class
 * @param args 显示文本(多行)
 */
function set(
  {
    fillStyle = 'rgba(0, 0, 0, 0.1)',
    font = 'normal 14px Microsoft YaHei',
    insertDom = document.body,
    ZIndex = 9996,
    className = 'watermark',
    rotate = 15
  } = {}, ...args
) {
  const canvas = document.createElement('canvas')
  let lensArr = [...args].map(item => (item.length))
  let sortArr = lensArr.sort((a, b) => (b - a))
  let max = sortArr[0]
  canvas.width = max * 14 + 164
  canvas.height = rotate === 0 ? 126 : max * 14 * Math.sin(rotate * Math.PI / 180) + 112
  canvas.style.display = 'none'
  const context = canvas.getContext('2d')
  // 控制文字的旋转角度和上下位置
  context.rotate(-rotate * Math.PI / 180)
  // context.translate(0, 0)
  // 文字颜色
  context.fillStyle = fillStyle
  // 文字样式
  context.font = font
  args.forEach((text, index) => {
    context.fillText(text, 0, index === 0 ? (canvas.height - 12) : (canvas.height + 40 * index), canvas.width - 100)
  })
  // 新建一个用于填充canvas水印的div标签,考虑到z-index对个别内容影响,故而不用body
  const waterMark = document.createElement('div')
  const styleStr = `left: 0px; top: 0px; width: 100%; height: 100%; position: absolute; z-index: ${ZIndex}; pointer-events: none; background-image: url(${canvas.toDataURL('image/png')}); background-repeat: repeat; mix-blend-mode: multiply;`
  waterMark.setAttribute('style', styleStr)
  waterMark.classList.add(`${className}`)
  insertDom.appendChild(waterMark)
}

/**
 * 关闭页面的水印,即要移除水印标签
 */
function close(insertDom = document.body, className = 'watermark') {
  const waterMark = document.querySelector(`.${className}`)
  // deleteFlag = true
  insertDom.removeChild(waterMark)
}

const watermark = {
  set,
  close
}
export default watermark

2.4 拖拽

元素可拖拽:draggable="true"
开始拖拽事件:ondragstart=drag(event)
设置被拖数据的数据类型和值:dataTransfer.setData("type",data)

接收拖拽元素:ondragover="allowDrop(event)",方法中设置:event.preventDefault()
放置元素后:ondrop="drop(event)"

<body>

//接收拖拽的dom`在这里插入代码片`
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
//可以拖动的dom
<img id="drag1" src="/images/logo.png" draggable="true" ondragstart="drag(event)" width="336" height="69">

<script>
	//开始拖拽
 	function drag(event){
 		event.dataTransfer.setData("Text",event.targrt.id)
 	};
 	//允许接收拖拽元素
 	function allowDrop(event){
 		event.preventDefault()
 	};
 	//拖拽后
 	function drop(event){
	 	event.preventDefault();
	    var data=event.dataTransfer.getData("Text");
	    event.target.appendChild(document.getElementById(data));
 	}
</script>

</body>

2.5 地理位置

必须客户同意。

var x=document.getElementById("demo");
function getLocation(){
    if (navigator.geolocation){
        navigator.geolocation.getCurrentPosition(showPosition);
    }else{
        x.innerHTML="该浏览器不支持获取地理位置。";
    }
}
 
function showPosition(position){
    x.innerHTML="纬度: " + position.coords.latitude + 
    "<br>经度: " + position.coords.longitude;    
}
  1. 音频,视频,插件
    浏览器将使用第一个 可识别的格式:
<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
  <source src="movie.ogg" type="video/ogg">
  您的浏览器不支持Video标签。
</video>

<audio controls>
  <source src="horse.ogg" type="audio/ogg">
  <source src="horse.mp3" type="audio/mpeg">
  您的浏览器不支持 audio 元素。
</audio>

//<object> 元素定义了在 HTML 文档中嵌入的对象。
<object width="400" height="50" data="bookmark.swf"></object>
<object width="100%" height="500px" data="snippet.html"></object>
<object data="audi.jpeg"></object>

//<embed> 元素表示一个 HTML Embed 对象 。
<embed width="400" height="50" src="bookmark.swf">
<embed width="100%" height="500px" src="snippet.html">

3.CSS复习+Scss

3.1 link和import区别

link:属于html标签,在界面加载时会同步加载
import:属于css语法,界面加载后在加载。会导致样式闪烁

3.2 动画 ( @keyframes )

//设置动画名
div{ 
animation: myfirst 5s;
-moz-animation: myfirst 5s;	/* Firefox */
-webkit-animation: myfirst 5s;	/* Safari 和 Chrome */
-o-animation: myfirst 5s;	/* Opera */
}

//设置动画效果
@keyframes myfirst{//可用半分比
from {background: red;}
to {background: yellow;}
}

@-moz-keyframes myfirst /* Firefox */{
from {background: red;}
to {background: yellow;}
}

@-webkit-keyframes myfirst /* Safari 和 Chrome */{
from {background: red;}
to {background: yellow;}
}

@-o-keyframes myfirst /* Opera */{
from {background: red;}
to {background: yellow;}
}

在这里插入图片描述

3.3 scss

scss常见语法

4.js 复习

4.1 类型判断,转换

4.1.1 typeof

在这里插入图片描述

4.1.2 instanceof

在这里插入图片描述

4.1.3 Object.prototype.toString.call

在这里插入图片描述

4.1.4 转换成布尔Boolean

在这里插入图片描述

4.1.5 转换成数值Number

在这里插入图片描述
在这里插入图片描述

4.1.6 转换成字符串String

在这里插入图片描述

4.1.7 判断是不是数组,对象和类数组转换成数组

在这里插入图片描述

4.2 数字的相关方法

value.parseInt
valu.pareFloat
Math.PI
Math.ceil
Math.floor
Math.round
Math.random

  • i++,++i计算:

变量后写++:计算后,变量本身在+
变量前写++:变量本身先加1,在计算

4.3 字符串转换比大小

字符串和字符串比较,会转换成编码比较

"23"<"3" // true
"23"<3	// false

运算符优先级:
1.括号()
2.一元运算符号 ++,–,!
3.乘除取余*,/,%
4.加减法 +,-
5.移位 << >>
6.关系 > < >= <=
7.相等 == !=
8.且 &&
9.或 ||
10.条件运算符?
11.赋值+=,=等

4.4 false,null,undifined与0的关系

console.log(false == 0); // true
console.log('' == 0); // true
console.log(0==undefined); // false
console.log(0== null); // false
console.log(null == undefined); // true
console.log(null === undefined); // false

4.5 数组常见方法,去重,解构

concat
pop
push
shift
unshift

reduce
sort
map
filter
foreach
some
every

  • 数组去重
Array.from(new Set([1,2,3,4,3,4,5,6]))
  • 数组最大最小值
Math.max(...[-10,-1,0,1,2,'100'])
Math.min(...['-10',-1,0,1,2,100])

在这里插入图片描述

  • 数组解构
    es6新增flat方法
    在这里插入图片描述

4.6 堆和栈, 深拷贝浅拷贝

栈:操作系统自行分布,先进先出
基础数据类型,存放在栈内存中,占据固定大小的空间。内存地址大小的固定的
堆:程序手动分布,先进后出
引用数据类型的指针存在栈中,对象存在堆中

深拷贝:
赋值一份对象值存储到堆内存内,不是只赋值指针

4.7 作用域,this,闭包

作用域分为:全局作用域window,函数作用域,块级作用域(es6新增)

  • 作用域链:保证对执行环境有权访问的所有变量和函数的有序访问
  • 全局执行环境是window对象,每个函数都有自己的执行环境
  • 内部环境可以通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境的任何变量和函数
  • 对象不构成单独的作用域

闭包:一个函数内部创建另外一个函数(内部函数使用外部函数活动对象,所以外部函数执行完后,作用域链被销毁,但是活动对象还在)

function out(a){
	var b = 1
	return function(c, d){
		var e = a+b+c+d
		console.log(e)
		return {
			b,
			e
		}
	}
}
out(1)(1,1)
// 定义一个out函数,会创建它的执行环境。
// 调用函数后会创建它的活动对象,活动对象包含arguments,a为1,b为1
// 函数执行中,需要作用域链查找变量,此时作用域链第一位是out的活动对象,第二位是全局执行环境的活动对象

// 匿名函数返回后,会创建匿名函数的执行环境
// 调用函数后会创建它的活动对象,活动对象包含arguments,c为1,d为1,e为4
// 此时作用域链第一位是匿名函数的活动对象,第二位是out函数的活动对象,第三位是全局执行环境的活动对象

// 当out执行后,它的作用域链被销毁,但是它的活动对象没被销毁,因为匿名函数的作用域链任然在引用out的活动对象

this指向问题:this对象是在运行时基于函数执行环境定的

  • 在全局函数中,this指向window
  • 当函数作为对象方法被调用时,指向该对象
  • 匿名函数执行环境具有全局性,this指向window
  • new构造函数的this指向实例对象
  • setTimeout普通函数写法指向window
  • 箭头函数()=>指向定义时上层作用域中的this

4.8 面向对象相关

4.8.1 函数定义方式
1.函数声明式(会有函数提升)
function name(){}
2.函数表达式(匿名函数赋值给变量)
const name = function(){} 
4.8.2 函数的四个内置属性,call,apply,bind

prototype,this,arguments,length
在特定的作用域下调用函数

var color = "bule"
function func(){
	console.log(this.color)
}
var obj = {
	color:"red"
}
// apply :第二个参数是参数数组
func.apply(obj,[parm1,parm2])
// call:参数要逐个列出
func.call(obj,parm1,,parm2)
// bind:创建函数实例
const colorFun = func.bind(obj)
color()
4.8.3 对象定义的方式
1.对象构造函数法
const person = new Object()
person.name = '1'
2.对象字面量法
const person = {
	name:"1"
}
4.8.4 对象的数据属性,访问器属性。object.defineProperty
数据属性:
value:值
writable:能否修改属性值
enumerable:能否使用for in
configurable:能否使用delete删除属性

访问器属性:(必须通过object.defineProperty)
get:获取值触发
set:设置值
enumerable:能否使用for in
configurable:能否使用delete删除属性

设置属性

object.defineProperty(obj,'name',{
	value:'123'
	writable:false
})
object.defineProperties(obj,{
	name:{
		value:'123'
		writable:false
	},
	color:{
		get:function(){
			return 'red'
		},
		set:function(value){
			if(value=='bule'){
				return 'yellow'
			}
		}
	}
})
4.8.5 toString,valueOf方法
  • toString方法将对象转换为字符串并返回字符串
var obj = {
	a:1
}
console.log(obj.toString())  // [object Object]
console.log(['1',''].toString()) // 1,

在这里插入图片描述

  • valueOf:返回对象的原始值
var obj = {
	a:1,
	valueOf:function(){
		return this.a + 1
	}
}
console.log(obj.valueOf())  // 2
4.8.6 New关键字
const person1 = new Person()

1.创建一个空对象
const person1 = {}
2.构造函数的作用域赋值给新对象,this指向新对象
Person.apply(person1,arguments)
2.执行构造函数代码(属性和方法加到this指向的对象内)
person1.属性=value
3.返回新对象
return person1

4.8.7 原型模式
// 构造函数
const person = function(){}
// 构造函数有个prototype属性,prototype指向原型对象,这句话是给原型对象内新增了值为123的name。原型对象内有一个constructor属性指向构造函数
person.prototype.name="123" 
// 创建一个实例,实例中有一个_proto_指向原型对象
const person1 = new person() 
// 实例中找不到name会去原型对象上找
console.log(person1)
console.log(person1.name)

在这里插入图片描述

4.8.8 原型链

让一个构造函数的原型等于另外一个构造函数的实例

  • 原型链的原理依赖于对象的_proto_隐式属性
  • 实例对象的_proto_指向原型对象=构造函数的prototype
  • 原型对象的_proto_指向Object原型对象=Object.prototype
  • Object对象的_proto_等于null,是终点

4.9 事件冒泡,事件捕获

事件冒泡:事件由最开始具体的元素接受想上传播。直到根节点
阻止冒泡:e.stopPropagation()
事件捕获:不大具体的节点应该更早接收到事件,具体的节点最后收到事件
DOM事件流(event flow )存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段

// 第三个参数默认false,冒泡阶段执行,true为捕获阶段执行
event.addEventListener(事件类型,回调函数,true||false)

4.10 防抖,节流

防抖:一定时间内,触发多次函数,等待结束时间执行一次
一般用于输入框搜索,实时获取数据

var obj1 = {
 	id:null, 
 	method1:function(){
 		console.log('666')
	},
	click1:function(){
		clearTimeout(this.id);
		var that=this;
		this.id=setTimeout(function(){
			that.method1()
		},1000)
	}
} 
window.onresize = function(){obj1.click1()}
function debounce(fun,time){
	let timeId = null;
	return function(){
		if(timeId){
			clearTimeout(timeId);
		}
		var that = this;
		timeId = setTimeout(function(){
			timeId = null
			fun.apply(that,arguments);
		}, time)
	}
}
window.addEventListener('resize',
	debounce(function(){
		console.log(window.innerWidth)
	},1000)
)

节流:一定时间内,无论函数触发多少次,都只在开始触发一次
一般终于窗口缩放触发函数

function throttle(fn, time) {
	let timeId = null;//声明一个定时器
	return function () {
		var width1 = this.innerWidth;
		if (!timeId) {
			var that = this;
			timeId = setTimeout(function () {
				fn.call(that,width1);
				timeId = null;
			}, time)
		}
	}
}
window.addEventListener('resize',
	throttle(function(width){
		console.log('输出第一次调整时候的窗口宽度',width)
	},5000)
)

在这里插入图片描述

5.Es6

es6常见语法记录

6.vue2

Vue2的常见 / 高级用法

7.vue3和vue2区别

vue3和vue2区别

8.Node,npm,pnpm

node.js常见语法

8.1 npm和pnpm区别

  • 包存放方式,空间占用
    npm:通过在每个项目node_mudule下存放依赖,就算多个项目有相同依赖也是安装到项目的node_mudule内,所以空间占用大
    pnpm:存放在全局的存储库,所以空间占用小
  • 包获取方式
    npm:在当前项目的node_mudule中查找
    pnpm:通过符号链接查找存储库

推荐别的大佬写的博客

8.2 npm和pnpm的workspace

  • 什么是工作空间:
    对单一存储库(也称为多包存储库、多项目存储库或单体存储库)的支持, 可以创建一个 workspace 以将多个项目合并到一个仓库中。
    本质上就是在当前工作目录中可以通过npm/pnpm install将对应文件夹与当前工作目录的node_modules文件夹建立符号链接。
8.2.1 npm的工作空间

npm官网的workspaces
以truelore-public为例,truelore-public内部封装了一系列的功能在这里插入图片描述

  1. 把truelore-public添加到业务系统中的packages文件夹中
  2. 将package.json中添加
{
	  "name": "my-workspaces-project",
	  "workspaces": ["packages/truelore-public"]
	}
  1. 执行安装指令吧
npm install
  1. 使用对应功能
import { ZlDialog } from 'truelore-public'
8.2.2pnpm的工作空间

pnpm官网的workspaces

  1. 根目录下添加添加pnpm-workspace.yaml
    	packages:
    	  # 各个业务代码
    	  - 'packages/*'
    	  # subtree/组件库
    	  - 'libs/*'
    
  2. 将目录中添加相关的文件
    在这里插入图片描述
  3. 在package.json文件中配置libs文件的组件依赖
    在这里插入图片描述
            "foo": "workspace:*",
            "bar": "workspace:~",
            "qar": "workspace:^",
            "zoo": "workspace:^1.5.0"
     会被编译成
     		"foo": "1.5.0",
            "bar": "~1.5.0",
            "qar": "^1.5.0",
            "zoo": "^1.5.0"
    
  4. 执行安装指令
    pnpm i
    
  5. 添加相关业务系统的运行和打包指令
    在这里插入图片描述

9.vue2项目从0到1记录配置

vue2项目从0到1记录

10.webpack,vite

10.1 webpack

前端webpack常见语法记录

10.2 vite

10.3 webpack和vite区别:

  1. webpack是用node.js写的,vite是使用go写的
  2. webpack在构建大型项目时,需要将所有模块打包,这导致初次加载速度较慢。相比之下,vite利用浏览器对ES Module的原生支持(需要部署才能正常使用,本地是通过devServe),只打包和缓存实际改动的模块,从而极大提高了打包效率
  3. 热更新原理上,webapack整个模块链重新打包和替换,但是vite只会针对改动的模块进行更新
  4. webpack的插件,loader相关的生态体系比vite的健全

11.React

React16新手教程记录

12.uniApp,小程序,Electron

uni-app开发微信小程序的简要流程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值