记录 node/package manager 的一些细碎

yarn2 yarn2不再支持yarn global add,参考 issue。 顺便一说发现好多人还在用yarn1… volta 使用volta作为node manamger,目前存在无法使用pnpm全局安装的问题,同样可采用pnpm dlx ...的方式来解决 volta uninstall yarn失败,参考 issue1、issue2。 fnm fnm和volta 用下来,个人还是感觉volta更舒适,主要还是在于volta对于node版本的切换无感知,而fnm需要手动切换版本。 volta只需要在项目中volta pin node@x.x.x就可以将版本写入package.json中,随后每次进入不同的目录都会自动切换到对应的node版本。 corepack corepack不能与volta使用,当你使用volta install node后,你的node中并没有 corepack,参考 issue1、issue2 虽然说corepack已经被视为规范,但它处于试验阶段好几年了,且node官方常年不作为…所以我还是选择先相信volta

December 2, 2024 · 1 min · Zink

6.29 思考

入职快两个月了,这段时间基本是被工作推动生活,几乎忘了自己的目标,今天更新 checklist 的时候终于有机会回过头来看了。发现这样的状态还是蛮危险的,安逸于当下的生活,对未来失去了活力。 最近又感到自己知识上的匮乏,twitter 最近的 timeline 发生了一些大事,我能感觉到这些事背后还有更深的冰山,但是我无法探究下去,甚至无法用语言对下面这座冰山进行一个粗略的描述。这使我焦虑,或许我应该调整一下生活模式:把学习新知识作为一个构建生活的方式,而不是用娱乐、工作、消遣来填满我的生活。 人还是不能被普通人叙事打倒,一定得在某些方面追求卓越(不一定是社会面的判断标准),才能让自己感觉到活着。

June 29, 2022 · 1 min · Zink

Event Loop Promise async/await 总结

同步任务 因为 JavaScript 是单线程的,所以同步任务只能在主线程上排队执行,并且只有当前一个任务完成才能执行下一个任务 当 JavaScript 运行时,每个函数的执行都会进入调用栈(Call Stack)中,当前函数执行完毕后将其移出栈,然后执行下一个函数,如果其中有非常耗时的函数执行,那么调用栈就阻塞了,后面的任务只能一直处于等待状态无法执行,且此时 UI 对面任何用户操作都不会响应,看起来就像程序崩溃了一样。 为了解决这个问题,我们有了异步任务。 异步任务 常见的异步: setTimeout() setInterval() Promise.resolve().then() fetch.then() 异步任务在执行之前不会进入调用栈,它进入事件循环队列(Event Loop Queue),当主线程执行完毕后,且异步时机到了,就会将事件循环队列中的任务推入调用栈中执行。 Event Loop Event Loop 的工作非常简单,它只是监控调用栈和回调队列(包含每个事件对应的回调函数,比如 click 的回调函数)。如果调用栈为空,Event Loop 将队列中的第一个任务移除并推送到调用栈。 从 ES6 开始,Event Loop 处理异步也分两种,在Macrotask中处理setTimeout这类的,在Microtask中处理Promise这类的。它会优先处理Microtask中的任务 browser event model Node.js 中的 Event Loop Node.js 中的 Event Loop 分为 6 个阶段,依次是: timers 定时器 这个阶段执行已被setTimeout()和setInterval()调度的回调函数 pending callbacks 待定回调 执行延迟到下一个循环迭代的I/O回调 idle, prepare Node.js 系统内部使用 poll 轮询 检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞(等待) check 检测 setImmediate()回调函数在这里执行 close callback 关闭的回调函数 一些关闭的回调函数,如:sockt.on('close', ...) process.nextTick()的回调会在每个阶段结束之前调用。 ...

March 10, 2022 · 1 min · Zink

React 哲学

最近在看 React 的文档,因为之前有使用 Vue 的经验,所以其中的概念理解起来倒是不算难,不过 React 的文档给我的感觉并不只是教我怎么写 React,怎么使用它的语法,它更多的是在教我如何从组件的角度出发,编写一个健壮的 web app。 以前在写 Vue 组件的时候,通常是使用现有的基础组件库,然后拼装成一个 page component,所有数据都由 page component 管理,通过 props 将数据分发给子组件,但是以前并没有思考过为什么要这样做,只是因为大家都这样写代码,所以我也这样写代码。 而 React 哲学告诉了我们,在面对一份新的设计稿时,应当如何从最基本的层面去思考如何构建这个页面。 第一步:通过 UI 来划分组件 其实在设计领域,也一直在推崇组件化,即设计师在设计 UI 时,也需要将每个功能点按组件划分,并不是一味地堆叠元素。 通过单一功能原则来判断组件的分为 第二步:创建一个静态版本 这一步通俗来说应该就是切图了,通过 mock data 构建一个没有交互能力的静态版本 第三步:确定 UI state 的最小(且完整)表示 确定哪些数据是需要组件自身来更改。 通过可以从以下三步判断: 该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。 该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。 这一步我的理解是,该数据是否可由组件自身的交互操作改变它 你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。 第四步:确定 state 放置的位置 假设现在拥有 parent compoent、child1 component 和 child2 component(后文简称 p、c1、c2),c2 中的数据由 p 通过 props 传递给它,c1 自身维护一份 state,但 c2 中的数据依赖 c1 的 state,那么此时应该将 c1 的 state 提升到 p 中,并通过 props 传递给 c1 ...

March 2, 2022 · 1 min · Zink

什么是继承?

要理解继承,首先需要理解原型链 function Person(name, age, gender){ this.name = name this.age = age this.gender = gender } Person.prototype.hi = function (){ console.log(`Hi, I'm ${this.name}`) } let f = new Person('zoe', 18, 'female') f.__proto__ === Person.prototype // true,ES5写法 Object.getPrototypeOf(f) === Person.prototype // true,ES6写法, __proto__ 是浏览器厂商私建 Person.prototype.__proto__ === Object.prototype // true 首先定义几个基本名词: 实例对象:通过new xxx出来的对象叫做实例对象 构造函数:如上方代码中的Person,一般以大写字母开头命名 - __proto__:ES6 之前,没有明确访问原型的方法,只能通过__proto__来访问,它的作用就是找到实例对象的原型 prototype:原型,是构造函数的一个属性 constructor:构造函数,写过 Java 这类 oop 的同学应该不陌生,这个在 ES5 中不经常接触到,ES6 中的 Class 经常用到, 然后通过上面的代码,我们可以得到这样的公式: 实例对象.__proto__ === 构造函数.prototype 构造函数.prototype.__proto__ === Object.prototype (长继承不适用,这里的继承链是 Person 继承 Object) 其次,Object 是原型链的顶端 Object.prototype.__proto__ === null ok,那么明白了这个,我们就来讨论继承,继承本质上只是用来减少重复代码的一种编程手段,如果我们有多个类,并且都有重复的属性,那么我们可以将重复的属性提取到父类身上,再由父类通过继承给子类。再简化一下:子类构造函数的实例对象也能访问到父类的属性或方法。 function Male(name, age){ this.name = name this.age = age this.gender = 'male' } let m = new Male("m", 24) function Female(name, age){ this.name = name this.age = age this.gender = 'female' } let f = new Female("f", 24) 在上面这个例子中,我们定义了两个构造函数,分别来构造男性和女性,但是 name 和 age 重复了,此时我们可以创建一个父类,来优化掉重复的代码 ...

February 10, 2022 · 2 min · Zink