Skip to content
On This Page

202304

金三银四,四月你还好吗!是否虚度了阳春三月,没关系,往前看,人间四月等着你去努力

TIP

人间四月芳菲尽,山寺桃花始盛开

0401

-接下来每天积累五条面试相关经验

在前端面试中,可能会问到以下 React 相关的面试题:

介绍 React 生命周期。

React 中的组件通信方式有哪些?

什么是虚拟 DOM?如何实现虚拟 DOM?

React 中的状态管理方式有哪些?

如何优化 React 的性能?

React 中的 key 属性有什么作用?

什么是高阶组件?如何创建高阶组件?

React 中的 ref 属性有什么作用?(from gpt)

在 React 中,ref 是用于获取组件或 DOM 元素引用的属性。通过 ref,我们可以在 React 组件渲染完成之后,访问组件或 DOM 元素的属性和方法,从而实现一些 DOM 操作或组件交互。 回调函数 ref 不仅可以用来获取 DOM 元素的引用,还可以用来获取组件的实例引用。当使用回调函数 ref 来获取组件实例时,该回调函数的参数就是组件的实例引用。例如:

js
import React, { Component } from "react";

class MyComponent extends Component {
  doSomething() {
    // do something
    console.log("child comp");
  }

  render() {
    return (
      <div>
        <button
          onClick={() => {
            this.props.onClick(this);
          }}
        >
          Click me
        </button>
      </div>
    );
  }
}

class App extends Component {
  handleClick = (component) => {
    component.doSomething();
  };

  render() {
    return (
      <div>
        <MyComponent onClick={this.handleClick} />
      </div>
    );
  }
}

React Hooks 是什么?有哪些常用的 Hooks?

什么是 Context?如何使用 Context?

介绍 React 中的路由。

React 中的事件处理方式有哪些?

如何使用 Redux 进行状态管理?

React 和 Vue 的区别有哪些?

  • JIT 编译器:在 Tailwind CSS v2.1.0 及以后的版本中,Tailwind CSS 引入了一个 JIT(Just-In-Time)编译器,它的作用是动态地生成 CSS 样式类,这样可以大大减少 CSS 文件的大小。在运行时,JIT 编译器会根据用户的实际使用情况动态生成 CSS 样式类,并将其添加到最终的 CSS 文件中。

  • 前端框架的 JIT 和 AOT 编译方案

现代前端框架都需要“编译”这一步骤,用于:

1.将框架中描述的 UI 转换为宿主环境可识别的代码

2.代码转化,比如将 ts 编译为 js、实现 polyfill 等

3.执行一些编译时优化

4.代码打包、压缩、混淆

编译可以选择放在两个时机执行:

代码构建时,被称为 AOT(Ahead Of Time,提前编译或预编译),宿主环境获得的是编译后的代码

代码在宿主环境执行时,被称为 JIT(Just In Time,即时编译),代码在宿主环境编译并执行

如何通过编译器的优化原理,如何提高 JavaScript 的执行效率?(from gpt)

编译器的优化原理主要是基于静态分析和运行时优化两个方面来实现的,可以通过以下方式来提高 JavaScript 的执行效率:

  • 减少变量的使用:在 JavaScript 中,变量的使用会导致内存分配和垃圾回收等操作,从而影响代码的执行效率。因此,在编写 JavaScript 代码时,应尽量减少变量的使用。

  • 避免频繁创建对象和数组:在 JavaScript 中,创建对象和数组会导致内存分配和垃圾回收等操作,从而影响代码的执行效率。因此,在编写 JavaScript 代码时,应尽量避免频繁创建对象和数组。

  • 使用函数节流和函数防抖:在处理一些频繁触发的事件时,可以使用函数节流和函数防抖来优化代码的执行效率。函数节流可以控制函数的执行频率,从而避免频繁的操作,而函数防抖可以在一定的延迟时间之后执行函数,从而避免重复执行。

  • 使用 Web Worker:Web Worker 可以在独立的线程中执行 JavaScript 代码,从而避免阻塞主线程,提高代码的执行效率。

  • 使用编译器的优化原理:编译器的优化原理可以帮助我们优化 JavaScript 代码的执行效率,例如使用 webpack、rollup 等构建工具来进行代码压缩和打包,使用 Babel 等工具进行语法转换和优化等操作,从而减少 JavaScript 代码的体积和提高代码的执行效率。

  • 使用代码优化工具:使用一些代码优化工具,例如 Google 的 Closure Compiler、UglifyJS 等,可以帮助我们对 JavaScript 代码进行分析和优化,从而提高代码的执行效率。

总之,在提高 JavaScript 的执行效率时,需要结合编译器的优化原理、代码优化工具和代码编写习惯等多个方面进行综合优化。

JavaScript 是如何执行的?(from gpt)

JavaScript 的执行过程可以分为两个阶段:编译阶段和执行阶段。

编译阶段:在编译阶段,JavaScript 引擎会对代码进行词法分析和语法分析,生成抽象语法树(AST),并且对代码进行预编译,例如变量提升、函数声明提升等操作。在这个阶段,JavaScript 引擎会检查代码是否符合语法规范,并生成执行上下文(Execution Context)。

执行阶段:在执行阶段,JavaScript 引擎会按照编译阶段生成的执行上下文执行代码。执行上下文包含了变量、函数、作用域链等信息,JavaScript 引擎根据作用域链来查找变量和函数,并且在执行过程中进行变量赋值、函数调用等操作。在执行过程中,JavaScript 引擎会将代码分为同步任务和异步任务,同步任务会按照顺序执行,而异步任务会先被放到任务队列中,等待下一个事件循环执行。

JavaScript 引擎执行代码时,还会进行垃圾回收和优化等操作。垃圾回收是指当变量或对象不再被引用时,会被自动清除内存空间,从而避免内存泄漏。优化是指 JavaScript 引擎会根据代码的执行情况进行优化,例如 JIT 编译、预解析等操作,从而提高代码的执行效率。

总之,JavaScript 的执行过程是一个编译和执行的过程,通过编译阶段和执行阶段的协同工作,JavaScript 能够完成对代码的解析和执行。

说下 TS 中的泛型(from gpt)

在 TypeScript 中,泛型允许我们在定义函数、类或接口时不预先指定类型,而是在使用时再动态指定类型,以增加代码的灵活性和复用性。(定义时不指定具体类型)

泛型的基本语法是使用尖括号<T>(T 可以替换为任意标识符),将类型参数声明在函数或类名之后

ts
class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
  return x + y;
};

0402

  • modern.js 中的 NoSSR
ts
import { useEffect, useState } from "react";

export function NoSSR(props: { children: React.ReactNode }) {
  const { children } = props;
  const [isMounted, setIsMounted] = useState(false);

  useEffect(() => {
    setIsMounted(true);
  }, []);

  if (!isMounted) {
    return null;
  } else {
    return <div>{children}</div>;
  }
}

每日一题:面试官问,说下 react fiber 原理

React Fiber 是 React v16 中引入的新的协调引擎,它的目标是提高 React 的渲染性能和用户体验。

传统的 React 渲染方式是基于递归调用的,这种方式存在一些问题,比如在渲染大量组件时会造成主线程阻塞,影响用户体验。React Fiber 的出现解决了这个问题,它使用了一种新的调度算法,将渲染工作分解为多个阶段,每个阶段可以中断和恢复,从而实现了优先级控制和异步渲染,提高了 React 的渲染性能和用户体验。

React Fiber 的实现原理如下:

  • 构建 Fiber 树:在渲染过程中,React 会创建一颗 Fiber 树,表示所有需要更新的组件以及它们的关系。与传统的虚拟 DOM 不同的是,Fiber 树不仅包含组件的结构,还包含组件的状态、生命周期等信息。

  • 调度更新:当组件状态发生变化时,React 会根据优先级调度更新,将更新任务分解成多个阶段,每个阶段对应一个优先级。React 会根据优先级和剩余时间来决定当前阶段能否执行,从而实现优先级控制和异步渲染。

  • 执行更新:当当前阶段可以执行时,React 会遍历 Fiber 树,执行对应阶段的更新任务。React Fiber 引入了一种新的数据结构叫做 FiberNode,用来描述每个需要更新的组件,包含组件的类型、props、state 等信息。遍历 Fiber 树时,React Fiber 会根据 FiberNode 之间的关系执行更新任务,并将更新结果保存在 FiberNode 中。

  • 提交更新:当所有阶段的更新任务都执行完毕时,React Fiber 会将更新结果一次性提交到浏览器中,实现视图的更新。React Fiber 还引入了另一种新的数据结构叫做 SideEffect,用来保存更新过程中产生的副作用,比如需要插入、删除或更新 DOM 元素。在提交更新时,React Fiber 会根据 SideEffect 进行批量操作,减少浏览器的重绘和回流,提高性能。

总之,React Fiber 的实现原理主要是基于优先级调度、阶段分解、中断恢复和批量更新等技术,通过这些技术实现了高效的异步渲染和优先级控制。

0403

  • width:fit-content 使用场景fit-content width: fit-content(fit-content min(max-content, max(min-content, length-percentage))),它可以根据元素的内容自动计算宽度,实现自适应宽度的效果。与 width: auto 相比,width: fit-content 可以使元素的宽度不会超出其包含块的宽度,而 width: auto 则可能会导致元素宽度超出包含块的宽度。

width: max-content 用于指定元素的宽度为其包含内容的最大宽度。

具体来说,当应用该属性时,元素的宽度将会自动调整为其内部内容的最大宽度。例如,如果一个元素包含了一个很长的文本行,那么该元素的宽度将会自动调整为文本行的最大宽度。

这个属性在实现自适应布局、表格自适应等方面非常有用。在实现自适应布局时,我们经常需要根据内容的大小来动态地调整元素的宽度,而 max-content 正是为这种场景而生的。

width: min-content 指元素宽度自动调整为其所包含的最小内容。如果元素的内容比它的宽度更窄,那么该元素将以内容的宽度为基础来进行渲染。如果该元素的内容比其宽度更宽,则会按照其默认的宽度来渲染,并在容器中溢出

  • cors 中个的 withCredentials 有什么用(from gpt)

    withCredentials 是 XMLHttpRequest 对象的一个属性,它是用于指定跨域请求时是否携带 Cookie 和认证信息的。当设置 withCredentials 为 true 时,请求中会携带当前域的 Cookie 和认证信息,而这些信息会被浏览器自动添加到请求的头部中。如果没有设置 withCredentials,则请求头中不会包含 Cookie 和认证信息。需要注意的是,当开启 withCredentials 属性后,服务器端需要配置响应头 Access-Control-Allow-Credentials 为 true,才能使得请求能够成功返回数据。

每日一题,说下 react 和 vue 区别(from gpt)

Vue 和 React 是目前最流行的前端框架之一,虽然两者都可以用来构建单页面应用程序 (SPA),但在实现细节和编程模型上有一些不同点。以下是一些主要的区别:

模板语法不同:Vue 使用基于 HTML 的模板语法,而 React 使用 JavaScript 中的 JSX 语法。

组件定义方式不同:Vue 中定义组件时使用的是对象字面量的方式,而 React 中使用 ES6 类或函数式组件的方式。

数据绑定方式不同:Vue 使用双向数据绑定 (two-way data binding),而 React 使用单向数据流 (one-way data flow)。

组件通信方式不同:Vue 使用 prop 和自定义事件进行父子组件之间的通信,而 React 使用 props 和回调函数。

状态管理方式不同:Vue 使用 Vuex 进行状态管理,而 React 使用 Redux 或者 Context API 进行状态管理。

渲染方式不同:Vue 使用模板编译的方式进行渲染,而 React 使用虚拟 DOM 进行渲染。

性能优化方面不同:Vue 通过模板编译的方式进行编译优化,而 React 通过使用 Fiber 架构和异步渲染等方式进行性能优化。

总的来说,Vue 更加注重开发者友好和快速开发,而 React 更加注重灵活性和可维护性。选择使用哪个框架,应该根据具体项目需求和开发团队的技术背景来决定。

每日一题,说下 react 中的并发更新

react 表单受控组件和非受控组件优缺点

0404

  • CSS 属性 overflow-wrap 是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词中断换行。
css
overflow-wrap: break-word; // 英文字母不换行处理

太失败了 逻辑思维太差劲

js
/**
 * @param {number[]} nums1
 * @param {number} m
 * @param {number[]} nums2
 * @param {number} n
 * @return {void} Do not return anything, modify nums1 in-place instead.
 */
var merge = function (nums1, m, nums2, n) {
  nums1.splice(m, n, ...nums2);
  nums1.sort((a, b) => a - b);
};
  • splice 实现数组增加元素
js
const arr = [1, 2, 3, 4, 5, 6];
arr.splice(3, 0, 7, 7); // 从索引为3的位置删除0个元素添加7 和 7
console.log(arr); // [1,2,3,7,7, 4,5,6]

// 从索引 2 的位置开始删除所有元素
var myFish = ["angel", "clown", "mandarin", "sturgeon"];
var removed = myFish.splice(2);
// 运算后的 myFish: ["angel", "clown"]
// 被删除的元素:["mandarin", "sturgeon"]

// 从索引 -2 的位置开始删除 1 个元素
var myFish = ["angel", "clown", "mandarin", "sturgeon"];
var removed = myFish.splice(-2, 1);
// 运算后的 myFish: ["angel", "clown", "sturgeon"]
// 被删除的元素:["mandarin"]

// 从索引 2 的位置开始删除 1 个元素,插入“trumpet”
var myFish = ["angel", "clown", "drum", "sturgeon"];
var removed = myFish.splice(2, 1, "trumpet");
// 运算后的 myFish: ["angel", "clown", "trumpet", "sturgeon"]
// 被删除的元素:["drum"]

0405 清明节放假一天

  • Headless CMS?

    就是没有展示界面,只提供内容管理和内容 API 的 CMS

Headless CMS(Headless Content Management System)是一种新型的内容管理系统。相对于传统的 CMS,Headless CMS 更加注重内容管理系统的内容管理能力,而不是提供页面模板等展示功能。Headless CMS 通过提供 API 来将内容与展示分离,使得前端展示可以更加灵活和多样化。

Headless CMS 的工作方式如下:

内容管理:Headless CMS 提供一套完善的内容管理工具,可以帮助管理员更加便捷地创建、修改、发布和管理各种内容。

API 调用:Headless CMS 将内容以 API 的形式暴露出来,前端可以通过 API 调用来获取数据,从而自由地进行展示和定制。

前端展示:由于 Headless CMS 与展示无关,因此前端可以使用各种技术和工具来实现展示,例如 React、Vue、Angular 等等。

Headless CMS 可以在各种场景下使用,例如单页应用、移动应用、静态网站等。它的优点包括更加灵活的前端展示、更加易于扩展和定制、更加适合多平台展示等等。

  • tailwindcss, 首先推荐一个网站 tailblocks.cc, 它拥有 50+ 代码块,在右上角可以切换网站主题颜色,所有的代码块都是响应式的,并且支持暗黑皮肤。 通过键盘左右键可以快速切换、预览效果。

  • 从 0 到 1 搭建个人博客,需要使用的技术有 nextjs+tailwindcss,从此刻开始实践,需要用到的包有

js
import Markdown from "markdown-it";
import matter from "gray-matter";

0406

有太多的知识需要学习,稳住心态!

0407

  • 利用 GPT 自动生成词典,如何做到自动化的?不可能是人工粘贴和复制?

react 中的 useMemo 和 useCallback

  • 本质上,useMemo 和 useCallback 都是用来帮助我们优化 重新渲染 的工具 Hook
  • useMemo 接受两个参数:

a.需要执行的一些计算处理工作,包裹在一个函数中 b.一个依赖数组

在组件挂载的过程中,当这个组件第一次被渲染时,React 都会调用这个函数来执行这段计算逻辑,计算所有的质数。无论我们从这个函数中返回什么值,都会分配给 allPrimes 变量。

然而,对于每一个后续的渲染,React 都要从以下两种情况中做出选择:

a.再次调用 useMemo 中的计算函数,重新计算数值 b.重复使用上一次已经计算出来的数据

为了做出一个正确的选择,React 会判断你传入的依赖数组,这个数组中的每个变量是否在两次渲染间 值是否改变了 ,如果发生了改变,就重新执行计算的逻辑去获取一个新的值,否则不重新计算,直接返回上一次计算的值。

useMemo 本质上就像一个小的缓存,而依赖数组就是缓存的失效策略

在上面的例子中,其实本质上是在说 “只有当 selectedNum 的值变化时才重新计算质数列表“。 当组件因为其他情况重新渲染,例如状态 time 的值改变了,useMemo 就会忽略这个计算函数,直接返回之前缓存的值。

  • 简单的数据类型比如 字符串、数字和布尔值 可以通过值进行比较。但是当涉及到数组和对象时,它们只能通过引用进行比较

  • 通过在多次渲染中保留相同的引用,我们允许纯组件以我们想要的方式运作,忽略掉那些不影响用户界面的渲染。

  • useCallback 的用途与 useMemo 相同,但它是专门为函数构建的。我们直接给返回它一个函数,它会记住这个函数,在渲染之间线程化它。

js
React.useCallback(function helloWorld() {}, []);

// ...功能相当于:
React.useMemo(() => function helloWorld() {}, []);

useCallback 是一种语法糖,它的存在存粹是为了让我们在缓存回调函数的时候可以方便点。

0408

0409

  • 跑完苏州回沪躺了一天,明天开始步入正轨
  • 弄懂 React 事件机制 一般的事件触发都会经历三个阶段:

捕获阶段,事件从 window 开始,自上而下一直传播到目标元素的阶段。 目标阶段,事件真正的触发元素处理事件的阶段。 冒泡阶段,从目标元素开始,自下而上一直传播到 window 的阶段。

如果想阻止事件的传播,可以在指定节点的事件监听器通过 **event.stopPropagation()**或 event.cancelBubble = true 阻止事件传播。

有些事件是没有冒泡阶段的,如 scroll、blur、及各种媒体事件等。

0410

  • 匆匆忙忙完成两个业务需求,都没时间记录
  • 听到奶奶住院,感觉大事不好,最近得回老家一趟看望老人

0411

  • 把前几天看到的记录下, 奇迹小说网站参考
  • 生活就是个缓慢受锤的过程, 人一天天老下去, 奢望也一天天消逝, 最后变得像挨了锤的牛一样。 可是我过二十一岁生日时没有预见到这一点。 我觉得自己会永远生猛下去, 什么也锤不了我。 ——王小波语录《黄金时代》
  • 今天完成 H5 唤端 APP 以及 [React 事件机制]两篇记录文章

0412

  • nofollow 是 HTML 页面中 a 标签的属性值。这个标签的意义是告诉搜索引擎"不要追踪此网页上的链接或不要追踪此特定链接"
js
<a href="" rel="nofollow">
  A标签
</a>
  • tree Shaking

依赖于 ES6 的模块特性,ES6 模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,这就是 tree-shaking 的基础。

静态分析就是不需要执行代码,就可以从字面量上对代码进行分析。ES6 之前的模块化,比如 CommonJS 是动态加载,只有执行后才知道引用的什么模块,就不能通过静态分析去做优化,正是基于这个基础上,才使得 tree-shaking 成为可能

但 并不是说所有无用的代码都可以被消除,还是上面的代码,换个写法 tree-shaking 就失效了

js
// util.js
export default {
  targetType(target) {
    return Object.prototype.toString.call(target).slice(8, -1).toLowerCase();
  },
  deepClone(target) {
    return JSON.parse(JSON.stringify(target));
  },
};

// 引入并使用
import util from "../util";
util.targetType(null);

究其原因,export default 导出的是一个对象,「无法通过静态分析判断出一个对象的哪些变量未被使用,所以 tree-shaking 只对使用 export 导出的变量生效」

这也是函数式编程越来越火的原因,因为可以很好利用 tree-shaking 精简项目的体积,也是 vue3 全面拥抱了函数式编程的原因之一

长列表虚拟滚动(未完待续)

7 个月过去了

0413

  • react 版的 blog 借鉴 nextra

  • ssg 中如何读取和解析 markdown 内容,并且如何去渲染的?

  • vitepress 是如何读取 markdown 内容以及渲染的?

  • 大胆猜想下: 写文章都是 md 格式的,前面会有 YAML 格式的内容,比如标记文章标题/tag/IMG 等等,然后是正文内容.服务端需要做的就是解析 Yaml 内容,拿到文章相关信息以及正文信息,然后再用**markdown-it**渲染出来

md
---
layout: doc
title: 工作记录
---

渲染的思路大概是: 利用 markdown-it 包 解析 md 格式的文档成 html

js
import Markdown from "markdown-it";
const md = new Markdown();
md.render("# This is Title");
// 解析出 如下html
{
  /* <h1>This is Title</h1> */
}

那用户写的文章都是 md 文档,是不是不用转换来在转换去?这块不是很懂,应该还是需要转换,需要拿到 yaml 格式的内容,转换成文本,然后再利用*gray-matter 包*解析出 md 文档

js
import Markdown from "markdown-it";
const md = new Markdown();
import matter from "gray-matter";
const result = matter("---\ntitle: Home\n---\nOther stuff");
//=> { data: { title: 'Home'}, content: 'Other stuff' }
md.render(result.content);

举例子

md
---
title: Hello
slug: home
---

<h1>Hello world!</h1>

得到这样的对象

js
{
  content: '<h1>Hello world!</h1>',
  data: {
    title: 'Hello',
    slug: 'home'
  }
}

0414

  • 心无旁骛,专心自己的研究才是王道,这几天务必把个人博客整一整?

解析 md 的各种插件眼花缭乱,都不知道哪个对应哪一个

  • gray-matter

可以方便地解析文本文件中的 Front Matter,然后使用解析后的数据来渲染网站的各种元素,例如文章标题、作者、发布日期等等。同时,它也可以将解析后的数据与文件内容一起写回到原始文件中。

  • remark

remark 是一个 JavaScript 库,用于处理和转换 Markdown 文档。它可以用于在 Node.js 中构建自定义文档处理工具,也可以用于在 Web 浏览器中实时转换 Markdown 文本。 remark 的主要功能包括解析和序列化 Markdown 文档,提供 AST(抽象语法树)节点和插件架构,允许开发人员编写自定义的 Markdown 转换器和语法分析器。此外,remark 还具有插件生态系统,可以在其上构建插件来添加新功能或修改现有功能。

  • rehype

rehype 是一个用于 HTML 和 XML 的可扩展处理器,是一个通用的 HTML 转换器。它是由 unified 生态系统中的插件所支持的,可以让你的 HTML 或 XML 数据与其他的工具协同工作,例如用于解析 markdown 文档的 remark。

rehype 本身并不提供太多的功能,而是通过插件来扩展其能力。rehype 提供了一种在 HTML 和 XML 数据中转换和操作标记的方式。你可以在 HTML 中使用类似的 AST 语法树,然后使用插件来处理该树的节点并且在插件之间传递该树。

rehype 可以被用来实现很多的功能,例如处理 HTML 和 XML 的转换和规范化、代码高亮、代码语法高亮、文本处理等等。它是一个非常灵活和可扩展的工具,可以被用于各种不同的前端开发任务。

0415/16

  • 看了下电动车,价格太贵,无奈自己还是太穷啦!
  • 输入是 md 语法,输出是 html 这块工具包还是蛮多的,有很多地方不了解

remark 举例

You can use plugins to change markdown. In:

md
// 输入

# Hi, Saturn!

Plugin:

js
import { visit } from "unist-util-visit";

/** @type {import('unified').Plugin<[], import('mdast').Root>} */
function myRemarkPluginToIncreaseHeadings() {
  return (tree) => {
    visit(tree, (node) => {
      if (node.type === "heading") {
        node.depth++;
      }
    });
  };
}

运行完插件之后,输出

md
## Hi, Saturn!

remark 第二个例子

Example: turning markdown into HTML 把 md 转弯转成 html,remark is an ecosystem around markdown. A different ecosystem is for HTML: rehype(重新炒作 html). The following example turns markdown into HTML by combining both ecosystems with remark-rehype:

js
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeSanitize from "rehype-sanitize";
import rehypeStringify from "rehype-stringify";

main();

async function main() {
  const file = await unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypeSanitize)
    .use(rehypeStringify)
    .process("# Hello, Neptune!");

  console.log(String(file));
}

输出

js
<h1>Hello, Neptune!</h1>

0417

  • 写业务,奇迹文学网站前期代码量还挺多的,加油,继续画书本页
  • 专注一件事,个人博客

0418

  • 继续写业务
  • 没有机会接触到核心业务,也没有机会施展拳脚,业务受限,方向受限,所以晋升就看看吧,千万别当真
  • 提高业务效率,专注于自己想做的事上面

0419

  • 当你在骑行或者开车的场景下,没有思考的空间的时候,不要轻易答应,这个时候阔以礼貌性回复,'稍等一下,或者等我十几分钟',然后等你有思考的空间了,再做决定。

0420

个人博客终于进入到了关进环节,也就是 md 文件的渲染部分,最终还是采用 next+mdx+remote,基础使用部分

js
import { serialize } from "next-mdx-remote/serialize";
import { MDXRemote } from "next-mdx-remote";

import Test from "../components/test";

const components = { Test };

export default function TestPage({ source }) {
  return (
    <div className="wrapper">
      <MDXRemote {...source} components={components} />
    </div>
  );
}

export async function getStaticProps() {
  // MDX text - can be from a local file, database, anywhere
  const source = "Some **mdx** text, with a component <Test />";
  const mdxSource = await serialize(source);
  return { props: { source: mdxSource } };
}

Test 组件是阔以内嵌在 md 文档里阔以渲染的

0421

  • hyphens 属性定义是否允许在一行文本中使用连字符创建更多的自动换行机会。 hyphens: manual // 默认。单词只在 ‐ 或 ­ 处有连字符(如果需要) hyphens: none // 单词不用连字符(不换行)。

  • 代码语法高亮??prismjs

0422

  • 周末又是跑了一趟医院皮肤科,还是太穷了,治不起

0423

  • 中午时间还是不能看比赛,一看就睡不着,身体已经严重透支,需要休息啦!!
  • 自分享唤端的这个真慢,目前思路是等待微信标签初始化之后再去显示播放按钮,慢的主要原因是在安卓端 weixinjs SDK 加载太慢导致

0424

  • 自己做博客,有点辛苦,需要调休下
  • ssr 项目发布失败,要记得去查看机器信息,然后访问日志 pm2 log 去看看错误信息

0425

使用 docker-compose

Docker Compose 是一个用来定义和运行复杂应用的 Docker 工具。一个使用 Docker 容器的应用,通常由多个容器组成。使用 Docker Compose 不再需要使用 shell 脚本来启动容器。 Compose 通过一个配置文件来管理多个 Docker 容器,在配置文件中,所有的容器通过 services 来定义,然后使用 docker-compose 脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。使用的三个步骤:

使用 Dockerfile 定义应用程序的环境。

使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。

最后,执行 docker-compose up 命令来启动并运行整个应用程序。

yaml
version: "3" #版本号
services: #docker容器
  nginx: #容器名称
    container_name: nginx-1 #自定义启动后容器名
    restart: always #设置为always,表明此容器应该在停止的情况下总是重启
    image: nginx:latest #镜像名:版本号
    ports: #启动端口号 宿主机端口:容器端口
      - 3000:80
    volumes: #数据卷,将容器中的文件与服务器映射
      - ./conf.d:/etc/nginx/conf.d
    environment: #环境配置
      TZ: Asia/SH
      env: production

docker-compose 常用命令

shell
 # 1. 基于docker-compose.yml启动管理的容器
docker-compose up -d
# 2. 关闭并删除容器
docker-compose down
# 3. 开启|关闭|重启已经存在的由docker-compose维护的容器
docker-compose start|stop|restart
# 4. 查看由docker-compose管理的容器
docker-compose ps
# 5. 查看日志
docker-compose logs -f

0426

  • 期望越大失望越大,随时准备着,继续准备,开发工具 vite/rollup 和 react/vue 源码阅读
  • vite 搭建开发环境,手写?简历中的项目要非常熟悉

0427

  • 终于搞完了博客的基本开发功能,算是有始有终,接下来就是小修小补

0428

  • 有点迷茫,对于现状不满,不知道如何破局

0429

  • 五一安排,针对简历是的东西回顾回归知识点,postcss 和 vite 相关知识点几乎是不熟悉了,需要时间回顾回顾下 了解 rollup/vite 打包构建流程以及相关 plugin 插件,这个都忘得差不多了 了解 babel 编译原理, 了解 postcss 编译原理,实践实践 nextjs 中的 getServerSideProps/getStaticProps 怎么实现的,如何才能实现
  • tailwindcss 是如何运行起来的,如果让你设计一个怎么实现

0430

  • 参加老铁婚礼,大清早三点半起来,导致现在都没休息好,消耗太大
  • 过节高峰期,五一十一春节,如果能在出发前买到票就走,买不到就原地休息。抢票需要定制下抢票方案,高铁和动车是首选,如果抢不到 K 开头的列车一定要有座,这次从南京回上海将近五个小时站着,累个半死