pnpm
pnpm
pnpm-快速的,节省磁盘空间的包管理工具,是Node包管理工具,同时它也是npm的替代品,但比npm更快。
pnpm的设计初衷是节约磁盘空间并提升安装速度,也是我使用决定从npm转pnpm的原因。
当使用 npm 或 Yarn 时,如果你有100个项目使用了某个依赖(dependency),就会有100份该依赖的副本保存在硬盘上。 而在使用 pnpm 时,依赖会被存储在内容可寻址的存储中,所以:
如果你用到了某依赖项的不同版本,那么只会将有差异的文件添加到仓库。 例如,如果某个包有100个文件,而它的新版本只改变了其中1个文件。那么pnpm update时只会向存储中心额外添加1个新文件,而不会因为仅仅一个文件的改变复制整新版本包的内容。所有文件都会存储在硬盘上的某一位置。 当软件包被被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间。 这允许你跨项目地共享同一版本的依赖。因此,在磁盘上节省了大量空间,这与项目和依赖项的数量成正比,并且安装速度要快得多!
pnpm现状2021年pnpm的下载量约为2020年的3倍,用户量在急剧上升,说明pnpm确确实实有解 ...
前端异常监控平台
背景前端项目发布到生产环境之后,线上问题几乎都需要用户投诉等渠道通知到开发人员,开发人员根据描述还原场景,定位问题再修复之,这样效率极低,影响用户体验和开发工作效率。因此一些前端监控平台就应运而生了,目前比较主流的框架有:
sentry
fundebug
webfunny
ARMS
为什么不用这些成熟的框架呢?首先这些框架都是收费的,费用不低,且存在数据泄漏的风险;其次平台二次开发受限,无法根据自身业务定制功能。所以搭建一套私有化的前端监控平台还是很有价值的,主要是能提高开发者排查问题,在用户投诉前发现问题并解决问题,减少用户投诉率。
整体架构前端监控平台一般有四部分组成:日志采集、日志存储、日志分析、报警
日志采集
日志采集这一步主要是在用户端捕获各种错误信息以及一些环境信息,然后上报给服务端。
首先我们要明确平台需要哪些数据,除了最基本的错误信息之外,还需要项目信息、操作系统、浏览器版本和采样率等基础数据。
明确了数据之后就可以开始编写sdk了,下文将从错误信息、项目信息、操作系统、浏览器版本和采样率来分析如何采集。
错误信息常见的错误类型分为五类:运行时报错、资源加 ...
性能优化之SSR初体验
性能优化之SSR初体验SSR是什么?
Server Side Render简称SSR。具体指html页面内容通过服务端渲染生成,浏览器接收到服务器响应时直接显示对应的内容就可以了。
了解完SSR就必须知道和它相爱相杀的CSR。CSR全称Client Side Render,页面上的内容是js动态渲染出来的(Vue、React等框架),服务端只返回一个html模板,其余渲染在浏览器完成。
SSR也不算是一个新的概念,早期的后端PHP、JAVA就已经支持服务端渲染,美其名曰模板引擎,如phtml、jsp、jade等。最近几年前端工程化的日渐成熟,前后端开始分离,将原本的SSR模式转变成了CSR。同时也带来了一些性能上的缺陷以及SEO问题等等。
SSR优劣势对比上面两张图SSR的优势很明显,在进行到第二阶段下载js文件时页面已经呈现,而CSR需要到第四阶段可交互时才显示页面。这对于首屏性能和**搜索引擎SEO**有着天然的好处。
当然SSR的劣势不小,对于现有的Vue或者React项目迁移成本很大;消耗服务器资源;框架生态支持不太完美。
从个人经验上来说,除非对项目首屏性能或者SEO有 ...
Vue3.0——Provide/Inject的妙用
Vue3.0——Provide/Inject的妙用说起Vue的状态管理工具,应该大部分人都会想到Vuex,毕竟是官方提供的工具,但是都进入Vue3时代了,不会还有人不知道依赖注入吧。为什么会突然提到依赖注入呢?跟状态管理工具有什么关系呢?当然有关系,因为依赖注入在Vue3中可以替代Vuex。我们知道Vue3提供的ref/reactive API具有组件解耦的特性,也就是说我们可以在组件之外创建响应式数据,这么一来跨组件共享数据的需求就在Vue3新框架内部得到了解决。
Provide / Inject
通常,当我们需要从父组件向子组件传递数据时,我们使用 props。如果组件层级比较深,那通过props传递下去会比较麻烦。针对这种情况我们可以使用一对 provide 和 inject。无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这些数据。
Provide / Inject不是什么新的api,在Vue2的时候就已经存在了,只不过在Vue3得到新的应用。这里只做 ...
Vue3.0——reactive和ref原理
Vue3.0——reactive和ref原理Vue3采用了新的Proxy实现数据拦截,但Proxy还是只能代理一层。对于深层的对象需要递归代理,相比2.0在初始化递归,3.0的运行时递归,大大减少了初始化的递归性能消耗。
Proxy首先简单了解下Proxy,方便后面学习reactive和ref原理。
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
基础示例:
12345678910111213141516171819202122232425const handler = { // 属性读取操作的捕捉器 get: function (target, prop) { console.log('getting key: ' + prop); return target[prop]; }, // 属性设置操作的捕捉器 set: function (target, prop, value) { console. ...
css变量那些事
css变量也不是一个新词,但是说起css变量可能很多同学都不太熟悉,因为它的使用场景确实不太多,做过皮肤切换功能的同学估计是了解css变量带来的好处(变量是个好东西)。
浏览器支持 开始之前先了解下css变量的兼容性,避免一顿操作猛如虎,一看兼容泪满面。现在市面上主流的浏览器基本上都支持(IE6这玩意别跟我说主流),全球网站流量的 77% 支持CSS变量,而美国已经接近90%。
声明你的第一个css变量既然是变量,那么可以大胆的猜测它一定有作用域(后面会讲到)。我们先在全局也就是 :root 上定义,也意味着所有的DOM节点都能使用到全局的变量。
123:root { --title-color: #1b1b1b; }
声明变量的语法是 --* ,至于命名规则就比较有意思了,css变量命名除了不能包含 $ ,[ , ^,(,%等字符之外都是可以,甚至中文字也行。
使用你的第一个css变量刚刚我们已经在全局声明了一个--title-color,那么现在我们可以在任意位置去使用到它。
123.card-title { color: ...
computed 实现原理
computed 实现原理
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值
那么计算属性为何可以做到当它的依赖项发生改变时才会进行重新的计算,否则当前数据是被缓存的?
使用123456789101112131415161718192021export default { computed: { // function status() { return this.$store.state.status }, // getter fullName: { // getter get: function() { return this.firstName + ' ' + this.lastName }, // setter set: function(n ...
vue自定义指令的魅力
vue自定义指令的魅力默认的内置指令:v-html、v-if、v-show、v-for等,除此之外vue允许注册自定义指令。
指令格式:v-name:arg.modifier=”value”
v-on:click.stop = 'clickFn'(简写@click.stop="clickFn")
指令定义函数提供了几个钩子函数:
bind-只调用一次,指令第一次绑定到元素时调用
insert
update-当前绑定元素有任意改变时触发
componentUpdated
unbind-只调用一次,指令与元素解绑时调用(dom节点移除时调用,v-if)
滚动条实例产品需求:默认情况下滚动条不展示,滚动起来才出现滚动条注册指令
123456789101112131415Vue.directive('scroll', { bind(el, binding){ // binding = { name, arg, value, modifiers, oldValue } ...
前端与反爬虫
前端与反爬虫
爬虫爬取数据主要是从 dom 节点上获取的,那么我们前端可以在 dom 节点上搞点骚操作来干扰爬虫抓取数据
1.1 字符串穿插在 html 字符间插入无关紧要的元素来达到干扰爬虫的效果
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647/** * 获取随机中文字 */const randomText = () => { let _len = 2 let i = 0 let _str = '' let _base = 20000 let _range = 1000 while (i < _len) { i++ var _lower = parseInt(Math.random() * _range) _str += String.fromCharCode(_base + _lower) } return ...
状态模式
状态模式
状态模式允许一个对象在其内部状态改变的时候改变它的行为,对象看起来似乎修改了它的类
1234const obj = { state: '' action(){}}
对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为
简单实现王者荣耀就可能同时有好几个状态(攻击,移动,回城,死亡)等
1234567891011121314// if-else款const change = state => { if (state == '攻击') { console.log('攻击') } else if (state == '移动') { console.log('移动') } else if (state == '回城') { console.log('回城') } else if (st ...