diff --git a/404.html b/404.html index b484eb959..7b05c439b 100644 --- a/404.html +++ b/404.html @@ -26,7 +26,7 @@
- + \ No newline at end of file diff --git a/analysis/cli/create-vue.html b/analysis/cli/create-vue.html index e6adebfe8..1a5fcee74 100644 --- a/analysis/cli/create-vue.html +++ b/analysis/cli/create-vue.html @@ -855,7 +855,7 @@ ...sorted, } } - + \ No newline at end of file diff --git a/analysis/react/18.2.0/base/fiber.html b/analysis/react/18.2.0/base/fiber.html index e4a03c934..45f3b44b1 100644 --- a/analysis/react/18.2.0/base/fiber.html +++ b/analysis/react/18.2.0/base/fiber.html @@ -77,7 +77,7 @@ } ReactDOM.render(<App />, document.getElementById('root'))
  1. 首次执行 ReactDOM.render 时会创建 fiberRootNode(源码中叫 fiberRoot)和 rootFiber

为什么要区分 fiberRootNoderootFiber

因为在一个 React 应用中我们可以多次调用 ReactDOM.render 来渲染不同的组件树,这时它们会拥有不同的 rootFiber。但是整个应用的根节点只有一个那就是 fiberRootNode

这时 fiberRootNodecurrent 指针会指向当前页面上已渲染内容对应 Fiber 树(即 current Fiber 树

rootFiber

js
fiberRootNode.current = rootFiber

由于是首屏渲染,页面中还没有挂载任何 DOM,所以 fiberRootNode.current 指向的 rootFiber 是没有任何 子 Fiber 节点的(即current Fiber 树为空)

  1. 接下来进入 render 阶段,根据组件返回的 JSX 在内存中依次创建 Fiber 节点 并连接在一起构建 Fiber 树,其被称为workInProgress Fiber 树(下图中右侧为内存中构建的树,左侧为页面显示的树)

在构建 workInProgress Fiber 树 时会尝试复用 current Fiber 树 中已有的 Fiber 节点 内的属性,在首屏渲染时只有 rootFiber 存在对应的 current fiber(即 rootFiber.alternate

workInProgressFiber

  1. 图中右侧已构建完的 workInProgress Fiber 树 会在 commit 阶段 渲染到页面

此时 DOM 更新为右侧树对应的界面。fiberRootNodecurrent 指针指向 workInProgress Fiber 树 使其变更为current Fiber 树(即下图所示)

wipTreeFinish

update 阶段

  1. 当我们点击 p 节点 触发状态改变时,会开启一次新的 render 阶段 并构建一棵新的 workInProgress Fiber 树

wipTreeUpdate

mount 时一样,workInProgress fiber 的创建会复用 current Fiber 树 中对应的节点数据

决定是否复用的过程就是 Diff 算法

  1. workInProgress Fiber 树render 阶段 完成构建后进入 commit 阶段 渲染到页面上。在渲染完毕后workInProgress Fiber 树 变更为 current Fiber 树

currentTreeUpdate


相关资料

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/base/file.html b/analysis/react/18.2.0/base/file.html index 39c642cc9..4ac78ff40 100644 --- a/analysis/react/18.2.0/base/file.html +++ b/analysis/react/18.2.0/base/file.html @@ -64,7 +64,7 @@ ├── react-server-dom-webpack ├── react-server-native-relay └─ react-suspense-test-utils # React Suspense 组件的测试工具包 - + \ No newline at end of file diff --git a/analysis/react/18.2.0/base/idea.html b/analysis/react/18.2.0/base/idea.html index 7fc73c0e4..72f239e94 100644 --- a/analysis/react/18.2.0/base/idea.html +++ b/analysis/react/18.2.0/base/idea.html @@ -36,7 +36,7 @@ }

源码地址 workLoopConcurrent | ReactFiberWorkLoop.old.js

在 React16 中,Reconciler 与 Renderer 不再是交替工作。当 Scheduler 将任务交给 Reconciler 后,Reconciler 会为变化的虚拟 DOM 打上代表增/删/更新的标记,类似这样:

js
export const Placement = /*                    */ 0b00000000000000000000000010
 export const Update = /*                       */ 0b00000000000000000000000100
 export const Deletion = /*                     */ 0b00000000000000000000001000

同时整个 Scheduler 与 Reconciler 的工作都在内存中进行。只有当所有组件都完成 Reconciler 的工作,才会统一交给 Renderer,这样就保证了整个过程不会出现中断导致页面渲染不完全的情况

Renderer(渲染器)

Renderer 根据 Reconciler 为 Fiber 节点打的标记,同步执行对应的 DOM 操作

在 React 16 架构中的更新流程

update-process

红框中的步骤随时可能由于以下原因被中断:

由于红框中的工作都在内存中进行,不会更新页面上的 DOM,所以即使反复中断用户也不会看见更新不完全的 DOM


相关资料

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/base/jsx.html b/analysis/react/18.2.0/base/jsx.html index aa67982cd..83c96b54f 100644 --- a/analysis/react/18.2.0/base/jsx.html +++ b/analysis/react/18.2.0/base/jsx.html @@ -122,7 +122,7 @@ function App() { return _jsx('h1', { children: 'Hello world' }) }

jsx 方法和上面的 createElement 方法一样,都是对参数进行处理,最后调用 ReactElement 方法返回 React Element 对象

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/base/mode-process.html b/analysis/react/18.2.0/base/mode-process.html index 1ed3b2fac..ad149c102 100644 --- a/analysis/react/18.2.0/base/mode-process.html +++ b/analysis/react/18.2.0/base/mode-process.html @@ -32,7 +32,7 @@ export const LegacyRoot = 0 export const ConcurrentRoot = 1

渲染流程

React 应用程序的渲染流程可以分为三个阶段:

rendercommit 阶段统称为 work,即 React 在工作中。如果任务正在 Scheduler 内调度就不属于 work 阶段

legacy 模式的调用栈

legacy-process

concurrent 模式的调用栈

concurrent-process

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/base/virtual-dom.html b/analysis/react/18.2.0/base/virtual-dom.html index c9d71caff..261ca5579 100644 --- a/analysis/react/18.2.0/base/virtual-dom.html +++ b/analysis/react/18.2.0/base/virtual-dom.html @@ -34,7 +34,7 @@ str += k + ' ' } console.log('' + str)

DOM

可以看到原生 DOM 对象上有很多属性和方法,而我们在操作 DOM 后,浏览器会进行重排(Reflow)和重绘(Repaint),一旦操作不当,就会造成性能问题

什么是 Virtual DOM

Virtual DOM 是 JavaScript 和 DOM 之间的一个映射缓存,其本质上是一个轻量级的 JavaScript 对象树,它通过这个树来描述 DOM 树的结构和属性

Virtual DOM 的工作原理

  1. 创建 Virtual DOM:当应用初始化时或数据发生变化时,会创建或更新 Virtual DOM
  2. Diff 算法:在生成新的 Virtual DOM 之后,会与之前的 Virtual DOM 进行比较,找出两者之间的差异。这个过程称为 Diff 算法,它能够高效地计算出需要更新的最小操作集合
  3. 更新原生 DOM:通过 Diff 算法的结果,确定了哪些部分需要更新,然后将这些变化应用到真实 DOM 上。这个阶段真正将变化应用到 DOM 上,通常使用最小的 DOM 操作来实现更新,从而减少了 DOM 操作的开销。

可以看到 Virtual DOM 的本质是一种在内存中进行 DOM 树的处理和优化的机制。通过在 JavaScript 对象上进行操作,可以避免频繁的直接 DOM 操作,从而提高了应用的性能和响应速度。虽然 Virtual DOM 本身会引入一定的计算开销,但由于减少了真实 DOM 操作,整体上还是对性能有所提升

Virtual DOM 的优缺点

优点

缺点


相关资料

网上都说操作真实 DOM 慢,但测试结果却比 React 更快,为什么? - 尤雨溪的回答

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/begin-work.html b/analysis/react/18.2.0/process/begin-work.html index d580cd1d5..ce8e6c6ff 100644 --- a/analysis/react/18.2.0/process/begin-work.html +++ b/analysis/react/18.2.0/process/begin-work.html @@ -421,7 +421,7 @@ export const Hydrating = /* */ 0b00000000000001000000000000 export const Visibility = /* */ 0b00000000000010000000000000 export const StoreConsistency = /* */ 0b00000000000100000000000000

在通知 Renderer 将 Fiber 节点 对应的 DOM 节点 渲染到页面上需要满足以下两个条件:

  1. fiber.stateNode 存在(即 Fiber 节点 中保存了对应的 DOM 节点
  2. fiber.flags 中包含 Placement 标记(即 DOM 节点 需要被插入到页面上)

在首屏渲染时如何满足上述两个条件?

  1. fiber.stateNode 会在 completeWork 中创建
  2. mount 时只有 rootFiber 会赋值 Placement flags,其他 Fiber 节点 都不会赋值 Placement flags,因此在 commit 阶段,插入操作仅会在根节点执行一次,避免了重复的 DOM 操作

如果在 mountChildFibers 时也会赋值 Placement flags,那么整棵 Fiber 的每个节点都会具有 Placement flags,这会导致在 commit 段执行大量的 DOM 插入操作,效率极低;

因此 React 进行了优化:mount 时只有 rootFiber 会赋值 Placement flags,从而确保在 commit 阶段只有一次插入操作,有效地提升了渲染性能

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/commit-before-mutation-effects.html b/analysis/react/18.2.0/process/commit-before-mutation-effects.html index 2dba37c61..d9109512f 100644 --- a/analysis/react/18.2.0/process/commit-before-mutation-effects.html +++ b/analysis/react/18.2.0/process/commit-before-mutation-effects.html @@ -179,7 +179,7 @@ } } } - + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/commit-layout-effects.html b/analysis/react/18.2.0/process/commit-layout-effects.html index 354ff5d6a..93296bd77 100644 --- a/analysis/react/18.2.0/process/commit-layout-effects.html +++ b/analysis/react/18.2.0/process/commit-layout-effects.html @@ -335,7 +335,7 @@ } } } - + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/commit-mutation-effects.html b/analysis/react/18.2.0/process/commit-mutation-effects.html index 13eb80468..e3bd5b9e3 100644 --- a/analysis/react/18.2.0/process/commit-mutation-effects.html +++ b/analysis/react/18.2.0/process/commit-mutation-effects.html @@ -524,7 +524,7 @@ ) } } - + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/commit-root.html b/analysis/react/18.2.0/process/commit-root.html index 721d99ccf..a6e7463ac 100644 --- a/analysis/react/18.2.0/process/commit-root.html +++ b/analysis/react/18.2.0/process/commit-root.html @@ -525,7 +525,7 @@ return null }

可以看到在 layput 阶段之后 主要做了以下工作:

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/complete-work.html b/analysis/react/18.2.0/process/complete-work.html index 8921409c3..c7fa7fc2d 100644 --- a/analysis/react/18.2.0/process/complete-work.html +++ b/analysis/react/18.2.0/process/complete-work.html @@ -376,7 +376,7 @@ </button> ) }

updatePayload

- + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/init.html b/analysis/react/18.2.0/process/init.html index 5d04ecd2d..a8d02890d 100644 --- a/analysis/react/18.2.0/process/init.html +++ b/analysis/react/18.2.0/process/init.html @@ -237,7 +237,7 @@ // 返回当前更新的优先级 return lane } - + \ No newline at end of file diff --git a/analysis/react/18.2.0/process/schedule-update-on-fiber.html b/analysis/react/18.2.0/process/schedule-update-on-fiber.html index 405e13df4..183662ab6 100644 --- a/analysis/react/18.2.0/process/schedule-update-on-fiber.html +++ b/analysis/react/18.2.0/process/schedule-update-on-fiber.html @@ -531,7 +531,7 @@ div Fiber completeWork App Fiber completeWork rootFiber completeWork

相关资料

- + \ No newline at end of file diff --git a/analysis/react/18.html b/analysis/react/18.html index 32d125aee..ab637c0ae 100644 --- a/analysis/react/18.html +++ b/analysis/react/18.html @@ -294,7 +294,7 @@ } export default App

执行堆栈图

从执行堆栈图看到,由于组件数量繁多(10000 个),JavaScript 执行时间为 300ms,也就是意味着在没有并发特性的情况下:一次性渲染 10000 个标签的时候,页面会阻塞大约 0.3 秒,造成卡顿;但是如果开启并发更新就不会存在这样的问题

并发模式总结

fiber 的含义

  1. 架构角度:在旧的架构中,Reconciler(协调器)采用递归的方式执行,无法中断,节点数据保存在递归的调用栈中,被称为 Stack Reconciler,stack 就是调用栈;在新的架构中,Reconciler(协调器)是基于 fiber 实现的,节点数据保存在 fiber 中,所以被称为 fiber Reconciler
  2. 静态数据结构角度:每个 fiber 对应一个组件,保存了这个组件类型对应的 dom 节点信息,这时,fiber 节点就是我们所说的虚拟DOM
  3. 动态工作单元角度:fiber 节点保存了该节点需要更新的状态以及需要执行的副作用

相关资料

React18 新特性解读 & 完整版升级指南

- + \ No newline at end of file diff --git a/analysis/react/interview.html b/analysis/react/interview.html index 14b74df6e..64d058cb5 100644 --- a/analysis/react/interview.html +++ b/analysis/react/interview.html @@ -156,7 +156,7 @@ } } }

属性代理和反向继承的总结

属性代理耦合度低,适用于多个业务组件的复用,而反向继承耦合度高,适用于单个业务组件的复用;通过反向继承方式实现的高阶组件比属性代理实现的高阶组件功能更强大,个性化程度更高

高阶组件的缺点


相关资料

setState 是同步更新还是异步更新

setState 在类组件中是 this.setState 方法,在函数组件中是 useState 返回值的修改函数 setState 用于变更状态,触发组件重新渲染,更新视图 UI

setState 是同步更新还是异步更新指的是:在调用 setState 之后是否马上能得到最新的 state 值,如果能就是同步,如果不能就是异步(React 官方定义是异步的)

React 18 之前

legacy 模式:ReactDOM.render(<App />, rootNode)

legacy 模式下,只要在 React 可以控制的地方,setState 的执行都是异步的,比如在 React 生命周期事件和合成事件中,都会走合并操作,延迟更新的策略
而在 React 无法控制的地方,如监听原生事件和异步调用的地方,setState 的执行都是就是同步的。比如在 addEventListenersetTimeoutsetIntervalPromiseMessageChannel 的回调函数中

React 18 之后

concurrent 模式:ReactDOM.createRoot(rootNode).render(<App />)

concurrent 模式下,由于默认启用了并发更新,所以 setState 的执行都是异步的,即不管是在 React 可以控制的地方还是无法控制的地方,默认都会走合并操作,延迟更新的策略

为什么 setState 是异步的?

RFClarification: why is setState asynchronous?


相关资料

- + \ No newline at end of file diff --git a/analysis/utils/await-to-js.html b/analysis/utils/await-to-js.html index 1930be0f0..b659ef16f 100644 --- a/analysis/utils/await-to-js.html +++ b/analysis/utils/await-to-js.html @@ -74,7 +74,7 @@ }) ) }

相关资料

- + \ No newline at end of file diff --git a/analysis/utils/clsx.html b/analysis/utils/clsx.html index bfe238e6f..ef09964b5 100644 --- a/analysis/utils/clsx.html +++ b/analysis/utils/clsx.html @@ -116,7 +116,7 @@ } export default clsx - + \ No newline at end of file diff --git a/analysis/utils/only-allow.html b/analysis/utils/only-allow.html index fdbc2661b..4f5ef7e65 100644 --- a/analysis/utils/only-allow.html +++ b/analysis/utils/only-allow.html @@ -145,7 +145,7 @@ // 返回 pmFromUserAgent 函数处理的结果 return pmFromUserAgent(process.env.npm_config_user_agent) } - + \ No newline at end of file diff --git a/assets/daily-notes_index.md.C_05FM_c.js b/assets/daily-notes_index.md.C_05FM_c.js deleted file mode 100644 index e22a20a17..000000000 --- a/assets/daily-notes_index.md.C_05FM_c.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,h as i,a8 as a,o as l}from"./chunks/framework.BU7NHiAd.js";const u=JSON.parse('{"title":"Daily Notes 日常笔记","description":"","frontmatter":{},"headers":[],"relativePath":"daily-notes/index.md","filePath":"daily-notes/index.md","lastUpdated":null}'),t={name:"daily-notes/index.md"};function o(n,e,r,p,m,d){return l(),i("div",null,e[0]||(e[0]=[a('

Daily Notes 日常笔记

日常笔记记录(零零散散啥都记系列)

新写一篇小笔记

共计 47 篇(上次更新: 2024-11-16)

2024 年 (共计 5 篇)

  1. 2024-11-16 —— 从 VSCode 迁移到 Cursor

  2. 2024-06-20 —— 漫画 APP 资源汇总

  3. 2024-05-24 —— 在 GitHub Actions 中触发其他仓库的 Actions

  4. 2024-05-20 —— 判断用户为移动端设备的若干种方式

  5. 2024-04-16 —— 浏览器的自动播放策略

2023 年 (共计 9 篇)

  1. 2023-12-13 —— 使用 shell 脚本复制项目信息到剪切板

  2. 2023-09-16 —— 使用 rollup 打包用户脚本(user script)

  3. 2023-05-21 —— 修改 node_modules 中的依赖(打补丁)

  4. 2023-05-18 —— 获取软件内置浏览器的 User-Agent

  5. 2023-03-12 —— VitePress 生成站点地图

  6. 2023-02-28 —— 使用 VitePress 打造个人前端导航网站

  7. 2023-02-20 —— 从 VuePress 迁移至 VitePress

  8. 2023-02-10 —— 不使用 JavaScript 来隐藏元素的若干方法

  9. 2023-01-06 —— 使用 shell 脚本检查并配置 git user 信息

2022 年 (共计 8 篇)

  1. 2022-12-28 —— 搭建青龙定时任务管理面板

  2. 2022-12-19 —— ShadowSocks PAC 用户自定规则

  3. 2022-10-28 —— Next.js 搭建官网踩坑小记

  4. 2022-10-19 —— 修复谷歌翻译失效

  5. 2022-09-13 —— CSS 伪类选择器中的表达式(an+b)

  6. 2022-08-16 —— 在 Github Actions 环境变量中传递数组或对象

  7. 2022-03-07 —— 常用搜索技巧

  8. 2022-01-13 —— Canvas 绘制带圆角的矩形图

2021 年 (共计 10 篇)

  1. 2021-12-16 —— Less 循环遍历和踩坑

  2. 2021-11-18 —— .npmrc 学习笔记

  3. 2021-11-09 —— Flex 语法和计算规则

  4. 2021-10-17 —— Plop 实战笔记

  5. 2021-08-19 —— 解决 Github Support for password

  6. 2021-05-31 —— 使用 npm 脚本钩子

  7. 2021-04-15 —— Webpack 打包优化(CRA 项目)

  8. 2021-01-22 —— Mac 终端小技巧

  9. 2021-01-14 —— 在 vue-cli 中使用 tailwindcss

  10. 2021-01-12 —— 修改 DNS 解决 Github 资源加载失败

2020 年 (共计 15 篇)

  1. 2020-11-27 —— CRA 接入 react-dev-inspector

  2. 2020-11-10 —— Webpack 性能分析

  3. 2020-10-22 —— puppeteer 学习笔记

  4. 2020-09-30 —— 使用 URLSearchParams 解析 URL 的查询字符串

  5. 2020-08-04 —— 获取当前 git 分支

  6. 2020-07-20 —— 语义化版本控制

  7. 2020-07-04 —— package.json 相关知识

  8. 2020-06-17 —— 使用 husky、lint-staged、commitlint 构建前端工作流

  9. 2020-06-15 —— 使用 jsdelivr 加速 Github 仓库资源

  10. 2020-06-06 —— 在项目中使用 ESLint 和 Prettier

  11. 2020-05-21 —— Tree-Shaking 相关笔记

  12. 2020-05-15 —— 使用 SVG 做动画

  13. 2020-04-30 —— 修改 CRA 的默认配置

  14. 2020-04-29 —— CSS 函数

  15. 2020-04-28 —— 使用 JS 开发命令行程序

',14)]))}const f=s(t,[["render",o]]);export{u as __pageData,f as default}; diff --git a/assets/daily-notes_index.md.C_05FM_c.lean.js b/assets/daily-notes_index.md.C_05FM_c.lean.js deleted file mode 100644 index e22a20a17..000000000 --- a/assets/daily-notes_index.md.C_05FM_c.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,h as i,a8 as a,o as l}from"./chunks/framework.BU7NHiAd.js";const u=JSON.parse('{"title":"Daily Notes 日常笔记","description":"","frontmatter":{},"headers":[],"relativePath":"daily-notes/index.md","filePath":"daily-notes/index.md","lastUpdated":null}'),t={name:"daily-notes/index.md"};function o(n,e,r,p,m,d){return l(),i("div",null,e[0]||(e[0]=[a('

Daily Notes 日常笔记

日常笔记记录(零零散散啥都记系列)

新写一篇小笔记

共计 47 篇(上次更新: 2024-11-16)

2024 年 (共计 5 篇)

  1. 2024-11-16 —— 从 VSCode 迁移到 Cursor

  2. 2024-06-20 —— 漫画 APP 资源汇总

  3. 2024-05-24 —— 在 GitHub Actions 中触发其他仓库的 Actions

  4. 2024-05-20 —— 判断用户为移动端设备的若干种方式

  5. 2024-04-16 —— 浏览器的自动播放策略

2023 年 (共计 9 篇)

  1. 2023-12-13 —— 使用 shell 脚本复制项目信息到剪切板

  2. 2023-09-16 —— 使用 rollup 打包用户脚本(user script)

  3. 2023-05-21 —— 修改 node_modules 中的依赖(打补丁)

  4. 2023-05-18 —— 获取软件内置浏览器的 User-Agent

  5. 2023-03-12 —— VitePress 生成站点地图

  6. 2023-02-28 —— 使用 VitePress 打造个人前端导航网站

  7. 2023-02-20 —— 从 VuePress 迁移至 VitePress

  8. 2023-02-10 —— 不使用 JavaScript 来隐藏元素的若干方法

  9. 2023-01-06 —— 使用 shell 脚本检查并配置 git user 信息

2022 年 (共计 8 篇)

  1. 2022-12-28 —— 搭建青龙定时任务管理面板

  2. 2022-12-19 —— ShadowSocks PAC 用户自定规则

  3. 2022-10-28 —— Next.js 搭建官网踩坑小记

  4. 2022-10-19 —— 修复谷歌翻译失效

  5. 2022-09-13 —— CSS 伪类选择器中的表达式(an+b)

  6. 2022-08-16 —— 在 Github Actions 环境变量中传递数组或对象

  7. 2022-03-07 —— 常用搜索技巧

  8. 2022-01-13 —— Canvas 绘制带圆角的矩形图

2021 年 (共计 10 篇)

  1. 2021-12-16 —— Less 循环遍历和踩坑

  2. 2021-11-18 —— .npmrc 学习笔记

  3. 2021-11-09 —— Flex 语法和计算规则

  4. 2021-10-17 —— Plop 实战笔记

  5. 2021-08-19 —— 解决 Github Support for password

  6. 2021-05-31 —— 使用 npm 脚本钩子

  7. 2021-04-15 —— Webpack 打包优化(CRA 项目)

  8. 2021-01-22 —— Mac 终端小技巧

  9. 2021-01-14 —— 在 vue-cli 中使用 tailwindcss

  10. 2021-01-12 —— 修改 DNS 解决 Github 资源加载失败

2020 年 (共计 15 篇)

  1. 2020-11-27 —— CRA 接入 react-dev-inspector

  2. 2020-11-10 —— Webpack 性能分析

  3. 2020-10-22 —— puppeteer 学习笔记

  4. 2020-09-30 —— 使用 URLSearchParams 解析 URL 的查询字符串

  5. 2020-08-04 —— 获取当前 git 分支

  6. 2020-07-20 —— 语义化版本控制

  7. 2020-07-04 —— package.json 相关知识

  8. 2020-06-17 —— 使用 husky、lint-staged、commitlint 构建前端工作流

  9. 2020-06-15 —— 使用 jsdelivr 加速 Github 仓库资源

  10. 2020-06-06 —— 在项目中使用 ESLint 和 Prettier

  11. 2020-05-21 —— Tree-Shaking 相关笔记

  12. 2020-05-15 —— 使用 SVG 做动画

  13. 2020-04-30 —— 修改 CRA 的默认配置

  14. 2020-04-29 —— CSS 函数

  15. 2020-04-28 —— 使用 JS 开发命令行程序

',14)]))}const f=s(t,[["render",o]]);export{u as __pageData,f as default}; diff --git a/assets/daily-notes_index.md.DrbQEmyg.js b/assets/daily-notes_index.md.DrbQEmyg.js new file mode 100644 index 000000000..a9e351fc5 --- /dev/null +++ b/assets/daily-notes_index.md.DrbQEmyg.js @@ -0,0 +1 @@ +import{_ as s,h as i,a8 as a,o as l}from"./chunks/framework.BU7NHiAd.js";const u=JSON.parse('{"title":"Daily Notes 日常笔记","description":"","frontmatter":{},"headers":[],"relativePath":"daily-notes/index.md","filePath":"daily-notes/index.md","lastUpdated":null}'),t={name:"daily-notes/index.md"};function o(n,e,r,p,m,d){return l(),i("div",null,e[0]||(e[0]=[a('

Daily Notes 日常笔记

日常笔记记录(零零散散啥都记系列)

新写一篇小笔记

共计 48 篇(上次更新: 2024-12-15)

2024 年 (共计 6 篇)

  1. 2024-12-15 —— 魅族 21 Pro 安装 Google 服务

  2. 2024-11-16 —— 从 VSCode 迁移到 Cursor

  3. 2024-06-20 —— 漫画 APP 资源汇总

  4. 2024-05-24 —— 在 GitHub Actions 中触发其他仓库的 Actions

  5. 2024-05-20 —— 判断用户为移动端设备的若干种方式

  6. 2024-04-16 —— 浏览器的自动播放策略

2023 年 (共计 9 篇)

  1. 2023-12-13 —— 使用 shell 脚本复制项目信息到剪切板

  2. 2023-09-16 —— 使用 rollup 打包用户脚本(user script)

  3. 2023-05-21 —— 修改 node_modules 中的依赖(打补丁)

  4. 2023-05-18 —— 获取软件内置浏览器的 User-Agent

  5. 2023-03-12 —— VitePress 生成站点地图

  6. 2023-02-28 —— 使用 VitePress 打造个人前端导航网站

  7. 2023-02-20 —— 从 VuePress 迁移至 VitePress

  8. 2023-02-10 —— 不使用 JavaScript 来隐藏元素的若干方法

  9. 2023-01-06 —— 使用 shell 脚本检查并配置 git user 信息

2022 年 (共计 8 篇)

  1. 2022-12-28 —— 搭建青龙定时任务管理面板

  2. 2022-12-19 —— ShadowSocks PAC 用户自定规则

  3. 2022-10-28 —— Next.js 搭建官网踩坑小记

  4. 2022-10-19 —— 修复谷歌翻译失效

  5. 2022-09-13 —— CSS 伪类选择器中的表达式(an+b)

  6. 2022-08-16 —— 在 Github Actions 环境变量中传递数组或对象

  7. 2022-03-07 —— 常用搜索技巧

  8. 2022-01-13 —— Canvas 绘制带圆角的矩形图

2021 年 (共计 10 篇)

  1. 2021-12-16 —— Less 循环遍历和踩坑

  2. 2021-11-18 —— .npmrc 学习笔记

  3. 2021-11-09 —— Flex 语法和计算规则

  4. 2021-10-17 —— Plop 实战笔记

  5. 2021-08-19 —— 解决 Github Support for password

  6. 2021-05-31 —— 使用 npm 脚本钩子

  7. 2021-04-15 —— Webpack 打包优化(CRA 项目)

  8. 2021-01-22 —— Mac 终端小技巧

  9. 2021-01-14 —— 在 vue-cli 中使用 tailwindcss

  10. 2021-01-12 —— 修改 DNS 解决 Github 资源加载失败

2020 年 (共计 15 篇)

  1. 2020-11-27 —— CRA 接入 react-dev-inspector

  2. 2020-11-10 —— Webpack 性能分析

  3. 2020-10-22 —— puppeteer 学习笔记

  4. 2020-09-30 —— 使用 URLSearchParams 解析 URL 的查询字符串

  5. 2020-08-04 —— 获取当前 git 分支

  6. 2020-07-20 —— 语义化版本控制

  7. 2020-07-04 —— package.json 相关知识

  8. 2020-06-17 —— 使用 husky、lint-staged、commitlint 构建前端工作流

  9. 2020-06-15 —— 使用 jsdelivr 加速 Github 仓库资源

  10. 2020-06-06 —— 在项目中使用 ESLint 和 Prettier

  11. 2020-05-21 —— Tree-Shaking 相关笔记

  12. 2020-05-15 —— 使用 SVG 做动画

  13. 2020-04-30 —— 修改 CRA 的默认配置

  14. 2020-04-29 —— CSS 函数

  15. 2020-04-28 —— 使用 JS 开发命令行程序

',14)]))}const f=s(t,[["render",o]]);export{u as __pageData,f as default}; diff --git a/assets/daily-notes_index.md.DrbQEmyg.lean.js b/assets/daily-notes_index.md.DrbQEmyg.lean.js new file mode 100644 index 000000000..a9e351fc5 --- /dev/null +++ b/assets/daily-notes_index.md.DrbQEmyg.lean.js @@ -0,0 +1 @@ +import{_ as s,h as i,a8 as a,o as l}from"./chunks/framework.BU7NHiAd.js";const u=JSON.parse('{"title":"Daily Notes 日常笔记","description":"","frontmatter":{},"headers":[],"relativePath":"daily-notes/index.md","filePath":"daily-notes/index.md","lastUpdated":null}'),t={name:"daily-notes/index.md"};function o(n,e,r,p,m,d){return l(),i("div",null,e[0]||(e[0]=[a('

Daily Notes 日常笔记

日常笔记记录(零零散散啥都记系列)

新写一篇小笔记

共计 48 篇(上次更新: 2024-12-15)

2024 年 (共计 6 篇)

  1. 2024-12-15 —— 魅族 21 Pro 安装 Google 服务

  2. 2024-11-16 —— 从 VSCode 迁移到 Cursor

  3. 2024-06-20 —— 漫画 APP 资源汇总

  4. 2024-05-24 —— 在 GitHub Actions 中触发其他仓库的 Actions

  5. 2024-05-20 —— 判断用户为移动端设备的若干种方式

  6. 2024-04-16 —— 浏览器的自动播放策略

2023 年 (共计 9 篇)

  1. 2023-12-13 —— 使用 shell 脚本复制项目信息到剪切板

  2. 2023-09-16 —— 使用 rollup 打包用户脚本(user script)

  3. 2023-05-21 —— 修改 node_modules 中的依赖(打补丁)

  4. 2023-05-18 —— 获取软件内置浏览器的 User-Agent

  5. 2023-03-12 —— VitePress 生成站点地图

  6. 2023-02-28 —— 使用 VitePress 打造个人前端导航网站

  7. 2023-02-20 —— 从 VuePress 迁移至 VitePress

  8. 2023-02-10 —— 不使用 JavaScript 来隐藏元素的若干方法

  9. 2023-01-06 —— 使用 shell 脚本检查并配置 git user 信息

2022 年 (共计 8 篇)

  1. 2022-12-28 —— 搭建青龙定时任务管理面板

  2. 2022-12-19 —— ShadowSocks PAC 用户自定规则

  3. 2022-10-28 —— Next.js 搭建官网踩坑小记

  4. 2022-10-19 —— 修复谷歌翻译失效

  5. 2022-09-13 —— CSS 伪类选择器中的表达式(an+b)

  6. 2022-08-16 —— 在 Github Actions 环境变量中传递数组或对象

  7. 2022-03-07 —— 常用搜索技巧

  8. 2022-01-13 —— Canvas 绘制带圆角的矩形图

2021 年 (共计 10 篇)

  1. 2021-12-16 —— Less 循环遍历和踩坑

  2. 2021-11-18 —— .npmrc 学习笔记

  3. 2021-11-09 —— Flex 语法和计算规则

  4. 2021-10-17 —— Plop 实战笔记

  5. 2021-08-19 —— 解决 Github Support for password

  6. 2021-05-31 —— 使用 npm 脚本钩子

  7. 2021-04-15 —— Webpack 打包优化(CRA 项目)

  8. 2021-01-22 —— Mac 终端小技巧

  9. 2021-01-14 —— 在 vue-cli 中使用 tailwindcss

  10. 2021-01-12 —— 修改 DNS 解决 Github 资源加载失败

2020 年 (共计 15 篇)

  1. 2020-11-27 —— CRA 接入 react-dev-inspector

  2. 2020-11-10 —— Webpack 性能分析

  3. 2020-10-22 —— puppeteer 学习笔记

  4. 2020-09-30 —— 使用 URLSearchParams 解析 URL 的查询字符串

  5. 2020-08-04 —— 获取当前 git 分支

  6. 2020-07-20 —— 语义化版本控制

  7. 2020-07-04 —— package.json 相关知识

  8. 2020-06-17 —— 使用 husky、lint-staged、commitlint 构建前端工作流

  9. 2020-06-15 —— 使用 jsdelivr 加速 Github 仓库资源

  10. 2020-06-06 —— 在项目中使用 ESLint 和 Prettier

  11. 2020-05-21 —— Tree-Shaking 相关笔记

  12. 2020-05-15 —— 使用 SVG 做动画

  13. 2020-04-30 —— 修改 CRA 的默认配置

  14. 2020-04-29 —— CSS 函数

  15. 2020-04-28 —— 使用 JS 开发命令行程序

',14)]))}const f=s(t,[["render",o]]);export{u as __pageData,f as default}; diff --git a/assets/daily-notes_issue-51.md.B9SDbeoB.js b/assets/daily-notes_issue-51.md.B9SDbeoB.js new file mode 100644 index 000000000..87859b4a9 --- /dev/null +++ b/assets/daily-notes_issue-51.md.B9SDbeoB.js @@ -0,0 +1 @@ +import{_ as e,h as l,a8 as a,o as r}from"./chunks/framework.BU7NHiAd.js";const u=JSON.parse('{"title":"魅族 21 Pro 安装 Google 服务","description":"","frontmatter":{},"headers":[],"relativePath":"daily-notes/issue-51.md","filePath":"daily-notes/issue-51.md","lastUpdated":null}'),t={name:"daily-notes/issue-51.md"};function i(d,o,c,s,n,h){return r(),l("div",null,o[0]||(o[0]=[a('

魅族 21 Pro 安装 Google 服务

原文地址

魅族 21 Pro 安装 Google 服务 | GitHub

记录下安装 Google 服务的过程,方便后续参考

开启谷歌服务

  1. 打开 设置
  2. 点击 辅助功能
  3. 开启 谷歌基础服务

登录谷歌账号

  1. 打开 设置
  2. 点击 辅助功能
  3. 点击 Google
  4. 点击 Google 账号 进行登录

更新 Google Play 服务

默认情况下 Google Play 不会显示在桌面,需要手动更新才能显示

  1. 打开 Google Play Store | APKMirror
  2. 下拉找到 All versions 点击最新版本(默认第一个为最新版本)
  3. 在新页面的 Download Google Play Store xx.xx.xx 中找到带 APK 标签的进行下载和安装

安装谷歌相机

',12)]))}const g=e(t,[["render",i]]);export{u as __pageData,g as default}; diff --git a/assets/daily-notes_issue-51.md.B9SDbeoB.lean.js b/assets/daily-notes_issue-51.md.B9SDbeoB.lean.js new file mode 100644 index 000000000..87859b4a9 --- /dev/null +++ b/assets/daily-notes_issue-51.md.B9SDbeoB.lean.js @@ -0,0 +1 @@ +import{_ as e,h as l,a8 as a,o as r}from"./chunks/framework.BU7NHiAd.js";const u=JSON.parse('{"title":"魅族 21 Pro 安装 Google 服务","description":"","frontmatter":{},"headers":[],"relativePath":"daily-notes/issue-51.md","filePath":"daily-notes/issue-51.md","lastUpdated":null}'),t={name:"daily-notes/issue-51.md"};function i(d,o,c,s,n,h){return r(),l("div",null,o[0]||(o[0]=[a('

魅族 21 Pro 安装 Google 服务

原文地址

魅族 21 Pro 安装 Google 服务 | GitHub

记录下安装 Google 服务的过程,方便后续参考

开启谷歌服务

  1. 打开 设置
  2. 点击 辅助功能
  3. 开启 谷歌基础服务

登录谷歌账号

  1. 打开 设置
  2. 点击 辅助功能
  3. 点击 Google
  4. 点击 Google 账号 进行登录

更新 Google Play 服务

默认情况下 Google Play 不会显示在桌面,需要手动更新才能显示

  1. 打开 Google Play Store | APKMirror
  2. 下拉找到 All versions 点击最新版本(默认第一个为最新版本)
  3. 在新页面的 Download Google Play Store xx.xx.xx 中找到带 APK 标签的进行下载和安装

安装谷歌相机

',12)]))}const g=e(t,[["render",i]]);export{u as __pageData,g as default}; diff --git a/assets/fe_monorepo_index.md.C7rO54Ic.js b/assets/fe_monorepo_index.md.KCsXh0q5.js similarity index 99% rename from assets/fe_monorepo_index.md.C7rO54Ic.js rename to assets/fe_monorepo_index.md.KCsXh0q5.js index cfa4941f6..f5dd394d0 100644 --- a/assets/fe_monorepo_index.md.C7rO54Ic.js +++ b/assets/fe_monorepo_index.md.KCsXh0q5.js @@ -21,7 +21,7 @@ import{_ as i,h as a,a8 as n,o as p}from"./chunks/framework.BU7NHiAd.js";const c ├── .git ├── src └── index.js - └── package.json

Multi-Repo 的优缺点

优点

缺点


如何选择

在选择时主要取决于项目需求、团队结构和偏好,没有哪种方式是绝对正确的,都要根据实际需求结合其优缺点来进行选择,下面是一些常见的考虑因素:

搭建 Monorepo 项目

常见的 Monorepo 实现

  1. 使用 pnpm/npm/yarnworkspace 功能
  2. 再搭配 Monorepo 管理工具
    1. pnpm
    2. lerna
    3. nx
    4. bazel
    5. rushstack

目前主流的方式是使用 pnpm 来做 Monorepo,其无须使用第三方工具就可以进行管理

安装 pnpm

sh
curl -fsSL https://get.pnpm.io/install.sh | sh -
sh
brew install pnpm
sh
npm install -g pnpm

相关资料

安装 | pnpm

创建项目

sh
# 创建并进入 my-monorepo 文件夹
+    └── package.json

Multi-Repo 的优缺点

优点

缺点


如何选择

在选择时主要取决于项目需求、团队结构和偏好,没有哪种方式是绝对正确的,都要根据实际需求结合其优缺点来进行选择,下面是一些常见的考虑因素:

搭建 Monorepo 项目

常见的 Monorepo 实现

  1. 使用 pnpm/npm/yarnworkspace 功能
  2. 再搭配 Monorepo 管理工具
    1. pnpm
    2. lerna
    3. nx
    4. bazel
    5. rushstack

目前主流的方式是使用 pnpm 来做 Monorepo,其无须使用第三方工具就可以进行管理

安装 pnpm

sh
curl -fsSL https://get.pnpm.io/install.sh | sh -
sh
brew install pnpm
sh
npm install -g pnpm

相关资料

安装 | pnpm

创建项目

sh
# 创建并进入 my-monorepo 文件夹
 mkdir my-monorepo
 cd my-monorepo
 
diff --git a/assets/fe_monorepo_index.md.C7rO54Ic.lean.js b/assets/fe_monorepo_index.md.KCsXh0q5.lean.js
similarity index 99%
rename from assets/fe_monorepo_index.md.C7rO54Ic.lean.js
rename to assets/fe_monorepo_index.md.KCsXh0q5.lean.js
index cfa4941f6..f5dd394d0 100644
--- a/assets/fe_monorepo_index.md.C7rO54Ic.lean.js
+++ b/assets/fe_monorepo_index.md.KCsXh0q5.lean.js
@@ -21,7 +21,7 @@ import{_ as i,h as a,a8 as n,o as p}from"./chunks/framework.BU7NHiAd.js";const c
     ├── .git
     ├── src
    └── index.js
-    └── package.json

Multi-Repo 的优缺点

优点

缺点


如何选择

在选择时主要取决于项目需求、团队结构和偏好,没有哪种方式是绝对正确的,都要根据实际需求结合其优缺点来进行选择,下面是一些常见的考虑因素:

搭建 Monorepo 项目

常见的 Monorepo 实现

  1. 使用 pnpm/npm/yarnworkspace 功能
  2. 再搭配 Monorepo 管理工具
    1. pnpm
    2. lerna
    3. nx
    4. bazel
    5. rushstack

目前主流的方式是使用 pnpm 来做 Monorepo,其无须使用第三方工具就可以进行管理

安装 pnpm

sh
curl -fsSL https://get.pnpm.io/install.sh | sh -
sh
brew install pnpm
sh
npm install -g pnpm

相关资料

安装 | pnpm

创建项目

sh
# 创建并进入 my-monorepo 文件夹
+    └── package.json

Multi-Repo 的优缺点

优点

缺点


如何选择

在选择时主要取决于项目需求、团队结构和偏好,没有哪种方式是绝对正确的,都要根据实际需求结合其优缺点来进行选择,下面是一些常见的考虑因素:

搭建 Monorepo 项目

常见的 Monorepo 实现

  1. 使用 pnpm/npm/yarnworkspace 功能
  2. 再搭配 Monorepo 管理工具
    1. pnpm
    2. lerna
    3. nx
    4. bazel
    5. rushstack

目前主流的方式是使用 pnpm 来做 Monorepo,其无须使用第三方工具就可以进行管理

安装 pnpm

sh
curl -fsSL https://get.pnpm.io/install.sh | sh -
sh
brew install pnpm
sh
npm install -g pnpm

相关资料

安装 | pnpm

创建项目

sh
# 创建并进入 my-monorepo 文件夹
 mkdir my-monorepo
 cd my-monorepo
 
diff --git a/assets/fe_node_pkg.md.BKRyM3y-.js b/assets/fe_node_pkg.md.DegpvfnG.js
similarity index 98%
rename from assets/fe_node_pkg.md.BKRyM3y-.js
rename to assets/fe_node_pkg.md.DegpvfnG.js
index 9d9575444..f91373f8a 100644
--- a/assets/fe_node_pkg.md.BKRyM3y-.js
+++ b/assets/fe_node_pkg.md.DegpvfnG.js
@@ -37,7 +37,7 @@ import{_ as t,h as r,l as a,e as i,I as e,b as l,a8 as p,C as h,o as k}from"./ch
 // recommend
 {
   "licenses": "MIT"
-}

文件配置

type

'commonjs' | 'module' 表明包使用的模块语法( Node@14 以上版本支持 ES Module

bin

string | { \${binName}: \${binFilePath} } 声明包的脚本文件

脚本文件一般在文件头以 SheBang 声明运行脚本的语言

sh
npm install demo -g
+}

文件配置

type

'commonjs' | 'module' 表明包使用的模块语法( Node@14 以上版本支持 ES Module

bin

string | { \${binName}: \${binFilePath} } 声明包的脚本文件

脚本文件一般在文件头以 SheBang 声明运行脚本的语言

sh
npm install demo -g
 
 d
 # log: Npm is COOL
js
#!/usr/bin/env node
@@ -50,7 +50,7 @@ import{_ as t,h as r,l as a,e as i,I as e,b as l,a8 as p,C as h,o as k}from"./ch
 }
sh
.
 ├── bin
    └── demo.js
-└── package.json

files

Array<string> 指明将此项目作为依赖包安装时包含的文件,默认为排除以下文件的全部内容:

TIP

files 字段作用类似的还有 .npmignore.gitignore

files 类似于白名单,往往产物内容更少更方便。而 ignore 文件类似于黑名单,需要开发者持续维护

types

string => filePath 声明此项目的 TypeScript 类型文件

TIP

  • typestypings 意义完全相同,可替换使用
  • 当主声明文件命名为 index.d.ts,并且位于包的根目录与 index.js 同级,则可以省略 types 字段,但建议保持良好的声明式习惯

参阅 TypeScript | Docs

main

string 标准化的工具包主入口

默认为 index.js ,主要用于 Node.jscjs 模块

js
const foo = require('foo') // => from "main" field
+└── package.json

files

Array<string> 指明将此项目作为依赖包安装时包含的文件,默认为排除以下文件的全部内容:

TIP

files 字段作用类似的还有 .npmignore.gitignore

files 类似于白名单,往往产物内容更少更方便。而 ignore 文件类似于黑名单,需要开发者持续维护

types

string => filePath 声明此项目的 TypeScript 类型文件

TIP

  • typestypings 意义完全相同,可替换使用
  • 当主声明文件命名为 index.d.ts,并且位于包的根目录与 index.js 同级,则可以省略 types 字段,但建议保持良好的声明式习惯

参阅 TypeScript | Docs

main

string 标准化的工具包主入口

默认为 index.js ,主要用于 Node.jscjs 模块

js
const foo = require('foo') // => from "main" field
 // foo => { value: 1 }
js
// foo.cjs
 module.exports = {
   value: 1,
@@ -115,7 +115,7 @@ import{_ as t,h as r,l as a,e as i,I as e,b as l,a8 as p,C as h,o as k}from"./ch
       }
     }
   }
-}

脚本配置

scripts

Record<string, string> 带有以下默认生命周期的脚本命令: <pre> | <post>

  • install
  • uninstall
  • start
  • restart
  • stop
  • test
  • pack
  • publish
  • 自定义脚本命令

特殊的 prepareprepublishOnlyscripts 文档

TIP

在 pnpm@6 与 yarn2 中, preinstall 将在 install 后执行,而不是在 install 之前

为此 pnpm 提供了 pnpm:devPreinstall 钩子以兼容开发者的使用习惯

config

Record<string, string> process.env 配置命令行的环境变量

js
#!/usr/bin/env node
+}

脚本配置

scripts

Record<string, string> 带有以下默认生命周期的脚本命令: <pre> | <post>

  • install
  • uninstall
  • start
  • restart
  • stop
  • test
  • pack
  • publish
  • 自定义脚本命令

特殊的 prepareprepublishOnlyscripts 文档

TIP

在 pnpm@6 与 yarn2 中, preinstall 将在 install 后执行,而不是在 install 之前

为此 pnpm 提供了 pnpm:devPreinstall 钩子以兼容开发者的使用习惯

config

Record<string, string> process.env 配置命令行的环境变量

js
#!/usr/bin/env node
 
 console.log(process.env.npm_package_config_port) // 8732
 console.log(process.env.npm_package_config_foo) // bar
json
{
diff --git a/assets/fe_node_pkg.md.BKRyM3y-.lean.js b/assets/fe_node_pkg.md.DegpvfnG.lean.js
similarity index 98%
rename from assets/fe_node_pkg.md.BKRyM3y-.lean.js
rename to assets/fe_node_pkg.md.DegpvfnG.lean.js
index 9d9575444..f91373f8a 100644
--- a/assets/fe_node_pkg.md.BKRyM3y-.lean.js
+++ b/assets/fe_node_pkg.md.DegpvfnG.lean.js
@@ -37,7 +37,7 @@ import{_ as t,h as r,l as a,e as i,I as e,b as l,a8 as p,C as h,o as k}from"./ch
 // recommend
 {
   "licenses": "MIT"
-}

文件配置

type

'commonjs' | 'module' 表明包使用的模块语法( Node@14 以上版本支持 ES Module

  • 默认为 commonjs, 对于 mjs 后缀名文件采用 ESM 语法解析

  • 设置为 module 时,对于 cjs 后缀名文件采用 commonjs 语法解析

bin

string | { \${binName}: \${binFilePath} } 声明包的脚本文件

脚本文件一般在文件头以 SheBang 声明运行脚本的语言

sh
npm install demo -g
+}

文件配置

type

'commonjs' | 'module' 表明包使用的模块语法( Node@14 以上版本支持 ES Module

  • 默认为 commonjs, 对于 mjs 后缀名文件采用 ESM 语法解析

  • 设置为 module 时,对于 cjs 后缀名文件采用 commonjs 语法解析

bin

string | { \${binName}: \${binFilePath} } 声明包的脚本文件

脚本文件一般在文件头以 SheBang 声明运行脚本的语言

sh
npm install demo -g
 
 d
 # log: Npm is COOL
js
#!/usr/bin/env node
@@ -50,7 +50,7 @@ import{_ as t,h as r,l as a,e as i,I as e,b as l,a8 as p,C as h,o as k}from"./ch
 }
sh
.
 ├── bin
    └── demo.js
-└── package.json

files

Array<string> 指明将此项目作为依赖包安装时包含的文件,默认为排除以下文件的全部内容:

  • .git
  • CVS
  • .svn
  • .hg
  • .lock-wscript
  • .wafpickle-N
  • .*.swp
  • .DS_Store
  • ._*
  • npm-debug.log
  • .npmrc
  • node_modules
  • config.gypi
  • *.orig
  • package.json / npm-shrinkwrap.json

TIP

files 字段作用类似的还有 .npmignore.gitignore

files 类似于白名单,往往产物内容更少更方便。而 ignore 文件类似于黑名单,需要开发者持续维护

types

string => filePath 声明此项目的 TypeScript 类型文件

TIP

  • typestypings 意义完全相同,可替换使用
  • 当主声明文件命名为 index.d.ts,并且位于包的根目录与 index.js 同级,则可以省略 types 字段,但建议保持良好的声明式习惯

参阅 TypeScript | Docs

main

string 标准化的工具包主入口

默认为 index.js ,主要用于 Node.jscjs 模块

js
const foo = require('foo') // => from "main" field
+└── package.json

files

Array<string> 指明将此项目作为依赖包安装时包含的文件,默认为排除以下文件的全部内容:

  • .git
  • CVS
  • .svn
  • .hg
  • .lock-wscript
  • .wafpickle-N
  • .*.swp
  • .DS_Store
  • ._*
  • npm-debug.log
  • .npmrc
  • node_modules
  • config.gypi
  • *.orig
  • package.json / npm-shrinkwrap.json

TIP

files 字段作用类似的还有 .npmignore.gitignore

files 类似于白名单,往往产物内容更少更方便。而 ignore 文件类似于黑名单,需要开发者持续维护

types

string => filePath 声明此项目的 TypeScript 类型文件

TIP

  • typestypings 意义完全相同,可替换使用
  • 当主声明文件命名为 index.d.ts,并且位于包的根目录与 index.js 同级,则可以省略 types 字段,但建议保持良好的声明式习惯

参阅 TypeScript | Docs

main

string 标准化的工具包主入口

默认为 index.js ,主要用于 Node.jscjs 模块

js
const foo = require('foo') // => from "main" field
 // foo => { value: 1 }
js
// foo.cjs
 module.exports = {
   value: 1,
@@ -115,7 +115,7 @@ import{_ as t,h as r,l as a,e as i,I as e,b as l,a8 as p,C as h,o as k}from"./ch
       }
     }
   }
-}

脚本配置

scripts

Record<string, string> 带有以下默认生命周期的脚本命令: <pre> | <post>

  • install
  • uninstall
  • start
  • restart
  • stop
  • test
  • pack
  • publish
  • 自定义脚本命令

特殊的 prepareprepublishOnlyscripts 文档

TIP

在 pnpm@6 与 yarn2 中, preinstall 将在 install 后执行,而不是在 install 之前

为此 pnpm 提供了 pnpm:devPreinstall 钩子以兼容开发者的使用习惯

config

Record<string, string> process.env 配置命令行的环境变量

js
#!/usr/bin/env node
+}

脚本配置

scripts

Record<string, string> 带有以下默认生命周期的脚本命令: <pre> | <post>

  • install
  • uninstall
  • start
  • restart
  • stop
  • test
  • pack
  • publish
  • 自定义脚本命令

特殊的 prepareprepublishOnlyscripts 文档

TIP

在 pnpm@6 与 yarn2 中, preinstall 将在 install 后执行,而不是在 install 之前

为此 pnpm 提供了 pnpm:devPreinstall 钩子以兼容开发者的使用习惯

config

Record<string, string> process.env 配置命令行的环境变量

js
#!/usr/bin/env node
 
 console.log(process.env.npm_package_config_port) // 8732
 console.log(process.env.npm_package_config_foo) // bar
json
{
diff --git a/assets/pit_editor.md.Dor5Xkgu.js b/assets/pit_editor.md.ajctGNTx.js
similarity index 95%
rename from assets/pit_editor.md.Dor5Xkgu.js
rename to assets/pit_editor.md.ajctGNTx.js
index c24596c44..cfaa20a7a 100644
--- a/assets/pit_editor.md.Dor5Xkgu.js
+++ b/assets/pit_editor.md.ajctGNTx.js
@@ -1 +1 @@
-import{_ as i,h as e,a8 as a,o as t}from"./chunks/framework.BU7NHiAd.js";const k=JSON.parse('{"title":"编辑器踩坑记录","description":"记录个人遇到或他人分享的编辑器相关踩坑记录","frontmatter":{"description":"记录个人遇到或他人分享的编辑器相关踩坑记录"},"headers":[],"relativePath":"pit/editor.md","filePath":"pit/editor.md","lastUpdated":1715327095000}'),o={name:"pit/editor.md"};function n(d,s,l,p,h,c){return t(),e("div",null,s[0]||(s[0]=[a('

编辑器踩坑记录

在 VSCode 使用 GUI 时提示 xxx: command not found

husky 为例

在 VSCode 中使用 GUI(源代码管理 - 输入框)进行 git commit 时,提示 Git: .husky/commit-msg: line 4: npx: command not found

原因

  1. 使用了 fnmnvm 存在了多个版本的 Node.js
  2. 在终端外部启动的 GUI 不会初始化 Node.js,导致 $PATH 中没有 Node.js
  3. 当使用 VSCode GUI 时,就会导致 Node.js 相关的命令丢失

解决方法

一共有如下几种方案

  1. 通过 VSCode 的 code 命令打开编辑器(使用命令行进入到项目目录 code .
  2. 添加 ~/.config/husky/init.sh~/.huskyrc 文件(内容如下)

~/.huskyrc 高版本已弃用

bash
eval "$(fnm env --use-on-cd)"
bash
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"

shell 启动文件快速且轻量级时可直接在 ~/.config/husky/init.sh~/.huskyrc 配置如下

Oh My ZSH: 你们针对我?

sh
. ~/.zshrc
',14)]))}const u=i(o,[["render",n]]);export{k as __pageData,u as default}; +import{_ as i,h as e,a8 as a,o as t}from"./chunks/framework.BU7NHiAd.js";const k=JSON.parse('{"title":"编辑器踩坑记录","description":"记录个人遇到或他人分享的编辑器相关踩坑记录","frontmatter":{"description":"记录个人遇到或他人分享的编辑器相关踩坑记录"},"headers":[],"relativePath":"pit/editor.md","filePath":"pit/editor.md","lastUpdated":1715327095000}'),o={name:"pit/editor.md"};function n(d,s,l,p,h,c){return t(),e("div",null,s[0]||(s[0]=[a('

编辑器踩坑记录

在 VSCode 使用 GUI 时提示 xxx: command not found

husky 为例

在 VSCode 中使用 GUI(源代码管理 - 输入框)进行 git commit 时,提示 Git: .husky/commit-msg: line 4: npx: command not found

原因

  1. 使用了 fnmnvm 存在了多个版本的 Node.js
  2. 在终端外部启动的 GUI 不会初始化 Node.js,导致 $PATH 中没有 Node.js
  3. 当使用 VSCode GUI 时,就会导致 Node.js 相关的命令丢失

解决方法

一共有如下几种方案

  1. 通过 VSCode 的 code 命令打开编辑器(使用命令行进入到项目目录 code .
  2. 添加 ~/.config/husky/init.sh~/.huskyrc 文件(内容如下)

~/.huskyrc 高版本已弃用

bash
eval "$(fnm env --use-on-cd)"
bash
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"

shell 启动文件快速且轻量级时可直接在 ~/.config/husky/init.sh~/.huskyrc 配置如下

Oh My ZSH: 你们针对我?

sh
. ~/.zshrc
',14)]))}const u=i(o,[["render",n]]);export{k as __pageData,u as default}; diff --git a/assets/pit_editor.md.Dor5Xkgu.lean.js b/assets/pit_editor.md.ajctGNTx.lean.js similarity index 95% rename from assets/pit_editor.md.Dor5Xkgu.lean.js rename to assets/pit_editor.md.ajctGNTx.lean.js index c24596c44..cfaa20a7a 100644 --- a/assets/pit_editor.md.Dor5Xkgu.lean.js +++ b/assets/pit_editor.md.ajctGNTx.lean.js @@ -1 +1 @@ -import{_ as i,h as e,a8 as a,o as t}from"./chunks/framework.BU7NHiAd.js";const k=JSON.parse('{"title":"编辑器踩坑记录","description":"记录个人遇到或他人分享的编辑器相关踩坑记录","frontmatter":{"description":"记录个人遇到或他人分享的编辑器相关踩坑记录"},"headers":[],"relativePath":"pit/editor.md","filePath":"pit/editor.md","lastUpdated":1715327095000}'),o={name:"pit/editor.md"};function n(d,s,l,p,h,c){return t(),e("div",null,s[0]||(s[0]=[a('

编辑器踩坑记录

在 VSCode 使用 GUI 时提示 xxx: command not found

husky 为例

在 VSCode 中使用 GUI(源代码管理 - 输入框)进行 git commit 时,提示 Git: .husky/commit-msg: line 4: npx: command not found

原因

  1. 使用了 fnmnvm 存在了多个版本的 Node.js
  2. 在终端外部启动的 GUI 不会初始化 Node.js,导致 $PATH 中没有 Node.js
  3. 当使用 VSCode GUI 时,就会导致 Node.js 相关的命令丢失

解决方法

一共有如下几种方案

  1. 通过 VSCode 的 code 命令打开编辑器(使用命令行进入到项目目录 code .
  2. 添加 ~/.config/husky/init.sh~/.huskyrc 文件(内容如下)

~/.huskyrc 高版本已弃用

bash
eval "$(fnm env --use-on-cd)"
bash
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"

shell 启动文件快速且轻量级时可直接在 ~/.config/husky/init.sh~/.huskyrc 配置如下

Oh My ZSH: 你们针对我?

sh
. ~/.zshrc
',14)]))}const u=i(o,[["render",n]]);export{k as __pageData,u as default}; +import{_ as i,h as e,a8 as a,o as t}from"./chunks/framework.BU7NHiAd.js";const k=JSON.parse('{"title":"编辑器踩坑记录","description":"记录个人遇到或他人分享的编辑器相关踩坑记录","frontmatter":{"description":"记录个人遇到或他人分享的编辑器相关踩坑记录"},"headers":[],"relativePath":"pit/editor.md","filePath":"pit/editor.md","lastUpdated":1715327095000}'),o={name:"pit/editor.md"};function n(d,s,l,p,h,c){return t(),e("div",null,s[0]||(s[0]=[a('

编辑器踩坑记录

在 VSCode 使用 GUI 时提示 xxx: command not found

husky 为例

在 VSCode 中使用 GUI(源代码管理 - 输入框)进行 git commit 时,提示 Git: .husky/commit-msg: line 4: npx: command not found

原因

  1. 使用了 fnmnvm 存在了多个版本的 Node.js
  2. 在终端外部启动的 GUI 不会初始化 Node.js,导致 $PATH 中没有 Node.js
  3. 当使用 VSCode GUI 时,就会导致 Node.js 相关的命令丢失

解决方法

一共有如下几种方案

  1. 通过 VSCode 的 code 命令打开编辑器(使用命令行进入到项目目录 code .
  2. 添加 ~/.config/husky/init.sh~/.huskyrc 文件(内容如下)

~/.huskyrc 高版本已弃用

bash
eval "$(fnm env --use-on-cd)"
bash
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"

shell 启动文件快速且轻量级时可直接在 ~/.config/husky/init.sh~/.huskyrc 配置如下

Oh My ZSH: 你们针对我?

sh
. ~/.zshrc
',14)]))}const u=i(o,[["render",n]]);export{k as __pageData,u as default}; diff --git a/assets/workflow_library_dayjs.md.C7eBLzYu.js b/assets/workflow_library_dayjs.md.CxZPm0C6.js similarity index 95% rename from assets/workflow_library_dayjs.md.C7eBLzYu.js rename to assets/workflow_library_dayjs.md.CxZPm0C6.js index bab74513c..6ab277376 100644 --- a/assets/workflow_library_dayjs.md.C7eBLzYu.js +++ b/assets/workflow_library_dayjs.md.CxZPm0C6.js @@ -1,4 +1,4 @@ -import{V as rs}from"./chunks/vmp_components.DSwsTOIt.js";import{q as ss,x as Es,y as ds,o as ts,h as ls,l as s,f as z,e as l,F as ys,a8 as is,I as as,b as ns,g as gs}from"./chunks/framework.BU7NHiAd.js";var hs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ks(O){return O&&O.__esModule&&Object.prototype.hasOwnProperty.call(O,"default")?O.default:O}var es={exports:{}};(function(O,W){(function(F,u){O.exports=u()})(hs,function(){var F=1e3,u=6e4,_=36e5,m="millisecond",v="second",H="minute",Y="hour",$="day",T="week",A="month",L="quarter",w="year",M="date",q="Invalid Date",X=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,x=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,K={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(h){var n=["th","st","nd","rd"],i=h%100;return"["+h+(n[(i-20)%10]||n[i]||n[0])+"]"}},S=function(h,n,i){var k=String(h);return!k||k.length>=n?h:""+Array(n+1-k.length).join(i)+h},Q={s:S,z:function(h){var n=-h.utcOffset(),i=Math.abs(n),k=Math.floor(i/60),a=i%60;return(n<=0?"+":"-")+S(k,2,"0")+":"+S(a,2,"0")},m:function h(n,i){if(n.date()1)return h(E[0])}else{var c=n.name;y[c]=n,a=c}return!k&&a&&(P=a),a||!k&&P},d=function(h,n){if(t(h))return h.clone();var i=typeof n=="object"?n:{};return i.date=h,i.args=arguments,new b(i)},p=Q;p.l=g,p.i=t,p.w=function(h,n){return d(h,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var b=function(){function h(i){this.$L=g(i.locale,null,!0),this.parse(i),this.$x=this.$x||i.x||{},this[e]=!0}var n=h.prototype;return n.parse=function(i){this.$d=function(k){var a=k.date,r=k.utc;if(a===null)return new Date(NaN);if(p.u(a))return new Date;if(a instanceof Date)return new Date(a);if(typeof a=="string"&&!/Z$/i.test(a)){var E=a.match(X);if(E){var c=E[2]-1||0,o=(E[7]||"0").substring(0,3);return r?new Date(Date.UTC(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)):new Date(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)}}return new Date(a)}(i),this.init()},n.init=function(){var i=this.$d;this.$y=i.getFullYear(),this.$M=i.getMonth(),this.$D=i.getDate(),this.$W=i.getDay(),this.$H=i.getHours(),this.$m=i.getMinutes(),this.$s=i.getSeconds(),this.$ms=i.getMilliseconds()},n.$utils=function(){return p},n.isValid=function(){return this.$d.toString()!==q},n.isSame=function(i,k){var a=d(i);return this.startOf(k)<=a&&a<=this.endOf(k)},n.isAfter=function(i,k){return d(i){const _=G(),v=G().endOf("D").diff(_);if(v<=0){cancelAnimationFrame(W.value);return}F.value=G.duration(v),W.value=requestAnimationFrame(u)};return Es(()=>{W.value=requestAnimationFrame(u)}),ds(()=>{cancelAnimationFrame(W.value)}),(_,m)=>(ts(),ls(ys,null,[s("div",os,[m[0]||(m[0]=s("div",{class:"w-36"},"使用 format 方法:",-1)),s("div",ms,[s("div",{class:"countdown",innerHTML:F.value.format("[]HH[] 时 []mm[] 分 []ss[] 秒")},null,8,bs),s("div",Cs,z(F.value.format("D 天 HH 时 mm 分 ss 秒")),1),s("div",fs,z(F.value.format("DD : HH : mm : ss")),1),s("div",Bs,z(F.value.format("HH-mm-ss")),1)])]),s("div",Ds,[m[4]||(m[4]=s("div",{class:"w-36"},"使用取值方法:",-1)),s("div",vs,[s("span",null,z(F.value.hours()),1),m[1]||(m[1]=l(" 时 ")),s("span",null,z(F.value.minutes()),1),m[2]||(m[2]=l(" 分 ")),s("span",null,z(F.value.seconds()),1),m[3]||(m[3]=l(" 秒 ")),s("span",null,z(F.value.milliseconds()),1)])])],64))}},js=JSON.parse('{"title":"Day.js 使用技巧","description":"","frontmatter":{},"headers":[],"relativePath":"workflow/library/dayjs.md","filePath":"workflow/library/dayjs.md","lastUpdated":1702913488000}'),ws={name:"workflow/library/dayjs.md"},Os=Object.assign(ws,{setup(O){return(W,F)=>(ts(),ls("div",null,[F[1]||(F[1]=is(`

Day.js 使用技巧

使用 Day.js 实现倒计时

js
import dayjs from 'dayjs'
+import{V as rs}from"./chunks/vmp_components.DSwsTOIt.js";import{q as ss,x as Es,y as ds,o as ts,h as ls,l as s,f as V,e as l,F as ys,a8 as is,I as as,b as ns,g as gs}from"./chunks/framework.BU7NHiAd.js";var hs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ks(O){return O&&O.__esModule&&Object.prototype.hasOwnProperty.call(O,"default")?O.default:O}var es={exports:{}};(function(O,L){(function(F,u){O.exports=u()})(hs,function(){var F=1e3,u=6e4,_=36e5,m="millisecond",v="second",H="minute",Y="hour",$="day",T="week",A="month",N="quarter",w="year",M="date",q="Invalid Date",Q=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,x=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,X={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(h){var n=["th","st","nd","rd"],i=h%100;return"["+h+(n[(i-20)%10]||n[i]||n[0])+"]"}},S=function(h,n,i){var k=String(h);return!k||k.length>=n?h:""+Array(n+1-k.length).join(i)+h},R={s:S,z:function(h){var n=-h.utcOffset(),i=Math.abs(n),k=Math.floor(i/60),a=i%60;return(n<=0?"+":"-")+S(k,2,"0")+":"+S(a,2,"0")},m:function h(n,i){if(n.date()1)return h(E[0])}else{var c=n.name;y[c]=n,a=c}return!k&&a&&(P=a),a||!k&&P},d=function(h,n){if(t(h))return h.clone();var i=typeof n=="object"?n:{};return i.date=h,i.args=arguments,new b(i)},p=R;p.l=g,p.i=t,p.w=function(h,n){return d(h,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var b=function(){function h(i){this.$L=g(i.locale,null,!0),this.parse(i),this.$x=this.$x||i.x||{},this[e]=!0}var n=h.prototype;return n.parse=function(i){this.$d=function(k){var a=k.date,r=k.utc;if(a===null)return new Date(NaN);if(p.u(a))return new Date;if(a instanceof Date)return new Date(a);if(typeof a=="string"&&!/Z$/i.test(a)){var E=a.match(Q);if(E){var c=E[2]-1||0,o=(E[7]||"0").substring(0,3);return r?new Date(Date.UTC(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)):new Date(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)}}return new Date(a)}(i),this.init()},n.init=function(){var i=this.$d;this.$y=i.getFullYear(),this.$M=i.getMonth(),this.$D=i.getDate(),this.$W=i.getDay(),this.$H=i.getHours(),this.$m=i.getMinutes(),this.$s=i.getSeconds(),this.$ms=i.getMilliseconds()},n.$utils=function(){return p},n.isValid=function(){return this.$d.toString()!==q},n.isSame=function(i,k){var a=d(i);return this.startOf(k)<=a&&a<=this.endOf(k)},n.isAfter=function(i,k){return d(i){const _=G(),v=G().endOf("D").diff(_);if(v<=0){cancelAnimationFrame(L.value);return}F.value=G.duration(v),L.value=requestAnimationFrame(u)};return Es(()=>{L.value=requestAnimationFrame(u)}),ds(()=>{cancelAnimationFrame(L.value)}),(_,m)=>(ts(),ls(ys,null,[s("div",os,[m[0]||(m[0]=s("div",{class:"w-36"},"使用 format 方法:",-1)),s("div",ms,[s("div",{class:"countdown",innerHTML:F.value.format("[]HH[] 时 []mm[] 分 []ss[] 秒")},null,8,bs),s("div",Cs,V(F.value.format("D 天 HH 时 mm 分 ss 秒")),1),s("div",fs,V(F.value.format("DD : HH : mm : ss")),1),s("div",Bs,V(F.value.format("HH-mm-ss")),1)])]),s("div",Ds,[m[4]||(m[4]=s("div",{class:"w-36"},"使用取值方法:",-1)),s("div",vs,[s("span",null,V(F.value.hours()),1),m[1]||(m[1]=l(" 时 ")),s("span",null,V(F.value.minutes()),1),m[2]||(m[2]=l(" 分 ")),s("span",null,V(F.value.seconds()),1),m[3]||(m[3]=l(" 秒 ")),s("span",null,V(F.value.milliseconds()),1)])])],64))}},js=JSON.parse('{"title":"Day.js 使用技巧","description":"","frontmatter":{},"headers":[],"relativePath":"workflow/library/dayjs.md","filePath":"workflow/library/dayjs.md","lastUpdated":1702913488000}'),ws={name:"workflow/library/dayjs.md"},Os=Object.assign(ws,{setup(O){return(L,F)=>(ts(),ls("div",null,[F[1]||(F[1]=is(`

Day.js 使用技巧

使用 Day.js 实现倒计时

js
import dayjs from 'dayjs'
 import duration from 'dayjs/plugin/duration'
 
 // 配置 duration 插件
@@ -80,7 +80,7 @@ import{V as rs}from"./chunks/vmp_components.DSwsTOIt.js";import{q as ss,x as Es,
 `),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"      <"),s("span",{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"}},"span"),s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},">{{ count.milliseconds() }}")]),l(`
 `),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"    ")]),l(`
 `),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"  ")]),l(`
-`),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"")])])]),s("div",{class:"line-numbers-wrapper","aria-hidden":"true"},[s("span",{class:"line-number"},"1"),s("br"),s("span",{class:"line-number"},"2"),s("br"),s("span",{class:"line-number"},"3"),s("br"),s("span",{class:"line-number"},"4"),s("br"),s("span",{class:"line-number"},"5"),s("br"),s("span",{class:"line-number"},"6"),s("br"),s("span",{class:"line-number"},"7"),s("br"),s("span",{class:"line-number"},"8"),s("br"),s("span",{class:"line-number"},"9"),s("br"),s("span",{class:"line-number"},"10"),s("br"),s("span",{class:"line-number"},"11"),s("br"),s("span",{class:"line-number"},"12"),s("br"),s("span",{class:"line-number"},"13"),s("br"),s("span",{class:"line-number"},"14"),s("br"),s("span",{class:"line-number"},"15"),s("br"),s("span",{class:"line-number"},"16"),s("br"),s("span",{class:"line-number"},"17"),s("br"),s("span",{class:"line-number"},"18"),s("br"),s("span",{class:"line-number"},"19"),s("br"),s("span",{class:"line-number"},"20"),s("br"),s("span",{class:"line-number"},"21"),s("br"),s("span",{class:"line-number"},"22"),s("br"),s("span",{class:"line-number"},"23"),s("br"),s("span",{class:"line-number"},"24"),s("br"),s("span",{class:"line-number"},"25"),s("br"),s("span",{class:"line-number"},"26"),s("br"),s("span",{class:"line-number"},"27"),s("br"),s("span",{class:"line-number"},"28"),s("br"),s("span",{class:"line-number"},"29"),s("br"),s("span",{class:"line-number"},"30"),s("br"),s("span",{class:"line-number"},"31"),s("br"),s("span",{class:"line-number"},"32"),s("br"),s("span",{class:"line-number"},"33"),s("br"),s("span",{class:"line-number"},"34"),s("br"),s("span",{class:"line-number"},"35"),s("br"),s("span",{class:"line-number"},"36"),s("br"),s("span",{class:"line-number"},"37"),s("br"),s("span",{class:"line-number"},"38"),s("br"),s("span",{class:"line-number"},"39"),s("br"),s("span",{class:"line-number"},"40"),s("br"),s("span",{class:"line-number"},"41"),s("br"),s("span",{class:"line-number"},"42"),s("br"),s("span",{class:"line-number"},"43"),s("br"),s("span",{class:"line-number"},"44"),s("br"),s("span",{class:"line-number"},"45"),s("br"),s("span",{class:"line-number"},"46"),s("br"),s("span",{class:"line-number"},"47"),s("br"),s("span",{class:"line-number"},"48"),s("br"),s("span",{class:"line-number"},"49"),s("br"),s("span",{class:"line-number"},"50"),s("br"),s("span",{class:"line-number"},"51"),s("br"),s("span",{class:"line-number"},"52"),s("br"),s("span",{class:"line-number"},"53"),s("br"),s("span",{class:"line-number"},"54"),s("br"),s("span",{class:"line-number"},"55"),s("br"),s("span",{class:"line-number"},"56"),s("br"),s("span",{class:"line-number"},"57"),s("br"),s("span",{class:"line-number"},"58"),s("br"),s("span",{class:"line-number"},"59"),s("br"),s("span",{class:"line-number"},"60"),s("br"),s("span",{class:"line-number"},"61"),s("br"),s("span",{class:"line-number"},"62"),s("br")])],-1)])),default:ns(()=>[as(As)]),_:1}),F[2]||(F[2]=is(`

优点

  • 使用 Day.js 对象的 format 方法进行格式化
    • 无需自己实现格式化函数
    • 个位数时都不需要字符串补位操作
    • 在使用 format 时,在方括号中的字符不会被格式化替换
  • 兼容性良好

缺点

当需求场景超出 Day.js 对象的 format 方法的能力时(即不是标准的年月日时分秒格式)需要自己实现格式化函数

  • 40 天 13 时 14 分 00 秒
  • 52 时 13 分 14 秒
  • 100 分 50 秒

常用预设范围

常用于 antdRangePicker 组件

js
import dayjs from 'dayjs'
+`),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"")])])]),s("div",{class:"line-numbers-wrapper","aria-hidden":"true"},[s("span",{class:"line-number"},"1"),s("br"),s("span",{class:"line-number"},"2"),s("br"),s("span",{class:"line-number"},"3"),s("br"),s("span",{class:"line-number"},"4"),s("br"),s("span",{class:"line-number"},"5"),s("br"),s("span",{class:"line-number"},"6"),s("br"),s("span",{class:"line-number"},"7"),s("br"),s("span",{class:"line-number"},"8"),s("br"),s("span",{class:"line-number"},"9"),s("br"),s("span",{class:"line-number"},"10"),s("br"),s("span",{class:"line-number"},"11"),s("br"),s("span",{class:"line-number"},"12"),s("br"),s("span",{class:"line-number"},"13"),s("br"),s("span",{class:"line-number"},"14"),s("br"),s("span",{class:"line-number"},"15"),s("br"),s("span",{class:"line-number"},"16"),s("br"),s("span",{class:"line-number"},"17"),s("br"),s("span",{class:"line-number"},"18"),s("br"),s("span",{class:"line-number"},"19"),s("br"),s("span",{class:"line-number"},"20"),s("br"),s("span",{class:"line-number"},"21"),s("br"),s("span",{class:"line-number"},"22"),s("br"),s("span",{class:"line-number"},"23"),s("br"),s("span",{class:"line-number"},"24"),s("br"),s("span",{class:"line-number"},"25"),s("br"),s("span",{class:"line-number"},"26"),s("br"),s("span",{class:"line-number"},"27"),s("br"),s("span",{class:"line-number"},"28"),s("br"),s("span",{class:"line-number"},"29"),s("br"),s("span",{class:"line-number"},"30"),s("br"),s("span",{class:"line-number"},"31"),s("br"),s("span",{class:"line-number"},"32"),s("br"),s("span",{class:"line-number"},"33"),s("br"),s("span",{class:"line-number"},"34"),s("br"),s("span",{class:"line-number"},"35"),s("br"),s("span",{class:"line-number"},"36"),s("br"),s("span",{class:"line-number"},"37"),s("br"),s("span",{class:"line-number"},"38"),s("br"),s("span",{class:"line-number"},"39"),s("br"),s("span",{class:"line-number"},"40"),s("br"),s("span",{class:"line-number"},"41"),s("br"),s("span",{class:"line-number"},"42"),s("br"),s("span",{class:"line-number"},"43"),s("br"),s("span",{class:"line-number"},"44"),s("br"),s("span",{class:"line-number"},"45"),s("br"),s("span",{class:"line-number"},"46"),s("br"),s("span",{class:"line-number"},"47"),s("br"),s("span",{class:"line-number"},"48"),s("br"),s("span",{class:"line-number"},"49"),s("br"),s("span",{class:"line-number"},"50"),s("br"),s("span",{class:"line-number"},"51"),s("br"),s("span",{class:"line-number"},"52"),s("br"),s("span",{class:"line-number"},"53"),s("br"),s("span",{class:"line-number"},"54"),s("br"),s("span",{class:"line-number"},"55"),s("br"),s("span",{class:"line-number"},"56"),s("br"),s("span",{class:"line-number"},"57"),s("br"),s("span",{class:"line-number"},"58"),s("br"),s("span",{class:"line-number"},"59"),s("br"),s("span",{class:"line-number"},"60"),s("br"),s("span",{class:"line-number"},"61"),s("br"),s("span",{class:"line-number"},"62"),s("br")])],-1)])),default:ns(()=>[as(As)]),_:1}),F[2]||(F[2]=is(`

优点

  • 使用 Day.js 对象的 format 方法进行格式化
    • 无需自己实现格式化函数
    • 个位数时都不需要字符串补位操作
    • 在使用 format 时,在方括号中的字符不会被格式化替换
  • 兼容性良好

缺点

当需求场景超出 Day.js 对象的 format 方法的能力时(即不是标准的年月日时分秒格式)需要自己实现格式化函数

  • 40 天 13 时 14 分 00 秒
  • 52 时 13 分 14 秒
  • 100 分 50 秒

常用预设范围

常用于 antdRangePicker 组件

js
import dayjs from 'dayjs'
 
 // 获取当前的时间
 const now = dayjs()
diff --git a/assets/workflow_library_dayjs.md.C7eBLzYu.lean.js b/assets/workflow_library_dayjs.md.CxZPm0C6.lean.js
similarity index 95%
rename from assets/workflow_library_dayjs.md.C7eBLzYu.lean.js
rename to assets/workflow_library_dayjs.md.CxZPm0C6.lean.js
index bab74513c..6ab277376 100644
--- a/assets/workflow_library_dayjs.md.C7eBLzYu.lean.js
+++ b/assets/workflow_library_dayjs.md.CxZPm0C6.lean.js
@@ -1,4 +1,4 @@
-import{V as rs}from"./chunks/vmp_components.DSwsTOIt.js";import{q as ss,x as Es,y as ds,o as ts,h as ls,l as s,f as z,e as l,F as ys,a8 as is,I as as,b as ns,g as gs}from"./chunks/framework.BU7NHiAd.js";var hs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ks(O){return O&&O.__esModule&&Object.prototype.hasOwnProperty.call(O,"default")?O.default:O}var es={exports:{}};(function(O,W){(function(F,u){O.exports=u()})(hs,function(){var F=1e3,u=6e4,_=36e5,m="millisecond",v="second",H="minute",Y="hour",$="day",T="week",A="month",L="quarter",w="year",M="date",q="Invalid Date",X=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,x=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,K={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(h){var n=["th","st","nd","rd"],i=h%100;return"["+h+(n[(i-20)%10]||n[i]||n[0])+"]"}},S=function(h,n,i){var k=String(h);return!k||k.length>=n?h:""+Array(n+1-k.length).join(i)+h},Q={s:S,z:function(h){var n=-h.utcOffset(),i=Math.abs(n),k=Math.floor(i/60),a=i%60;return(n<=0?"+":"-")+S(k,2,"0")+":"+S(a,2,"0")},m:function h(n,i){if(n.date()1)return h(E[0])}else{var c=n.name;y[c]=n,a=c}return!k&&a&&(P=a),a||!k&&P},d=function(h,n){if(t(h))return h.clone();var i=typeof n=="object"?n:{};return i.date=h,i.args=arguments,new b(i)},p=Q;p.l=g,p.i=t,p.w=function(h,n){return d(h,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var b=function(){function h(i){this.$L=g(i.locale,null,!0),this.parse(i),this.$x=this.$x||i.x||{},this[e]=!0}var n=h.prototype;return n.parse=function(i){this.$d=function(k){var a=k.date,r=k.utc;if(a===null)return new Date(NaN);if(p.u(a))return new Date;if(a instanceof Date)return new Date(a);if(typeof a=="string"&&!/Z$/i.test(a)){var E=a.match(X);if(E){var c=E[2]-1||0,o=(E[7]||"0").substring(0,3);return r?new Date(Date.UTC(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)):new Date(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)}}return new Date(a)}(i),this.init()},n.init=function(){var i=this.$d;this.$y=i.getFullYear(),this.$M=i.getMonth(),this.$D=i.getDate(),this.$W=i.getDay(),this.$H=i.getHours(),this.$m=i.getMinutes(),this.$s=i.getSeconds(),this.$ms=i.getMilliseconds()},n.$utils=function(){return p},n.isValid=function(){return this.$d.toString()!==q},n.isSame=function(i,k){var a=d(i);return this.startOf(k)<=a&&a<=this.endOf(k)},n.isAfter=function(i,k){return d(i){const _=G(),v=G().endOf("D").diff(_);if(v<=0){cancelAnimationFrame(W.value);return}F.value=G.duration(v),W.value=requestAnimationFrame(u)};return Es(()=>{W.value=requestAnimationFrame(u)}),ds(()=>{cancelAnimationFrame(W.value)}),(_,m)=>(ts(),ls(ys,null,[s("div",os,[m[0]||(m[0]=s("div",{class:"w-36"},"使用 format 方法:",-1)),s("div",ms,[s("div",{class:"countdown",innerHTML:F.value.format("[]HH[] 时 []mm[] 分 []ss[] 秒")},null,8,bs),s("div",Cs,z(F.value.format("D 天 HH 时 mm 分 ss 秒")),1),s("div",fs,z(F.value.format("DD : HH : mm : ss")),1),s("div",Bs,z(F.value.format("HH-mm-ss")),1)])]),s("div",Ds,[m[4]||(m[4]=s("div",{class:"w-36"},"使用取值方法:",-1)),s("div",vs,[s("span",null,z(F.value.hours()),1),m[1]||(m[1]=l(" 时 ")),s("span",null,z(F.value.minutes()),1),m[2]||(m[2]=l(" 分 ")),s("span",null,z(F.value.seconds()),1),m[3]||(m[3]=l(" 秒 ")),s("span",null,z(F.value.milliseconds()),1)])])],64))}},js=JSON.parse('{"title":"Day.js 使用技巧","description":"","frontmatter":{},"headers":[],"relativePath":"workflow/library/dayjs.md","filePath":"workflow/library/dayjs.md","lastUpdated":1702913488000}'),ws={name:"workflow/library/dayjs.md"},Os=Object.assign(ws,{setup(O){return(W,F)=>(ts(),ls("div",null,[F[1]||(F[1]=is(`

Day.js 使用技巧

使用 Day.js 实现倒计时

js
import dayjs from 'dayjs'
+import{V as rs}from"./chunks/vmp_components.DSwsTOIt.js";import{q as ss,x as Es,y as ds,o as ts,h as ls,l as s,f as V,e as l,F as ys,a8 as is,I as as,b as ns,g as gs}from"./chunks/framework.BU7NHiAd.js";var hs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ks(O){return O&&O.__esModule&&Object.prototype.hasOwnProperty.call(O,"default")?O.default:O}var es={exports:{}};(function(O,L){(function(F,u){O.exports=u()})(hs,function(){var F=1e3,u=6e4,_=36e5,m="millisecond",v="second",H="minute",Y="hour",$="day",T="week",A="month",N="quarter",w="year",M="date",q="Invalid Date",Q=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,x=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,X={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(h){var n=["th","st","nd","rd"],i=h%100;return"["+h+(n[(i-20)%10]||n[i]||n[0])+"]"}},S=function(h,n,i){var k=String(h);return!k||k.length>=n?h:""+Array(n+1-k.length).join(i)+h},R={s:S,z:function(h){var n=-h.utcOffset(),i=Math.abs(n),k=Math.floor(i/60),a=i%60;return(n<=0?"+":"-")+S(k,2,"0")+":"+S(a,2,"0")},m:function h(n,i){if(n.date()1)return h(E[0])}else{var c=n.name;y[c]=n,a=c}return!k&&a&&(P=a),a||!k&&P},d=function(h,n){if(t(h))return h.clone();var i=typeof n=="object"?n:{};return i.date=h,i.args=arguments,new b(i)},p=R;p.l=g,p.i=t,p.w=function(h,n){return d(h,{locale:n.$L,utc:n.$u,x:n.$x,$offset:n.$offset})};var b=function(){function h(i){this.$L=g(i.locale,null,!0),this.parse(i),this.$x=this.$x||i.x||{},this[e]=!0}var n=h.prototype;return n.parse=function(i){this.$d=function(k){var a=k.date,r=k.utc;if(a===null)return new Date(NaN);if(p.u(a))return new Date;if(a instanceof Date)return new Date(a);if(typeof a=="string"&&!/Z$/i.test(a)){var E=a.match(Q);if(E){var c=E[2]-1||0,o=(E[7]||"0").substring(0,3);return r?new Date(Date.UTC(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)):new Date(E[1],c,E[3]||1,E[4]||0,E[5]||0,E[6]||0,o)}}return new Date(a)}(i),this.init()},n.init=function(){var i=this.$d;this.$y=i.getFullYear(),this.$M=i.getMonth(),this.$D=i.getDate(),this.$W=i.getDay(),this.$H=i.getHours(),this.$m=i.getMinutes(),this.$s=i.getSeconds(),this.$ms=i.getMilliseconds()},n.$utils=function(){return p},n.isValid=function(){return this.$d.toString()!==q},n.isSame=function(i,k){var a=d(i);return this.startOf(k)<=a&&a<=this.endOf(k)},n.isAfter=function(i,k){return d(i){const _=G(),v=G().endOf("D").diff(_);if(v<=0){cancelAnimationFrame(L.value);return}F.value=G.duration(v),L.value=requestAnimationFrame(u)};return Es(()=>{L.value=requestAnimationFrame(u)}),ds(()=>{cancelAnimationFrame(L.value)}),(_,m)=>(ts(),ls(ys,null,[s("div",os,[m[0]||(m[0]=s("div",{class:"w-36"},"使用 format 方法:",-1)),s("div",ms,[s("div",{class:"countdown",innerHTML:F.value.format("[]HH[] 时 []mm[] 分 []ss[] 秒")},null,8,bs),s("div",Cs,V(F.value.format("D 天 HH 时 mm 分 ss 秒")),1),s("div",fs,V(F.value.format("DD : HH : mm : ss")),1),s("div",Bs,V(F.value.format("HH-mm-ss")),1)])]),s("div",Ds,[m[4]||(m[4]=s("div",{class:"w-36"},"使用取值方法:",-1)),s("div",vs,[s("span",null,V(F.value.hours()),1),m[1]||(m[1]=l(" 时 ")),s("span",null,V(F.value.minutes()),1),m[2]||(m[2]=l(" 分 ")),s("span",null,V(F.value.seconds()),1),m[3]||(m[3]=l(" 秒 ")),s("span",null,V(F.value.milliseconds()),1)])])],64))}},js=JSON.parse('{"title":"Day.js 使用技巧","description":"","frontmatter":{},"headers":[],"relativePath":"workflow/library/dayjs.md","filePath":"workflow/library/dayjs.md","lastUpdated":1702913488000}'),ws={name:"workflow/library/dayjs.md"},Os=Object.assign(ws,{setup(O){return(L,F)=>(ts(),ls("div",null,[F[1]||(F[1]=is(`

Day.js 使用技巧

使用 Day.js 实现倒计时

js
import dayjs from 'dayjs'
 import duration from 'dayjs/plugin/duration'
 
 // 配置 duration 插件
@@ -80,7 +80,7 @@ import{V as rs}from"./chunks/vmp_components.DSwsTOIt.js";import{q as ss,x as Es,
 `),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"      <"),s("span",{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"}},"span"),s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},">{{ count.milliseconds() }}")]),l(`
 `),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"    ")]),l(`
 `),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"  ")]),l(`
-`),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"")])])]),s("div",{class:"line-numbers-wrapper","aria-hidden":"true"},[s("span",{class:"line-number"},"1"),s("br"),s("span",{class:"line-number"},"2"),s("br"),s("span",{class:"line-number"},"3"),s("br"),s("span",{class:"line-number"},"4"),s("br"),s("span",{class:"line-number"},"5"),s("br"),s("span",{class:"line-number"},"6"),s("br"),s("span",{class:"line-number"},"7"),s("br"),s("span",{class:"line-number"},"8"),s("br"),s("span",{class:"line-number"},"9"),s("br"),s("span",{class:"line-number"},"10"),s("br"),s("span",{class:"line-number"},"11"),s("br"),s("span",{class:"line-number"},"12"),s("br"),s("span",{class:"line-number"},"13"),s("br"),s("span",{class:"line-number"},"14"),s("br"),s("span",{class:"line-number"},"15"),s("br"),s("span",{class:"line-number"},"16"),s("br"),s("span",{class:"line-number"},"17"),s("br"),s("span",{class:"line-number"},"18"),s("br"),s("span",{class:"line-number"},"19"),s("br"),s("span",{class:"line-number"},"20"),s("br"),s("span",{class:"line-number"},"21"),s("br"),s("span",{class:"line-number"},"22"),s("br"),s("span",{class:"line-number"},"23"),s("br"),s("span",{class:"line-number"},"24"),s("br"),s("span",{class:"line-number"},"25"),s("br"),s("span",{class:"line-number"},"26"),s("br"),s("span",{class:"line-number"},"27"),s("br"),s("span",{class:"line-number"},"28"),s("br"),s("span",{class:"line-number"},"29"),s("br"),s("span",{class:"line-number"},"30"),s("br"),s("span",{class:"line-number"},"31"),s("br"),s("span",{class:"line-number"},"32"),s("br"),s("span",{class:"line-number"},"33"),s("br"),s("span",{class:"line-number"},"34"),s("br"),s("span",{class:"line-number"},"35"),s("br"),s("span",{class:"line-number"},"36"),s("br"),s("span",{class:"line-number"},"37"),s("br"),s("span",{class:"line-number"},"38"),s("br"),s("span",{class:"line-number"},"39"),s("br"),s("span",{class:"line-number"},"40"),s("br"),s("span",{class:"line-number"},"41"),s("br"),s("span",{class:"line-number"},"42"),s("br"),s("span",{class:"line-number"},"43"),s("br"),s("span",{class:"line-number"},"44"),s("br"),s("span",{class:"line-number"},"45"),s("br"),s("span",{class:"line-number"},"46"),s("br"),s("span",{class:"line-number"},"47"),s("br"),s("span",{class:"line-number"},"48"),s("br"),s("span",{class:"line-number"},"49"),s("br"),s("span",{class:"line-number"},"50"),s("br"),s("span",{class:"line-number"},"51"),s("br"),s("span",{class:"line-number"},"52"),s("br"),s("span",{class:"line-number"},"53"),s("br"),s("span",{class:"line-number"},"54"),s("br"),s("span",{class:"line-number"},"55"),s("br"),s("span",{class:"line-number"},"56"),s("br"),s("span",{class:"line-number"},"57"),s("br"),s("span",{class:"line-number"},"58"),s("br"),s("span",{class:"line-number"},"59"),s("br"),s("span",{class:"line-number"},"60"),s("br"),s("span",{class:"line-number"},"61"),s("br"),s("span",{class:"line-number"},"62"),s("br")])],-1)])),default:ns(()=>[as(As)]),_:1}),F[2]||(F[2]=is(`

优点

  • 使用 Day.js 对象的 format 方法进行格式化
    • 无需自己实现格式化函数
    • 个位数时都不需要字符串补位操作
    • 在使用 format 时,在方括号中的字符不会被格式化替换
  • 兼容性良好

缺点

当需求场景超出 Day.js 对象的 format 方法的能力时(即不是标准的年月日时分秒格式)需要自己实现格式化函数

  • 40 天 13 时 14 分 00 秒
  • 52 时 13 分 14 秒
  • 100 分 50 秒

常用预设范围

常用于 antdRangePicker 组件

js
import dayjs from 'dayjs'
+`),s("span",{class:"line"},[s("span",{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}},"")])])]),s("div",{class:"line-numbers-wrapper","aria-hidden":"true"},[s("span",{class:"line-number"},"1"),s("br"),s("span",{class:"line-number"},"2"),s("br"),s("span",{class:"line-number"},"3"),s("br"),s("span",{class:"line-number"},"4"),s("br"),s("span",{class:"line-number"},"5"),s("br"),s("span",{class:"line-number"},"6"),s("br"),s("span",{class:"line-number"},"7"),s("br"),s("span",{class:"line-number"},"8"),s("br"),s("span",{class:"line-number"},"9"),s("br"),s("span",{class:"line-number"},"10"),s("br"),s("span",{class:"line-number"},"11"),s("br"),s("span",{class:"line-number"},"12"),s("br"),s("span",{class:"line-number"},"13"),s("br"),s("span",{class:"line-number"},"14"),s("br"),s("span",{class:"line-number"},"15"),s("br"),s("span",{class:"line-number"},"16"),s("br"),s("span",{class:"line-number"},"17"),s("br"),s("span",{class:"line-number"},"18"),s("br"),s("span",{class:"line-number"},"19"),s("br"),s("span",{class:"line-number"},"20"),s("br"),s("span",{class:"line-number"},"21"),s("br"),s("span",{class:"line-number"},"22"),s("br"),s("span",{class:"line-number"},"23"),s("br"),s("span",{class:"line-number"},"24"),s("br"),s("span",{class:"line-number"},"25"),s("br"),s("span",{class:"line-number"},"26"),s("br"),s("span",{class:"line-number"},"27"),s("br"),s("span",{class:"line-number"},"28"),s("br"),s("span",{class:"line-number"},"29"),s("br"),s("span",{class:"line-number"},"30"),s("br"),s("span",{class:"line-number"},"31"),s("br"),s("span",{class:"line-number"},"32"),s("br"),s("span",{class:"line-number"},"33"),s("br"),s("span",{class:"line-number"},"34"),s("br"),s("span",{class:"line-number"},"35"),s("br"),s("span",{class:"line-number"},"36"),s("br"),s("span",{class:"line-number"},"37"),s("br"),s("span",{class:"line-number"},"38"),s("br"),s("span",{class:"line-number"},"39"),s("br"),s("span",{class:"line-number"},"40"),s("br"),s("span",{class:"line-number"},"41"),s("br"),s("span",{class:"line-number"},"42"),s("br"),s("span",{class:"line-number"},"43"),s("br"),s("span",{class:"line-number"},"44"),s("br"),s("span",{class:"line-number"},"45"),s("br"),s("span",{class:"line-number"},"46"),s("br"),s("span",{class:"line-number"},"47"),s("br"),s("span",{class:"line-number"},"48"),s("br"),s("span",{class:"line-number"},"49"),s("br"),s("span",{class:"line-number"},"50"),s("br"),s("span",{class:"line-number"},"51"),s("br"),s("span",{class:"line-number"},"52"),s("br"),s("span",{class:"line-number"},"53"),s("br"),s("span",{class:"line-number"},"54"),s("br"),s("span",{class:"line-number"},"55"),s("br"),s("span",{class:"line-number"},"56"),s("br"),s("span",{class:"line-number"},"57"),s("br"),s("span",{class:"line-number"},"58"),s("br"),s("span",{class:"line-number"},"59"),s("br"),s("span",{class:"line-number"},"60"),s("br"),s("span",{class:"line-number"},"61"),s("br"),s("span",{class:"line-number"},"62"),s("br")])],-1)])),default:ns(()=>[as(As)]),_:1}),F[2]||(F[2]=is(`

优点

  • 使用 Day.js 对象的 format 方法进行格式化
    • 无需自己实现格式化函数
    • 个位数时都不需要字符串补位操作
    • 在使用 format 时,在方括号中的字符不会被格式化替换
  • 兼容性良好

缺点

当需求场景超出 Day.js 对象的 format 方法的能力时(即不是标准的年月日时分秒格式)需要自己实现格式化函数

  • 40 天 13 时 14 分 00 秒
  • 52 时 13 分 14 秒
  • 100 分 50 秒

常用预设范围

常用于 antdRangePicker 组件

js
import dayjs from 'dayjs'
 
 // 获取当前的时间
 const now = dayjs()
diff --git a/assets/workflow_terminal_zsh.md.dI2UmAq0.js b/assets/workflow_terminal_zsh.md.CCt2xNBQ.js
similarity index 98%
rename from assets/workflow_terminal_zsh.md.dI2UmAq0.js
rename to assets/workflow_terminal_zsh.md.CCt2xNBQ.js
index 5dd4fb886..802eccf29 100644
--- a/assets/workflow_terminal_zsh.md.dI2UmAq0.js
+++ b/assets/workflow_terminal_zsh.md.CCt2xNBQ.js
@@ -31,7 +31,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 plugins=(其他插件 z)
 
 # 使配置生效
-source ~/.zshrc

z | Github

fast-syntax-highlighting

终端语法高亮显示

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

z | Github

fast-syntax-highlighting

终端语法高亮显示

安装

sh
# 在 ~/.zshrc 中配置
 zinit light zdharma-continuum/fast-syntax-highlighting
 
 # 使配置生效
@@ -42,7 +42,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 plugins=(其他插件 fast-syntax-highlighting)
 
 # 使配置生效
-source ~/.zshrc

Fast Syntax Highlighting | Github

zsh-autosuggestions

根据您的历史记录和完成情况建议您键入的命令

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

Fast Syntax Highlighting | Github

zsh-autosuggestions

根据您的历史记录和完成情况建议您键入的命令

安装

sh
# 在 ~/.zshrc 中配置
 zinit ice lucid wait="0" atload="_zsh_autosuggest_start"
 zinit light zsh-users/zsh-autosuggestions
 
@@ -54,7 +54,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 plugins=(其他插件 zsh-autosuggestions)
 
 # 使配置生效
-source ~/.zshrc

zsh-autosuggestions | Github

zsh 主题

powerlevel10k

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

zsh-autosuggestions | Github

zsh 主题

powerlevel10k

安装

sh
# 在 ~/.zshrc 中配置
 zinit ice depth=1
 zinit light romkatv/powerlevel10k
 
@@ -72,7 +72,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 # 比如显示当前使用的 node 版本
 
 # 使配置生效
-source ~/.zshrc

常用配置

具体可参考 —— 茂茂的 zsh 配置文件

sh
#--------------------------------------------------#
+source ~/.zshrc

常用配置

具体可参考 —— 茂茂的 zsh 配置文件

sh
#--------------------------------------------------#
 # 加载 p10k 主题
 #--------------------------------------------------#
 zinit ice depth=1
diff --git a/assets/workflow_terminal_zsh.md.dI2UmAq0.lean.js b/assets/workflow_terminal_zsh.md.CCt2xNBQ.lean.js
similarity index 98%
rename from assets/workflow_terminal_zsh.md.dI2UmAq0.lean.js
rename to assets/workflow_terminal_zsh.md.CCt2xNBQ.lean.js
index 5dd4fb886..802eccf29 100644
--- a/assets/workflow_terminal_zsh.md.dI2UmAq0.lean.js
+++ b/assets/workflow_terminal_zsh.md.CCt2xNBQ.lean.js
@@ -31,7 +31,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 plugins=(其他插件 z)
 
 # 使配置生效
-source ~/.zshrc

z | Github

fast-syntax-highlighting

终端语法高亮显示

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

z | Github

fast-syntax-highlighting

终端语法高亮显示

安装

sh
# 在 ~/.zshrc 中配置
 zinit light zdharma-continuum/fast-syntax-highlighting
 
 # 使配置生效
@@ -42,7 +42,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 plugins=(其他插件 fast-syntax-highlighting)
 
 # 使配置生效
-source ~/.zshrc

Fast Syntax Highlighting | Github

zsh-autosuggestions

根据您的历史记录和完成情况建议您键入的命令

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

Fast Syntax Highlighting | Github

zsh-autosuggestions

根据您的历史记录和完成情况建议您键入的命令

安装

sh
# 在 ~/.zshrc 中配置
 zinit ice lucid wait="0" atload="_zsh_autosuggest_start"
 zinit light zsh-users/zsh-autosuggestions
 
@@ -54,7 +54,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 plugins=(其他插件 zsh-autosuggestions)
 
 # 使配置生效
-source ~/.zshrc

zsh-autosuggestions | Github

zsh 主题

powerlevel10k

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

zsh-autosuggestions | Github

zsh 主题

powerlevel10k

安装

sh
# 在 ~/.zshrc 中配置
 zinit ice depth=1
 zinit light romkatv/powerlevel10k
 
@@ -72,7 +72,7 @@ import{_ as i,h as a,a8 as n,o as l}from"./chunks/framework.BU7NHiAd.js";const g
 # 比如显示当前使用的 node 版本
 
 # 使配置生效
-source ~/.zshrc

常用配置

具体可参考 —— 茂茂的 zsh 配置文件

sh
#--------------------------------------------------#
+source ~/.zshrc

常用配置

具体可参考 —— 茂茂的 zsh 配置文件

sh
#--------------------------------------------------#
 # 加载 p10k 主题
 #--------------------------------------------------#
 zinit ice depth=1
diff --git a/daily-notes/index.html b/daily-notes/index.html
index 2b6efc480..ccea5fb1d 100644
--- a/daily-notes/index.html
+++ b/daily-notes/index.html
@@ -13,7 +13,7 @@
     
     
     
-    
+    
     
     
     
@@ -28,8 +28,8 @@
     
   
   
-    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Daily Notes 日常笔记

日常笔记记录(零零散散啥都记系列)

新写一篇小笔记

共计 47 篇(上次更新: 2024-11-16)

2024 年 (共计 5 篇)

  1. 2024-11-16 —— 从 VSCode 迁移到 Cursor

  2. 2024-06-20 —— 漫画 APP 资源汇总

  3. 2024-05-24 —— 在 GitHub Actions 中触发其他仓库的 Actions

  4. 2024-05-20 —— 判断用户为移动端设备的若干种方式

  5. 2024-04-16 —— 浏览器的自动播放策略

2023 年 (共计 9 篇)

  1. 2023-12-13 —— 使用 shell 脚本复制项目信息到剪切板

  2. 2023-09-16 —— 使用 rollup 打包用户脚本(user script)

  3. 2023-05-21 —— 修改 node_modules 中的依赖(打补丁)

  4. 2023-05-18 —— 获取软件内置浏览器的 User-Agent

  5. 2023-03-12 —— VitePress 生成站点地图

  6. 2023-02-28 —— 使用 VitePress 打造个人前端导航网站

  7. 2023-02-20 —— 从 VuePress 迁移至 VitePress

  8. 2023-02-10 —— 不使用 JavaScript 来隐藏元素的若干方法

  9. 2023-01-06 —— 使用 shell 脚本检查并配置 git user 信息

2022 年 (共计 8 篇)

  1. 2022-12-28 —— 搭建青龙定时任务管理面板

  2. 2022-12-19 —— ShadowSocks PAC 用户自定规则

  3. 2022-10-28 —— Next.js 搭建官网踩坑小记

  4. 2022-10-19 —— 修复谷歌翻译失效

  5. 2022-09-13 —— CSS 伪类选择器中的表达式(an+b)

  6. 2022-08-16 —— 在 Github Actions 环境变量中传递数组或对象

  7. 2022-03-07 —— 常用搜索技巧

  8. 2022-01-13 —— Canvas 绘制带圆角的矩形图

2021 年 (共计 10 篇)

  1. 2021-12-16 —— Less 循环遍历和踩坑

  2. 2021-11-18 —— .npmrc 学习笔记

  3. 2021-11-09 —— Flex 语法和计算规则

  4. 2021-10-17 —— Plop 实战笔记

  5. 2021-08-19 —— 解决 Github Support for password

  6. 2021-05-31 —— 使用 npm 脚本钩子

  7. 2021-04-15 —— Webpack 打包优化(CRA 项目)

  8. 2021-01-22 —— Mac 终端小技巧

  9. 2021-01-14 —— 在 vue-cli 中使用 tailwindcss

  10. 2021-01-12 —— 修改 DNS 解决 Github 资源加载失败

2020 年 (共计 15 篇)

  1. 2020-11-27 —— CRA 接入 react-dev-inspector

  2. 2020-11-10 —— Webpack 性能分析

  3. 2020-10-22 —— puppeteer 学习笔记

  4. 2020-09-30 —— 使用 URLSearchParams 解析 URL 的查询字符串

  5. 2020-08-04 —— 获取当前 git 分支

  6. 2020-07-20 —— 语义化版本控制

  7. 2020-07-04 —— package.json 相关知识

  8. 2020-06-17 —— 使用 husky、lint-staged、commitlint 构建前端工作流

  9. 2020-06-15 —— 使用 jsdelivr 加速 Github 仓库资源

  10. 2020-06-06 —— 在项目中使用 ESLint 和 Prettier

  11. 2020-05-21 —— Tree-Shaking 相关笔记

  12. 2020-05-15 —— 使用 SVG 做动画

  13. 2020-04-30 —— 修改 CRA 的默认配置

  14. 2020-04-29 —— CSS 函数

  15. 2020-04-28 —— 使用 JS 开发命令行程序

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Daily Notes 日常笔记

日常笔记记录(零零散散啥都记系列)

新写一篇小笔记

共计 48 篇(上次更新: 2024-12-15)

2024 年 (共计 6 篇)

  1. 2024-12-15 —— 魅族 21 Pro 安装 Google 服务

  2. 2024-11-16 —— 从 VSCode 迁移到 Cursor

  3. 2024-06-20 —— 漫画 APP 资源汇总

  4. 2024-05-24 —— 在 GitHub Actions 中触发其他仓库的 Actions

  5. 2024-05-20 —— 判断用户为移动端设备的若干种方式

  6. 2024-04-16 —— 浏览器的自动播放策略

2023 年 (共计 9 篇)

  1. 2023-12-13 —— 使用 shell 脚本复制项目信息到剪切板

  2. 2023-09-16 —— 使用 rollup 打包用户脚本(user script)

  3. 2023-05-21 —— 修改 node_modules 中的依赖(打补丁)

  4. 2023-05-18 —— 获取软件内置浏览器的 User-Agent

  5. 2023-03-12 —— VitePress 生成站点地图

  6. 2023-02-28 —— 使用 VitePress 打造个人前端导航网站

  7. 2023-02-20 —— 从 VuePress 迁移至 VitePress

  8. 2023-02-10 —— 不使用 JavaScript 来隐藏元素的若干方法

  9. 2023-01-06 —— 使用 shell 脚本检查并配置 git user 信息

2022 年 (共计 8 篇)

  1. 2022-12-28 —— 搭建青龙定时任务管理面板

  2. 2022-12-19 —— ShadowSocks PAC 用户自定规则

  3. 2022-10-28 —— Next.js 搭建官网踩坑小记

  4. 2022-10-19 —— 修复谷歌翻译失效

  5. 2022-09-13 —— CSS 伪类选择器中的表达式(an+b)

  6. 2022-08-16 —— 在 Github Actions 环境变量中传递数组或对象

  7. 2022-03-07 —— 常用搜索技巧

  8. 2022-01-13 —— Canvas 绘制带圆角的矩形图

2021 年 (共计 10 篇)

  1. 2021-12-16 —— Less 循环遍历和踩坑

  2. 2021-11-18 —— .npmrc 学习笔记

  3. 2021-11-09 —— Flex 语法和计算规则

  4. 2021-10-17 —— Plop 实战笔记

  5. 2021-08-19 —— 解决 Github Support for password

  6. 2021-05-31 —— 使用 npm 脚本钩子

  7. 2021-04-15 —— Webpack 打包优化(CRA 项目)

  8. 2021-01-22 —— Mac 终端小技巧

  9. 2021-01-14 —— 在 vue-cli 中使用 tailwindcss

  10. 2021-01-12 —— 修改 DNS 解决 Github 资源加载失败

2020 年 (共计 15 篇)

  1. 2020-11-27 —— CRA 接入 react-dev-inspector

  2. 2020-11-10 —— Webpack 性能分析

  3. 2020-10-22 —— puppeteer 学习笔记

  4. 2020-09-30 —— 使用 URLSearchParams 解析 URL 的查询字符串

  5. 2020-08-04 —— 获取当前 git 分支

  6. 2020-07-20 —— 语义化版本控制

  7. 2020-07-04 —— package.json 相关知识

  8. 2020-06-17 —— 使用 husky、lint-staged、commitlint 构建前端工作流

  9. 2020-06-15 —— 使用 jsdelivr 加速 Github 仓库资源

  10. 2020-06-06 —— 在项目中使用 ESLint 和 Prettier

  11. 2020-05-21 —— Tree-Shaking 相关笔记

  12. 2020-05-15 —— 使用 SVG 做动画

  13. 2020-04-30 —— 修改 CRA 的默认配置

  14. 2020-04-29 —— CSS 函数

  15. 2020-04-28 —— 使用 JS 开发命令行程序

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-1.html b/daily-notes/issue-1.html index 155a5f6aa..3b76ce1ea 100644 --- a/daily-notes/issue-1.html +++ b/daily-notes/issue-1.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 JS 开发命令行程序

书写脚本

新建一个脚本,如 touch maomao.js,内容如下

js
#!/usr/bin/env node
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 JS 开发命令行程序

书写脚本

新建一个脚本,如 touch maomao.js,内容如下

js
#!/usr/bin/env node
 console.log('脚本')

#!/usr/bin/env node用来表示它是一个 node 脚本

然后在命令行输入脚本路径运行即可

无路径运行

package.json 配置 bin 选项,如

json
  "bin": {
     "maomao": "maomao.js"
   },

然后运行 npm link 即可

使用 Inquirer.js 进行命令行交互

js
#!/usr/bin/env node
@@ -108,7 +108,7 @@
   log(chalk.blue('正在运行: npm run ' + env))
   shell.exec('npm run ' + env)
 })

image

相关库

具体 api 可以查看对应库

  • Inquirer.js 交互式命令行工具
  • chalk 修改控制台内容输出的样式
  • shelljsUnix ShellNode.js API 层的轻量级实现,可以很方便的调用系统命令
  • commander.js 编写指令和处理命令行

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-10.html b/daily-notes/issue-10.html index 50d65cd7b..072461317 100644 --- a/daily-notes/issue-10.html +++ b/daily-notes/issue-10.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

语义化版本控制

语义化版本说明

  • 标准版本号表示: X.Y.Z
    • X: 表示主版本号,在有任何不兼容的修改时递增
    • Y: 表示次版本号,在有向下兼容的新功能出现时递增
    • Z: 表示修订版本号,在只做了向下兼容的修正时才递增
  • 先行版本号,在修订版本号使用连接号加上一连串以句点分隔的标识符来修饰。
    • 先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求
    • 例子: 1.0.0-alpha 1.0.0-beta
  • 版本号优先级
    • 主版本号、次版本号及修订版本号以数值比较
    • 当主版本号、次版本号及修订版本号都相同时

版本号优先级排序

  1. 要将版本号拆分为主版本号、次版本号、修订版本号及先行版本号
  2. 由左到右依序比较每个标识符(主版本号、次版本号及修订版本号直接以数值比较)
  3. 当主版本号、次版本号及修订版本号都相同时,以先行版本号来判断
  4. 先行版本号判断通过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定:只有数字的标识符以数值高低比较,有字母或连接号时则逐字以 ASCII 的排序来比较

🌰 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

使用 standard-version

standard-version 可以进行语义化版本发布和 CHANGELOG 生成

安装

sh
npm install -g standard-version
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

语义化版本控制

语义化版本说明

  • 标准版本号表示: X.Y.Z
    • X: 表示主版本号,在有任何不兼容的修改时递增
    • Y: 表示次版本号,在有向下兼容的新功能出现时递增
    • Z: 表示修订版本号,在只做了向下兼容的修正时才递增
  • 先行版本号,在修订版本号使用连接号加上一连串以句点分隔的标识符来修饰。
    • 先行版本号则表示这个版本并非稳定而且可能无法满足预期的兼容性需求
    • 例子: 1.0.0-alpha 1.0.0-beta
  • 版本号优先级
    • 主版本号、次版本号及修订版本号以数值比较
    • 当主版本号、次版本号及修订版本号都相同时

版本号优先级排序

  1. 要将版本号拆分为主版本号、次版本号、修订版本号及先行版本号
  2. 由左到右依序比较每个标识符(主版本号、次版本号及修订版本号直接以数值比较)
  3. 当主版本号、次版本号及修订版本号都相同时,以先行版本号来判断
  4. 先行版本号判断通过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定:只有数字的标识符以数值高低比较,有字母或连接号时则逐字以 ASCII 的排序来比较

🌰 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

使用 standard-version

standard-version 可以进行语义化版本发布和 CHANGELOG 生成

安装

sh
npm install -g standard-version
 # OR
 npm install --save-dev standard-version

使用

package.jsonscripts 配置 "release": "standard-version"

sh
# 发布第一版
 npm run release -- --first-release
@@ -44,7 +44,7 @@
 
 # 指定版本
 npm run release -- --release-as x.y.z

相关资料

语义化版本 2.0.0语义版本控制程序 semver

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-11.html b/daily-notes/issue-11.html index 76fb8ee38..c453776e0 100644 --- a/daily-notes/issue-11.html +++ b/daily-notes/issue-11.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

获取当前 git 分支

命令

git 2.22 版本之后

sh
git branch --show-current

git 2.22 版本之前

sh
# 使用 rev-parse
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

获取当前 git 分支

命令

git 2.22 版本之后

sh
git branch --show-current

git 2.22 版本之前

sh
# 使用 rev-parse
 git rev-parse --abbrev-ref HEAD
 
 # 使用 symbolic-ref
@@ -42,7 +42,7 @@
     encoding: 'utf8'
   })
   .trim()

用途

可以根据分支名在 webpack 编译时做处理(如: 线上环境打包只允许在 master 分支)

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-12.html b/daily-notes/issue-12.html index 079198065..12af56488 100644 --- a/daily-notes/issue-12.html +++ b/daily-notes/issue-12.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 URLSearchParams 解析 URL 的查询字符串

URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串

语法和使用

js
// const url = 'https://github.com/search?o=desc&q=URLSearchParams&s=stars&type=Repositories'
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 URLSearchParams 解析 URL 的查询字符串

URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串

语法和使用

js
// const url = 'https://github.com/search?o=desc&q=URLSearchParams&s=stars&type=Repositories'
 const url = 'o=desc&q=URLSearchParams&s=stars&type=Repositories'
 
 // 实例化
@@ -85,7 +85,7 @@
   console.log(key, value)
 }

冷知识

query 上的 "" key

js
const searchParams = new URLSearchParams('?=maomao')
 searchParams.get('') // "maomao"

MDN 详细介绍点这里

相关 polyfill

core-js@2.x 未包含 URLSearchParams

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-13.html b/daily-notes/issue-13.html index 2a13e09ac..8bf43d0f3 100644 --- a/daily-notes/issue-13.html +++ b/daily-notes/issue-13.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

puppeteer 学习笔记

安装

sh
yarn add puppeteer
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

puppeteer 学习笔记

安装

sh
yarn add puppeteer
 # OR
 yarn add puppeteer-core

puppeteer-core 版本不会额外下载一个 Chromium (安装贼慢),同时会忽略所有 PUPPETEER_ * env 变量

puppeteer vs puppeteer-core

API 用法记录

js
import puppeteer from 'puppeteer-core'
 ;(async () => {
@@ -81,7 +81,7 @@
     console.log('error', error)
   }
 })()

相关资料

Puppeteer GithubPuppeteer 中文文档

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-14.html b/daily-notes/issue-14.html index cfba15ced..90b7c2ec0 100644 --- a/daily-notes/issue-14.html +++ b/daily-notes/issue-14.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Webpack 性能分析

打包速度分析 speed-measure-webpack-plugin

sh
yarn add -D speed-measure-webpack-plugin
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Webpack 性能分析

打包速度分析 speed-measure-webpack-plugin

sh
yarn add -D speed-measure-webpack-plugin
 # OR
 npm install -D speed-measure-webpack-plugin

speed-measure-webpack-plugin | GitHub

create-react-app

react-app-rewired + customize-cra 方案

修改 config-overrides.js 文件

js
const { override } = require('customize-cra')
 const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
@@ -60,7 +60,7 @@
     config.plugin('webpack-bundle-analyzer').use(BundleAnalyzerPlugin)
   }
 }

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-15.html b/daily-notes/issue-15.html index b47bb61d0..049477840 100644 --- a/daily-notes/issue-15.html +++ b/daily-notes/issue-15.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

CRA 接入 react-dev-inspector

react-dev-inspectorReact 开发辅助插件,可以通过点击页面自动跳转 vscode 打开对应的组件代码

安装 react-dev-inspector

sh
yarn add -D react-dev-inspector
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

CRA 接入 react-dev-inspector

react-dev-inspectorReact 开发辅助插件,可以通过点击页面自动跳转 vscode 打开对应的组件代码

安装 react-dev-inspector

sh
yarn add -D react-dev-inspector
 # OR
 npm install -D react-dev-inspector

webpack 配置

使用 react-app-rewiredcustomize-cra 方案

修改 config-overrides.js 文件

js
const { override, addWebpackPlugin } = require('customize-cra')
 const path = require('path')
@@ -74,7 +74,7 @@
   </InspectorWrapper>,
   document.getElementById('root')
 )

use-in-react

vscode 配置

  1. 打开 vscode
  2. 使用 command + shift + p (windows: ctrl + shift + p)
  3. 搜索 code
  4. 选择 Shell Command: Install 'code' command in PATH

效果图

效果图

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-16.html b/daily-notes/issue-16.html index deac27ee9..6c7c107a4 100644 --- a/daily-notes/issue-16.html +++ b/daily-notes/issue-16.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修改 DNS 解决 Github 图片资源加载失败

获取 IP 地址

  1. 打开 ipaddress
  2. 搜索 raw.githubusercontent.com (控制台资源报错的域名)

快捷搜索 raw.githubusercontent.com IP 地址

修改本地 Hosts 文件

各系统 hosts 文件路径如下

  • Windows 系统:C:\Windows\System32\drivers\etc\hosts
  • Mac 系统:/etc/hosts
  • Linux 系统:/etc/hosts
  • Android 系统:/system/etc/hosts
  • iOS 系统:/etc/hosts
sh
199.232.96.133    assets-cdn.github.com
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修改 DNS 解决 Github 图片资源加载失败

获取 IP 地址

  1. 打开 ipaddress
  2. 搜索 raw.githubusercontent.com (控制台资源报错的域名)

快捷搜索 raw.githubusercontent.com IP 地址

修改本地 Hosts 文件

各系统 hosts 文件路径如下

  • Windows 系统:C:\Windows\System32\drivers\etc\hosts
  • Mac 系统:/etc/hosts
  • Linux 系统:/etc/hosts
  • Android 系统:/system/etc/hosts
  • iOS 系统:/etc/hosts
sh
199.232.96.133    assets-cdn.github.com
 199.232.96.133    raw.githubusercontent.com
 199.232.96.133    gist.githubusercontent.com
 199.232.96.133    camo.githubusercontent.com
@@ -40,7 +40,7 @@
 199.232.96.133    avatars2.githubusercontent.com
 199.232.96.133    avatars3.githubusercontent.com
 199.232.96.133    avatars4.githubusercontent.com

199.232.96.133 为之前获取到的 IP 地址

推荐使用 Hosts 管理工具(SwitchHosts)修改

SwitchHosts

  1. Hosts 文件语法高亮
  2. 快速切换 Hosts
  3. 在线 Hosts 方案
  4. 系统托盘图标快速切换
  5. 支持 windows macOS linux

SwitchHosts | GitHub

在 SwitchHosts 中使用远程配置文件

  1. 打开 SwitchHosts
  2. 添加 hosts
  3. 选择类型为「远程」
  4. URL 为以下链接
    1. https://gitlab.com/ineo6/hosts/-/raw/master/hosts
    2. https://raw.hellogithub.com/hosts
  • hosts | GitHub 解决GitHub图片无法显示,加速GitHub网页浏览
  • GitHub520 | GitHub 让你“爱”上 GitHub,解决访问时图裂、加载慢的问题。(无需安装)

刷新本地 DNS 缓存

macOS

sh
sudo killall -HUP mDNSResponder

Windows

sh
ipconfig /flushdns

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-17.html b/daily-notes/issue-17.html index 2df0b9dd8..e1dc90f4f 100644 --- a/daily-notes/issue-17.html +++ b/daily-notes/issue-17.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在 vue-cli 中使用 tailwindcss

Tailwind CSS 是一个高度可定制的基础层 CSS 框架,提供一系列的基础工具类,通过工具类的组合完成样式编写

说明

tailwindcss 从 2.0 开始使用了 PostCSS 8,但是 vue-cli 自带的为 PostCSS 7,从而需要安装 tailwindcss的兼容版本

安装

  1. 安装依赖
sh
yarn add tailwindcss@npm:@tailwindcss/postcss7-compat
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在 vue-cli 中使用 tailwindcss

Tailwind CSS 是一个高度可定制的基础层 CSS 框架,提供一系列的基础工具类,通过工具类的组合完成样式编写

说明

tailwindcss 从 2.0 开始使用了 PostCSS 8,但是 vue-cli 自带的为 PostCSS 7,从而需要安装 tailwindcss的兼容版本

安装

  1. 安装依赖
sh
yarn add tailwindcss@npm:@tailwindcss/postcss7-compat
 # OR
 npm install tailwindcss@npm:@tailwindcss/postcss7-compat
 
@@ -44,7 +44,7 @@
   variants: {},
   plugins: []
 }

配置项说明

编辑器插件

Visual Studio Code - Tailwind CSS IntelliSense

  1. 语法提示
  2. 代码高亮
  3. Linting

解决 @apply 语法错误

@apply 改为单行列出,多次调用

WeChat17d0e6cf8604e0cf180fd509d286fe93

stackoverflow@apply 语法文档

post-css-7-compatibility-build

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-18.html b/daily-notes/issue-18.html index 380a6ba13..a46883fe7 100644 --- a/daily-notes/issue-18.html +++ b/daily-notes/issue-18.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Mac 终端小技巧

终端代理

临时使用

打开终端直接运行

sh
# http://proxyAddress:port 是 SSR 软件代理监听地址(一般为 127.0.0.1:xxxx)
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Mac 终端小技巧

终端代理

临时使用

打开终端直接运行

sh
# http://proxyAddress:port 是 SSR 软件代理监听地址(一般为 127.0.0.1:xxxx)
 # 只代理 http 请求
 export HTTP_PROXY=http://proxyAddress:port
 
@@ -70,7 +70,7 @@
 
 # 运行 unproxy 关闭代理
 unproxy

常用快捷键

操作含义
Ctrl + P上一条命令
Ctrl + R搜索命令历史
Ctrl + L清屏
Ctrl + U清除当前行
Ctrl + W删除光标前面的一个单词
Ctrl + K删除光标后面的所有字符
Ctrl + A移动光标到行首
Ctrl + E移动光标到行尾

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-19.html b/daily-notes/issue-19.html index 569b34178..dbe571e5c 100644 --- a/daily-notes/issue-19.html +++ b/daily-notes/issue-19.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Webpack 4 打包优化(CRA 项目)

react-app-rewired + customize-cra 方案为例

使用 dayjs 替换 moment

sh
yarn add -D antd-dayjs-webpack-plugin
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Webpack 4 打包优化(CRA 项目)

react-app-rewired + customize-cra 方案为例

使用 dayjs 替换 moment

sh
yarn add -D antd-dayjs-webpack-plugin
 # OR
 npm install -D antd-dayjs-webpack-plugin

修改 config-overrides.js 文件

js
const { override, addWebpackPlugin } = require('customize-cra')
 const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin')
@@ -82,7 +82,7 @@
 }
 
 module.exports = override(customWebpackConfig)

优化图

相关资料

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-2.html b/daily-notes/issue-2.html index 812cfbd9c..8204d447e 100644 --- a/daily-notes/issue-2.html +++ b/daily-notes/issue-2.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

CSS 函数

早上刷推看到的一个图

1F84C7046D0DD6DD8C98FD7E21475F4D

min()

计算表达式的值中最小的值作为参数值

类似 JS 中的 Math.min()

示例

css
width: min(50vw, 500px);

表示元素最大宽为 500px,即:小屏设备上宽度为 window 的一半,但在小屏设备上,不超过 500px

max()

计算表达式的值中最大的值作为参数值,用法和 min 一致

clamp()

返回一个区间范围的值

语法: clamp(MIN, VAL, MAX)MIN 表示最小值,VAL 表示首选值,MAX 表示最大值,即 VALMIN MAX 之间就用 VAL,比 MIN 小就用 MIN ,比 MAX 大就用 MAX

等同于 max(MIN, min(VAL, MAX))

组合使用

min() max() clamp() 这三哥们都是比较新的属性,兼容性都不咋地,仅用于个人玩具

image

html
<!DOCTYPE html>
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

CSS 函数

早上刷推看到的一个图

1F84C7046D0DD6DD8C98FD7E21475F4D

min()

计算表达式的值中最小的值作为参数值

类似 JS 中的 Math.min()

示例

css
width: min(50vw, 500px);

表示元素最大宽为 500px,即:小屏设备上宽度为 window 的一半,但在小屏设备上,不超过 500px

max()

计算表达式的值中最大的值作为参数值,用法和 min 一致

clamp()

返回一个区间范围的值

语法: clamp(MIN, VAL, MAX)MIN 表示最小值,VAL 表示首选值,MAX 表示最大值,即 VALMIN MAX 之间就用 VAL,比 MIN 小就用 MIN ,比 MAX 大就用 MAX

等同于 max(MIN, min(VAL, MAX))

组合使用

min() max() clamp() 这三哥们都是比较新的属性,兼容性都不咋地,仅用于个人玩具

image

html
<!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
@@ -70,7 +70,7 @@
     <div class="min-calc">min calc</div>
   </body>
 </html>

demo

顺便总结了下 CSS 的函数

数学函数

  • min() 计算表达式的值中最小的值作为参数值
    • width: min(50vw, 500px);
  • max() 计算表达式的值中最大的值作为参数值
    • width: max(50vw, 500px);
  • clamp() 返回一个区间范围的值
    • width: clamp(10px, 1em, 20px);
  • calc() 在声明 CSS 属性值时执行一些计算
    • width: calc(100% - 100px);
  • minmax()gird 布局中使用,定义了一个长宽范围的闭区间
  • repeat()gird 布局中使用,表示轨道列表的重复片段
  • attr() 获取选择到的元素的某一 HTML 属性值
    • a:before { content:attr(data-name); }

颜色函数

  • rgb() 使用红-绿-蓝(red-green-blue (RGB))定义颜色
    • color: rgb(123, 123, 123);
  • rgba()rgb 的基础上增加了阿尔法通道(A)
    • color: rgba(123, 123, 123, 0.23);
  • hsl() 使用色相-饱和度-明度(Hue-saturation-lightness)定义颜色
    • color: hsl(120, 100%, 75%);
  • hsla()hsl 的基础上增加了阿尔法通道(A)
    • color: hsla(120, 100%, 75%, 0.5);

背景图函数

  • url() 指向一个资源
    • background: url('img.png');
  • linear-gradient() 创建一个线性渐变
    • background-image: linear-gradient(45deg, blue, red);
    • background-image: linear-gradient(to left top, blue, red);
  • radial-gradient() 创建一个径向渐变
    • background-image: radial-gradient(circle, red, yellow, green);
  • repeating-linear-gradient() 创建重复的线性渐变
    • background-image: repeating-linear-gradient(red, yellow 10%, green 20%);
  • repeating-radial-gradient() 创建重复的径向渐变
    • background-image: repeating-radial-gradient(red, yellow 10%, green 15%);

动画缓动函数

其他函数

  • var() 用于插入自定义的属性值
    • width: var(--main-wdith);

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-20.html b/daily-notes/issue-20.html index fb6f8cf69..56300e79c 100644 --- a/daily-notes/issue-20.html +++ b/daily-notes/issue-20.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 npm 脚本钩子

钩子说明

npm 脚本中有 prepost 两个钩子

比如 build 脚本命令的钩子就是 prebuildpostbuild

json
{
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 npm 脚本钩子

钩子说明

npm 脚本中有 prepost 两个钩子

比如 build 脚本命令的钩子就是 prebuildpostbuild

json
{
   "scripts": {
     "prebuild": "echo I run before the build script",
     "build": "vue-cli-service build",
@@ -74,7 +74,7 @@
 +   "prestart": "node ./scripts/checkDependence.js"
   }
 }

使用效果

npm 相关命令说明

  1. npm view <name> 查询并返回指定包的所有信息
  2. npm view <name> versions 查询并返回指定包的所有版本信息(数组格式)
  3. npm view <name> version 查询并返回指定包的最新版本号

相关资料

npm-view

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-21.html b/daily-notes/issue-21.html index 816aedf6b..679cfa306 100644 --- a/daily-notes/issue-21.html +++ b/daily-notes/issue-21.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

解决 Github Support for password

方案一配置 SSH Key

生成密钥

sh
ssh-keygen -t rsa -C "邮箱地址"

查看并复制公钥

sh
# 进入 .ssh 目录
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

解决 Github Support for password

方案一配置 SSH Key

生成密钥

sh
ssh-keygen -t rsa -C "邮箱地址"

查看并复制公钥

sh
# 进入 .ssh 目录
 cd ~/.ssh
 # 查看文件
 ls
@@ -38,7 +38,7 @@
 git remote get-url origin
 # 修改项目源
 git remote set-url origin SSH源地址

嫌修改项目源麻烦可以使用方案二

其他

Git 配置多个 SSH-Key

方案二配置 Personal Access Token

  1. 打开 https://github.com/settings/tokens/new

  2. 输入表单内容然后点击 Generate token 按钮生成

    1. Note: 备注说明
    2. Expiration: token 有效期,怕麻烦直接选永久
    3. Select scopes: 一般选 repo 权限
  3. 复制生成好的 token

  4. 打开钥匙串搜索 github.com

编辑钥匙串

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-22.html b/daily-notes/issue-22.html index e8878bedf..5920af77e 100644 --- a/daily-notes/issue-22.html +++ b/daily-notes/issue-22.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Plop 实战笔记

Plop 是一个轻量级的项目搭建生成工具,提供了一种以一致的方式生成代码或任何其他类型的纯文本文件的简单方法

当我们在项目中引入时,可以通过定制对应的命令询问,可以帮助我们自动生成页面文件,添加对应的路由配置等

安装 Plop

sh
npm install --save-dev plop

添加运行脚本命令

修改 package.json 文件

diff
"scripts": {
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Plop 实战笔记

Plop 是一个轻量级的项目搭建生成工具,提供了一种以一致的方式生成代码或任何其他类型的纯文本文件的简单方法

当我们在项目中引入时,可以通过定制对应的命令询问,可以帮助我们自动生成页面文件,添加对应的路由配置等

安装 Plop

sh
npm install --save-dev plop

添加运行脚本命令

修改 package.json 文件

diff
"scripts": {
 +   "plop": "plop"
 }

创建配置文件

在项目根目录创建 plopfile.js 文件

js
module.exports = function (plop) {
   // 添加一个生成器(生成器名称和配置项)
@@ -93,7 +93,7 @@
     }
   })
 }

其他

Plop 的字符串转化函数底层(相关源码)使用了 change-case

当我们在 JS 中需要使用时可以引入该库,与模板语法处理保持统一

相关案例地址

完整案例

https://github.com/maomao1996/plop-demo

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-23.html b/daily-notes/issue-23.html index 5d44e025f..109aee6f2 100644 --- a/daily-notes/issue-23.html +++ b/daily-notes/issue-23.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Flex 语法和计算规则

flex 是以下三个 CSS 属性的简写

  • flex-grow 设置 flex 元素的增长系数;负值无效,省略时默认值为 1 (初始值为 0)
  • flex-shrink 设置 flex 元素的收缩系数(仅在默认 width/height 之和大于容器时生效);负值无效,省略时默认值为 1 (初始值为 1)
  • flex-basis 设置 flex 元素在主轴方向上的初始大小;省略时默认值为 0 (初始值为 auto)

语法

单值语法

css
/* 全局属性值 */
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Flex 语法和计算规则

flex 是以下三个 CSS 属性的简写

  • flex-grow 设置 flex 元素的增长系数;负值无效,省略时默认值为 1 (初始值为 0)
  • flex-shrink 设置 flex 元素的收缩系数(仅在默认 width/height 之和大于容器时生效);负值无效,省略时默认值为 1 (初始值为 1)
  • flex-basis 设置 flex 元素在主轴方向上的初始大小;省略时默认值为 0 (初始值为 auto)

语法

单值语法

css
/* 全局属性值 */
 /* 初始值 */
 flex: initial; => flex: 0 1 auto
 /* 从其父级继承 (flex 属性不可被继承,将设置为初始值) */
@@ -142,7 +142,7 @@
   <div class="right"></div>
 </div>

解答

分析代码可以得出,我们需要计算 flex 元素的收缩系数 flex-shrink

  1. 计算 flex 元素宽度总和: 300 + 400 + 500 = 1200px
  2. 计算溢出的宽度: 1200 - 1000 = 200px
  3. 计算总权重: 3 * 300 + 2 * 400 + 1 * 500 = 2200
  4. 计算 flex 元素实际宽度(width - 溢出宽度)
    1. left: 300 - 200 * 3 * 300 / 2200 = 218.19px
    2. center: 400 - 200 * 2 * 400 / 2200 = 327.28px
    3. right: 500 - 200 * 1 * 500 / 2200 = 454.55px

CodeSandbox: flex-shrink

flex-shrink 计算公式

sh
# 总权重计算: 各元素的宽度乘以其 flex-shrink 的总和
 元素宽度 - 溢出宽度 * flex-shrink 系数 * 元素宽度 / 总权重 = 实际宽度

相关资料

flex - CSS(层叠样式表)| MDN

详解 flex-grow 与 flex-shrink

flex 布局算法

深入理解 flex 布局以及计算

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-24.html b/daily-notes/issue-24.html index 904dad7a8..598a31ae4 100644 --- a/daily-notes/issue-24.html +++ b/daily-notes/issue-24.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

.npmrc 学习笔记

.npmrcnpm 配置文件,可以通过修改配置项对 npm 做配置

🌰: 修改镜像源

sh
registry=https://registry.npmmirror.com
sh
# 查看所有配置
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

.npmrc 学习笔记

.npmrcnpm 配置文件,可以通过修改配置项对 npm 做配置

🌰: 修改镜像源

sh
registry=https://registry.npmmirror.com
sh
# 查看所有配置
 npm config ls [-l|--json]
 
 # 查看配置
@@ -46,7 +46,7 @@
 
 # 编辑配置文件
 npm config edit [-g|--global]

配置说明

配置读取顺序

  1. 命令行
  2. 项目配置(项目根目录下的 npmrc 文件)
  3. 用户配置(用 npm config get userconfig 查看文件位置)
  4. 全局配置(用 npm config get prefix 查看文件位置)
  5. 默认配置

其他包管理器

yarn

踩坑点

yarn 1 中如果同时存在 .yarnrc.npmrc 文件时, .npmrc 优先级高于 .yarnrc 当我们使用 yarn 1 时项目只需要配置 .npmrc 文件

pnpm

pnpm 使用 .npmrc 文件

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-25.html b/daily-notes/issue-25.html index a826c1728..1231dd8c9 100644 --- a/daily-notes/issue-25.html +++ b/daily-notes/issue-25.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Less 循环遍历和踩坑

递归混合

Recursive Mixins 文档

less
.color {
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Less 循环遍历和踩坑

递归混合

Recursive Mixins 文档

less
.color {
   // 定义遍历对象
   @colors: #111, #444, #999;
 
@@ -137,7 +137,7 @@
   /* 这是测试用的块级注释 */
   width: 100px;
 }

原因: Less 编译后的代码会保留块级注释(可以用来添加版权信息等,Sass 也是如此)

注释踩坑 — Playground

相关资料

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-26.html b/daily-notes/issue-26.html index 7847e2e3d..391e62973 100644 --- a/daily-notes/issue-26.html +++ b/daily-notes/issue-26.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Canvas 绘制带圆角的矩形图

实现步骤:

  1. 绘制一个圆角矩形 (打开冰箱)
  2. 对圆角矩形进行剪切(把 🐘 放进去)
  3. 将图片绘制到矩形内(关上冰箱)

绘制圆角矩形

arcTo 方案

arcTo 可以根据控制点和半径绘制圆弧路径

js
// 绘制圆角矩形(使用 arcTo)
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Canvas 绘制带圆角的矩形图

实现步骤:

  1. 绘制一个圆角矩形 (打开冰箱)
  2. 对圆角矩形进行剪切(把 🐘 放进去)
  3. 将图片绘制到矩形内(关上冰箱)

绘制圆角矩形

arcTo 方案

arcTo 可以根据控制点和半径绘制圆弧路径

js
// 绘制圆角矩形(使用 arcTo)
 function drawRoundedRect(ctx, x, y, width, height, radius) {
   // 重置当前路径
   ctx.beginPath()
@@ -200,7 +200,7 @@
     </script>
   </body>
 </html>

CodeSandbox: Canvas 绘制带圆角的矩形图 — globalCompositeOperation

这是李总教我的方案,再次膜拜一下大佬

相关资料

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-27.html b/daily-notes/issue-27.html index 413942ce5..d8717efe0 100644 --- a/daily-notes/issue-27.html +++ b/daily-notes/issue-27.html @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

常用搜索技巧

搜索引擎常用技巧

  • ""(双引号): 精确搜索

    • 搜索结果中必须包含关键字且顺序一致
      • "react学习指南": 搜索 react 学习指南
  • -(减号): 排除搜索

    • 搜索结果中排除减号后面的关键词,可以设置多个排除关键词
      • react学习指南 -csdn 搜索 react 学习指南并过滤掉带 csdn 的结果
  • *(星号): 模糊搜索

    • 用星号代替某个字来进行搜索
      • 搜*技巧 搜索结果中带有 搜*技巧的网页
  • OR(或): 组合搜索

    • 在各个关键词之间加上 OR 进行多个关键词搜索
      • vue OR react 搜索结果带有 vue 或者 react
  • ..(两个点): 数字范围搜索

    • 在某个数字范围内执行搜索
      • 手机2000..3000 搜索 2000 - 3000 的手机
  • site: 指定站点搜索

    • 在指定的网址对关键词进行搜索
      • github.com 前端学习资料 在 github 上搜索前端学习资料
  • filetype: 文件类型搜索

    • 对关键词进行指定文件类型的资源搜索
      • filetype:pdf JavaScript 搜索 JavaScript 的 pdf 文件
  • inurl: 页面 url 搜索

    • 在页面网址(url)对关键词进行搜索
      • inurl:javascript 搜索页面网址带有 javascript 的网页
  • intitle: 页面 title 搜索

    • 在页面标题(title)中对关键词进行搜索
      • intitle:react学习指南 搜索页面标题带有 react 学习指南的网页
  • intext: 页面内容搜索

    • 在页面正文对关键词进行搜索
      • intext:JavaScript 搜索页面正文带有 JavaScript 的网页

Google 搜索帮助

Github 常用技巧

常用 Github 搜索技巧

  • ""(双引号): 精确搜索

    • "react-admin"
      • 搜索结果中必须包含 react-admin
  • in: 限制搜索的范围

    • in:name [关键词]
      • 范围为仓库名称
    • in:description [关键词]
      • 范围为仓库描述
    • in:readme [关键词]
      • 范围为 readme
  • stars / forks: 限制搜索的 starfork

    • stars:>100
      • star 数大于 100
    • stars:>=100
      • star 数大于等于 100
    • stars:<100
      • star 数小于 100
    • stars:<=100
      • star 数小于等于 100
    • stars:100..200
      • star 数在 100 到 200 之间(闭区间)
  • language: 限制搜索的语言

    • language:html
  • created / pushed: 限制搜索的日期范围

    • created:>2020-01-01
      • 创建日期大于 2020-01-01
    • pushed:>2020-01-01
      • 更新日期大于 2020-01-01

Github 搜索帮助

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

常用搜索技巧

搜索引擎常用技巧

  • ""(双引号): 精确搜索

    • 搜索结果中必须包含关键字且顺序一致
      • "react学习指南": 搜索 react 学习指南
  • -(减号): 排除搜索

    • 搜索结果中排除减号后面的关键词,可以设置多个排除关键词
      • react学习指南 -csdn 搜索 react 学习指南并过滤掉带 csdn 的结果
  • *(星号): 模糊搜索

    • 用星号代替某个字来进行搜索
      • 搜*技巧 搜索结果中带有 搜*技巧的网页
  • OR(或): 组合搜索

    • 在各个关键词之间加上 OR 进行多个关键词搜索
      • vue OR react 搜索结果带有 vue 或者 react
  • ..(两个点): 数字范围搜索

    • 在某个数字范围内执行搜索
      • 手机2000..3000 搜索 2000 - 3000 的手机
  • site: 指定站点搜索

    • 在指定的网址对关键词进行搜索
      • github.com 前端学习资料 在 github 上搜索前端学习资料
  • filetype: 文件类型搜索

    • 对关键词进行指定文件类型的资源搜索
      • filetype:pdf JavaScript 搜索 JavaScript 的 pdf 文件
  • inurl: 页面 url 搜索

    • 在页面网址(url)对关键词进行搜索
      • inurl:javascript 搜索页面网址带有 javascript 的网页
  • intitle: 页面 title 搜索

    • 在页面标题(title)中对关键词进行搜索
      • intitle:react学习指南 搜索页面标题带有 react 学习指南的网页
  • intext: 页面内容搜索

    • 在页面正文对关键词进行搜索
      • intext:JavaScript 搜索页面正文带有 JavaScript 的网页

Google 搜索帮助

Github 常用技巧

常用 Github 搜索技巧

  • ""(双引号): 精确搜索

    • "react-admin"
      • 搜索结果中必须包含 react-admin
  • in: 限制搜索的范围

    • in:name [关键词]
      • 范围为仓库名称
    • in:description [关键词]
      • 范围为仓库描述
    • in:readme [关键词]
      • 范围为 readme
  • stars / forks: 限制搜索的 starfork

    • stars:>100
      • star 数大于 100
    • stars:>=100
      • star 数大于等于 100
    • stars:<100
      • star 数小于 100
    • stars:<=100
      • star 数小于等于 100
    • stars:100..200
      • star 数在 100 到 200 之间(闭区间)
  • language: 限制搜索的语言

    • language:html
  • created / pushed: 限制搜索的日期范围

    • created:>2020-01-01
      • 创建日期大于 2020-01-01
    • pushed:>2020-01-01
      • 更新日期大于 2020-01-01

Github 搜索帮助

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-28.html b/daily-notes/issue-28.html index 02246dd76..f104d1a81 100644 --- a/daily-notes/issue-28.html +++ b/daily-notes/issue-28.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在 Github Actions 环境变量中传递数组或对象

大多数常见下我们只需要传递简单的字符串即可,但是当字段越来越多的时候或者一些特殊场景下,使用对象或数组更好

通过研究,我们可以通过配置 json 数据 + 环境变量输出到文件来实现数组或对象的传递

配置 Secrets

Secrets 中的 NameValue 示例格式如下:

NameValue
JSON_DATAjson 数据

json 数据内容如下

json
[
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在 Github Actions 环境变量中传递数组或对象

大多数常见下我们只需要传递简单的字符串即可,但是当字段越来越多的时候或者一些特殊场景下,使用对象或数组更好

通过研究,我们可以通过配置 json 数据 + 环境变量输出到文件来实现数组或对象的传递

配置 Secrets

Secrets 中的 NameValue 示例格式如下:

NameValue
JSON_DATAjson 数据

json 数据内容如下

json
[
   {
     "name": "maomao"
   },
@@ -57,7 +57,7 @@
         run: |
           echo "$JSON_DATA" > ./config.json
           npm run install && node index.js

GitHub Actions 表达式语法

在 index.js 中引入 json 文件

js
const config = require('./config.json')

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-29.html b/daily-notes/issue-29.html index a5f190d7d..3642822a2 100644 --- a/daily-notes/issue-29.html +++ b/daily-notes/issue-29.html @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

CSS 伪类选择器中的表达式(an+b)

CSS 伪类选择器中的表达式有如下写法

  • 数字:直接匹配具体位置的元素
  • 关键字evenodd,根据奇偶去匹配
  • 表达式:根据 an + b 的结果去匹配

语法

只针对表达式场景的语法

:nth-child(an+b) 为例:该伪类选择器会先找到所有当前元素的兄弟元素,然后按照位置的先后顺序从 1 开始进行排序,再根据伪类选择器括号中的表达式 an+b 所计算出的值对元素进行匹配

  • an 中的 a 是一个整数,表示倍数
  • an 中的 n 是一个从 0 开始增长的自然数(即 n=0,1,2,3...)
  • b 是一个整数,表示偏移值(即初始位置)

示例

  • 0n+3:等同于 3,会匹配第三个元素
  • 1n+0:等同于 1n,会匹配所有元素
  • 2n+0:等同于 2n 和关键字(even),会匹配位置为 2、4、6、8...的元素,即偶数位元素
  • 2n+1:等同于关键字(odd),会匹配位置为 1、3、5、7... 的元素,即奇数位元素
  • 3n+4:会匹配位置为 4、7、10、13... 的元素
  • 4n-1:会匹配位置为 4-1、8-1、12-1... 的元素

反向匹配

an 的值为负数时为反向匹配,会匹配偏移值 b 之前的元素,并且 b 不能省略(此时最多匹配 b 个元素)

示例

  • -n+5:会匹配前五个元素
  • -2n+5:会匹配位置为 5-2*0、5-2*1、5-2*2(即位置为 5 3 1)的元素
  • -4n+10:会匹配位置为 10-4*0、10-4*1、10-4*2(即位置为 10 6 2)的元素

注意点

  • ab 都必须为整数
  • an 必须写在 b 的前面,不能写成 b+an
  • 元素位置从 1 开始,n 是从 0 开始增长的一个自然数
  • a 为负数时,b 不可省略

相关资料

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

CSS 伪类选择器中的表达式(an+b)

CSS 伪类选择器中的表达式有如下写法

  • 数字:直接匹配具体位置的元素
  • 关键字evenodd,根据奇偶去匹配
  • 表达式:根据 an + b 的结果去匹配

语法

只针对表达式场景的语法

:nth-child(an+b) 为例:该伪类选择器会先找到所有当前元素的兄弟元素,然后按照位置的先后顺序从 1 开始进行排序,再根据伪类选择器括号中的表达式 an+b 所计算出的值对元素进行匹配

  • an 中的 a 是一个整数,表示倍数
  • an 中的 n 是一个从 0 开始增长的自然数(即 n=0,1,2,3...)
  • b 是一个整数,表示偏移值(即初始位置)

示例

  • 0n+3:等同于 3,会匹配第三个元素
  • 1n+0:等同于 1n,会匹配所有元素
  • 2n+0:等同于 2n 和关键字(even),会匹配位置为 2、4、6、8...的元素,即偶数位元素
  • 2n+1:等同于关键字(odd),会匹配位置为 1、3、5、7... 的元素,即奇数位元素
  • 3n+4:会匹配位置为 4、7、10、13... 的元素
  • 4n-1:会匹配位置为 4-1、8-1、12-1... 的元素

反向匹配

an 的值为负数时为反向匹配,会匹配偏移值 b 之前的元素,并且 b 不能省略(此时最多匹配 b 个元素)

示例

  • -n+5:会匹配前五个元素
  • -2n+5:会匹配位置为 5-2*0、5-2*1、5-2*2(即位置为 5 3 1)的元素
  • -4n+10:会匹配位置为 10-4*0、10-4*1、10-4*2(即位置为 10 6 2)的元素

注意点

  • ab 都必须为整数
  • an 必须写在 b 的前面,不能写成 b+an
  • 元素位置从 1 开始,n 是从 0 开始增长的一个自然数
  • a 为负数时,b 不可省略

相关资料

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-3.html b/daily-notes/issue-3.html index 67f85f2c4..1b751f123 100644 --- a/daily-notes/issue-3.html +++ b/daily-notes/issue-3.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修改 CRA 的默认配置

使用 create-react-app 初始化项目

sh
# JavaScript 模板
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修改 CRA 的默认配置

使用 create-react-app 初始化项目

sh
# JavaScript 模板
 yarn create react-app my-app
 # OR
 npx create-react-app my-app
@@ -84,7 +84,7 @@
 }

再去 tsconfig.json 中使用 extends 配置引入

json
{
   "extends": "./paths.json"
 }

相关 issues

fb 真霸道,自己不用 alias,也不让用户搞

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-30.html b/daily-notes/issue-30.html index 49ca7f8ae..a75db3806 100644 --- a/daily-notes/issue-30.html +++ b/daily-notes/issue-30.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修复谷歌翻译失效

之前找的知乎帖不知道为啥被删除,这里做下记录

谷歌关闭了中国大陆的谷歌翻译服务,导致 chrome 内置翻译和扩展均不可用,但可以通过修改 hosts 继续使用

获取 IP 地址

方案一:通过 IP 查询工具

  1. 打开 https://ping.chinaz.com/translate.google.cn
  2. 选择物理距离最近(即通过 IP 归属地来选择响应最快的)

方案二:使用命令行获取 IP

sh
# 打开终端输入 ping 命令
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修复谷歌翻译失效

之前找的知乎帖不知道为啥被删除,这里做下记录

谷歌关闭了中国大陆的谷歌翻译服务,导致 chrome 内置翻译和扩展均不可用,但可以通过修改 hosts 继续使用

获取 IP 地址

方案一:通过 IP 查询工具

  1. 打开 https://ping.chinaz.com/translate.google.cn
  2. 选择物理距离最近(即通过 IP 归属地来选择响应最快的)

方案二:使用命令行获取 IP

sh
# 打开终端输入 ping 命令
 ping google.cn

修改 hosts

各系统 hosts 文件路径如下

  • Windows 系统:C:\Windows\System32\drivers\etc\hosts
  • Mac 系统:/etc/hosts
  • Linux 系统:/etc/hosts
  • Android 系统:/system/etc/hosts
  • iOS 系统:/etc/hosts
sh
220.181.174.162 translate.googleapis.com

注意点:

  • translate.googleapis.com 才是谷歌翻译的 API 地址
  • 220.181.174.162 为之前获取到的 IP 地址

推荐使用 Hosts 管理工具(SwitchHosts)修改

当前可用的 IP 库

sh
108.177.122.90 translate.googleapis.com
 142.250.0.90 translate.googleapis.com
 142.250.10.90 translate.googleapis.com
@@ -89,7 +89,7 @@
 216.58.209.174 translate.googleapis.com
 216.58.214.14 translate.googleapis.com
 216.58.220.142 translate.googleapis.com

谷歌翻译不能用的解决方案 | 划词翻译

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-31.html b/daily-notes/issue-31.html index f9bb0c943..599fd01ad 100644 --- a/daily-notes/issue-31.html +++ b/daily-notes/issue-31.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Next.js 搭建官网踩坑小记

依赖版本说明

  • Next.js 13
  • tailwindcss 3.x
  • postcss 8.x
  • antd 4.x

配置模块路径别名

Next.js9.4 起自动支持 tsconfig.jsonjsconfig.json 中的 "paths""baseUrl" 选项,因此可以不在 webpack 配置项中配置模块路径别名

新建 tsconfig.json 或者 jsconfig.json 文件

项目不使用 TypeScript 时使用 jsconfig.json 进行配置

json
{
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Next.js 搭建官网踩坑小记

依赖版本说明

  • Next.js 13
  • tailwindcss 3.x
  • postcss 8.x
  • antd 4.x

配置模块路径别名

Next.js9.4 起自动支持 tsconfig.jsonjsconfig.json 中的 "paths""baseUrl" 选项,因此可以不在 webpack 配置项中配置模块路径别名

新建 tsconfig.json 或者 jsconfig.json 文件

项目不使用 TypeScript 时使用 jsconfig.json 进行配置

json
{
   "compilerOptions": {
     "baseUrl": ".",
     "paths": {
@@ -121,7 +121,7 @@
 }
 
 module.exports = nextConfig

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-33.html b/daily-notes/issue-33.html index 399df6ef0..92df5d50c 100644 --- a/daily-notes/issue-33.html +++ b/daily-notes/issue-33.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

ShadowSocks PAC 用户自定规则

代理自动配置(Proxy auto-config 简称 PAC)是一种网页浏览器技术,用于定义如何自动选择适当的代理服务器来访问一个网址

ShadowSocks 默认使用的 GFWList 规则,当 GFWList 规则无法满足我们的要求时,就需要用到 PAC 用户自定规则

PAC 规则语法说明

在书写 PAC 用户自定规则前,我们需要先了解其规则语法,ShadowSocks 使用的是 Adblock Plus 的规则引擎

Adblock Plus filters 规则文档

大概规则如下

代理相关标识符

  • @@ 标识符(设置不使用代理的规则)
    • 🌰 @@*.example.com/* 满足 @@ 后规则的地址不使用代理

地址匹配相关规则

  • 通配符 *
    • *.example.com/* 在实际使用时可省略 *,比如 *.example.com/* 可以写成 .example.com/
  • 正则表达式:以 \ 开始和结束
    • 🌰 \[\w]+:\/\/example.com\
  • 匹配地址开始和结尾 |
    • 🌰 |http://example.com example.com| 分别表示以 http://example.com 开始和以 example.com 结束的地址
  • 开头标识符 ||
    • 🌰 ||example.comhttp://example.comhttps://example.comftp://example.com 等地址均满足条件,只用于匹配地址开头
  • 分隔符 ^ 表示除了字母、数字或者 _ - . % 之外的任何字符。
    • 🌰 http://example.com^ 表示 http://example.com/http://example.com:8000/ 均满足条件,而http://example.com.ar/ 不满足条件

其他

  • 注释 !
    • 🌰 ! 这是一条注释

常用 PAC 规则

个人常用

sh
! Put user rules line by line in this file.
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

ShadowSocks PAC 用户自定规则

代理自动配置(Proxy auto-config 简称 PAC)是一种网页浏览器技术,用于定义如何自动选择适当的代理服务器来访问一个网址

ShadowSocks 默认使用的 GFWList 规则,当 GFWList 规则无法满足我们的要求时,就需要用到 PAC 用户自定规则

PAC 规则语法说明

在书写 PAC 用户自定规则前,我们需要先了解其规则语法,ShadowSocks 使用的是 Adblock Plus 的规则引擎

Adblock Plus filters 规则文档

大概规则如下

代理相关标识符

  • @@ 标识符(设置不使用代理的规则)
    • 🌰 @@*.example.com/* 满足 @@ 后规则的地址不使用代理

地址匹配相关规则

  • 通配符 *
    • *.example.com/* 在实际使用时可省略 *,比如 *.example.com/* 可以写成 .example.com/
  • 正则表达式:以 \ 开始和结束
    • 🌰 \[\w]+:\/\/example.com\
  • 匹配地址开始和结尾 |
    • 🌰 |http://example.com example.com| 分别表示以 http://example.com 开始和以 example.com 结束的地址
  • 开头标识符 ||
    • 🌰 ||example.comhttp://example.comhttps://example.comftp://example.com 等地址均满足条件,只用于匹配地址开头
  • 分隔符 ^ 表示除了字母、数字或者 _ - . % 之外的任何字符。
    • 🌰 http://example.com^ 表示 http://example.com/http://example.com:8000/ 均满足条件,而http://example.com.ar/ 不满足条件

其他

  • 注释 !
    • 🌰 ! 这是一条注释

常用 PAC 规则

个人常用

sh
! Put user rules line by line in this file.
 ! See https://adblockplus.org/en/filter-cheatsheet
 
 ! Github 相关
@@ -45,7 +45,7 @@
 ! npmtrends 相关
 ||npmtrends.com
 ||npm-trends-proxy.uidotdev.workers.dev

注意点

  • 修改 PAC 用户自定规则后需要重启客户端才能生效
  • 修改 PAC 用户自定规则后需要重启客户端才能生效
  • 修改 PAC 用户自定规则后需要重启客户端才能生效

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-34.html b/daily-notes/issue-34.html index 341e7c0fb..e09615a40 100644 --- a/daily-notes/issue-34.html +++ b/daily-notes/issue-34.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

青龙定时任务管理面板

青龙(qinglong)是一款支持 python3javaScripttypescriptshell 的定时任务管理面板

安装和部署

安装 docker 或者 docker-compose

sh
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.14.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

docker-compose

部署青龙

docker 部署

sh
docker run -dit \
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

青龙定时任务管理面板

青龙(qinglong)是一款支持 python3javaScripttypescriptshell 的定时任务管理面板

安装和部署

安装 docker 或者 docker-compose

sh
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.14.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

docker-compose

部署青龙

docker 部署

sh
docker run -dit \
   -v $PWD/ql/data:/ql/data \
   -p 5700:5700 \
   --name qinglong \
@@ -68,7 +68,7 @@
 
 # 禁用两步登录
 ql resettfa

常用的定时任务库

京东薅羊毛

集合库不用都拉取,拉一个就行,重复脚本太多容易黑号

faker2 faker3

京东集合库(推荐)

打开订阅管理 - 新建订阅

  1. 名称:ql repo https://git.metauniverse-cn.com/https://github.com/shufflewzc/faker3.git "jd_|jx_|gua_|jddj_|jdCookie" "activity|backUp" "^jd[^_]|USER|function|utils|sendNotify|ZooFaker_Necklace.js|JDJRValidator_|sign_graphics_validate|ql|JDSignValidator|magic|depend|h5sts" "main"
  2. 定时规则:5 0 * * *

faker2 和 faker3 选一个拉就行

KR

京东集合库

打开订阅管理 - 新建订阅

  1. 名称:ql repo https://github.com/KingRan/KR.git "jd_|jx_|jdCookie" "activity|backUp" "^jd[^_]|USER|utils|function|sign|ql|JDJR"
  2. 定时规则:30 * * * *
  3. 文件后缀:js ts py
  4. 代理:https://ghproxy.com/(可选)

KR

  1. 下载 alook 浏览器
  2. 打开京东触屏版 https://home.m.jd.com
  3. 通过手机验证码登录
  4. 点击 工具箱 — 开发者工具 — Cookies

QLScript2 通知库

上面的两个集合库均已内置,可以不用拉取

打开订阅管理 - 新建订阅

  1. 名称:ql repo https://github.com/ccwav/QLScript2.git "jd_" "NoUsed" "ql|sendNotify|utils|USER_AGENTS|jdCookie|JS_USER_AGENTS"
  2. 定时规则:0
  3. 代理:https://ghproxy.com/(可选)
使用教程

其他库

其他说明

  • 加密脚本可能存在安全隐患,使用需谨慎
  • 加密脚本可能存在安全隐患,使用需谨慎
  • 加密脚本可能存在安全隐患,使用需谨慎

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-35.html b/daily-notes/issue-35.html index 5e1a18fb9..1eef88cf8 100644 --- a/daily-notes/issue-35.html +++ b/daily-notes/issue-35.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 Shell 脚本检查并配置 git user 信息

最近在使用 fnm 时,发现项目配置了 .node-version.nvmrc 文件时,可以自动切换 node 版本,于是我就想到可以利用 shell 脚本来帮我检查和修改 git user 信息,防止造成用公司信息提交到 github 的尴尬(毕竟主要用公司电脑写代码)

fnm 检测 .node-version 和 .nvmrc 源码地址

常用的 Shell 检测运算符

sh
# 检测 filename 是否为目录
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 Shell 脚本检查并配置 git user 信息

最近在使用 fnm 时,发现项目配置了 .node-version.nvmrc 文件时,可以自动切换 node 版本,于是我就想到可以利用 shell 脚本来帮我检查和修改 git user 信息,防止造成用公司信息提交到 github 的尴尬(毕竟主要用公司电脑写代码)

fnm 检测 .node-version 和 .nvmrc 源码地址

常用的 Shell 检测运算符

sh
# 检测 filename 是否为目录
 -d filename
 
 # 检测 filename 是否为普通文件
@@ -82,7 +82,7 @@
     fi
   fi
 fi

其他

其实配置 SSH Key 就没这么多事,但如果项目使用的是 https 源,则需要修改为 SSH 源,而且个人觉得 https 源方便,在浏览器上复制 url 就行

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-36.html b/daily-notes/issue-36.html index 0ac3438b9..cf47c5660 100644 --- a/daily-notes/issue-36.html +++ b/daily-notes/issue-36.html @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

不使用 JavaScript 来隐藏元素的若干方法

这是一道经典面试题,也是最近帮朋友解决稿定设计的水印时想了各种方案,所以在此总结下(目前就 11 种)

隐藏元素的若干方法 Demo

1. width height

修改元素的 width 或者 height 属性(需要配合 overflow: hidden; 使用)

特点

  1. 不占据空间
  2. 不响应事件
  3. 支持动画

2. display: none

使元素不再显示,其对布局不会有影响

特点

  1. 不占据空间
  2. 不响应事件
  3. 不支持动画

3. visibility: hidden

隐藏元素,但是其他元素的布局不改变,相当于此元素变成透明,将其子元素设为 visibility: visible 时则该子元素依然可见

visibility - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 不响应事件
  3. 不支持动画

4. relative + 负 z-index

当元素之间重叠的时候 z-index 较大的元素会覆盖较小的元素在上层进行显示。

将元素的 z-index 属性设置为负值来达到隐藏元素的效果(实际是将元素放在了我们看不到的层叠上下文中)

z-index - CSS:层叠样式表 | MDN

创建层叠上下文

层叠上下文 - CSS:层叠样式表 | MDN

  • 根元素
  • position 不为 static
  • flexgrid 容器的子元素且 z-index 值不为 auto
  • opacity 不为 1
  • transform 不为 none
  • filter 不为 none
  • backdrop-filter 不为 none
  • clip-path 不为 none
  • mask / mask-image / mask-border 不为 none
  • mix-blend-mode 不为 normal
  • containlayoutpaint 或包含它们其中之一的合成值
  • 设置了 isolation: isolate
  • 设置了 -webkit-overflow-scrolling: touch
  • 设置了 will-change

特点

  1. 占据空间
  2. 不响应事件
  3. 不支持动画

5. absolute + 负 left

通过 position: absolute; left: -9999px 将元素移除可视区域来达到隐藏元素的效果

特点

  1. 不占据空间
  2. 不响应事件
  3. 支持动画

6. color + background

将元素的颜色值属性 color background-color 设置为 transparent 达到隐藏元素的效果

特点

  1. 占据空间
  2. 响应事件
  3. 支持动画

7. clip clip-path

clip-path 属性使用裁剪方式创建元素的可显示区域,区域内的部分显示,区域外的隐藏。可以使用 clip-path: circle(0) 来将元素隐藏

clip-path(CSS:层叠样式表)—— MDN

特点

  1. 占据空间
  2. 不响应事件
  3. 支持动画

8. transform

transform 属性允许你旋转、缩放、倾斜或平移指定元素。可以使用 transform: scale(0) 来将元素隐藏,还可以使用 rotateY(90deg) skew(90deg) 等属性达到隐藏元素效果

transform - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 不响应事件
  3. 支持动画

9. opacity: 0

opacity 属性用于指定一个元素的不透明度

opacity 的属性值不为 1 时,会把元素放置在一个新的层叠上下文中

一个元素和它包含的子元素都会具有和元素背景相同的透明度,哪怕这个元素和它的子元素有不同的 opacity 属性值

opacity - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 响应事件
  3. 支持动画

10. filter: opacity(0)

opacity() 转化图像的透明程度(已有的 opacity 属性很相似,不同之处在于通过 filter,一些浏览器为了提升性能会提供硬件加速)

filter - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 响应事件
  3. 支持动画

11. 全局属性 hidden

全局属性 hidden 是一个布尔属性,如果一个元素设置了这个属性,它就不会被显示(本质上是使用 display: none

hidden - HTML(超文本标记语言) | MDN

特点

  1. 不占据空间
  2. 不响应事件
  3. 不支持动画

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

不使用 JavaScript 来隐藏元素的若干方法

这是一道经典面试题,也是最近帮朋友解决稿定设计的水印时想了各种方案,所以在此总结下(目前就 11 种)

隐藏元素的若干方法 Demo

1. width height

修改元素的 width 或者 height 属性(需要配合 overflow: hidden; 使用)

特点

  1. 不占据空间
  2. 不响应事件
  3. 支持动画

2. display: none

使元素不再显示,其对布局不会有影响

特点

  1. 不占据空间
  2. 不响应事件
  3. 不支持动画

3. visibility: hidden

隐藏元素,但是其他元素的布局不改变,相当于此元素变成透明,将其子元素设为 visibility: visible 时则该子元素依然可见

visibility - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 不响应事件
  3. 不支持动画

4. relative + 负 z-index

当元素之间重叠的时候 z-index 较大的元素会覆盖较小的元素在上层进行显示。

将元素的 z-index 属性设置为负值来达到隐藏元素的效果(实际是将元素放在了我们看不到的层叠上下文中)

z-index - CSS:层叠样式表 | MDN

创建层叠上下文

层叠上下文 - CSS:层叠样式表 | MDN

  • 根元素
  • position 不为 static
  • flexgrid 容器的子元素且 z-index 值不为 auto
  • opacity 不为 1
  • transform 不为 none
  • filter 不为 none
  • backdrop-filter 不为 none
  • clip-path 不为 none
  • mask / mask-image / mask-border 不为 none
  • mix-blend-mode 不为 normal
  • containlayoutpaint 或包含它们其中之一的合成值
  • 设置了 isolation: isolate
  • 设置了 -webkit-overflow-scrolling: touch
  • 设置了 will-change

特点

  1. 占据空间
  2. 不响应事件
  3. 不支持动画

5. absolute + 负 left

通过 position: absolute; left: -9999px 将元素移除可视区域来达到隐藏元素的效果

特点

  1. 不占据空间
  2. 不响应事件
  3. 支持动画

6. color + background

将元素的颜色值属性 color background-color 设置为 transparent 达到隐藏元素的效果

特点

  1. 占据空间
  2. 响应事件
  3. 支持动画

7. clip clip-path

clip-path 属性使用裁剪方式创建元素的可显示区域,区域内的部分显示,区域外的隐藏。可以使用 clip-path: circle(0) 来将元素隐藏

clip-path(CSS:层叠样式表)—— MDN

特点

  1. 占据空间
  2. 不响应事件
  3. 支持动画

8. transform

transform 属性允许你旋转、缩放、倾斜或平移指定元素。可以使用 transform: scale(0) 来将元素隐藏,还可以使用 rotateY(90deg) skew(90deg) 等属性达到隐藏元素效果

transform - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 不响应事件
  3. 支持动画

9. opacity: 0

opacity 属性用于指定一个元素的不透明度

opacity 的属性值不为 1 时,会把元素放置在一个新的层叠上下文中

一个元素和它包含的子元素都会具有和元素背景相同的透明度,哪怕这个元素和它的子元素有不同的 opacity 属性值

opacity - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 响应事件
  3. 支持动画

10. filter: opacity(0)

opacity() 转化图像的透明程度(已有的 opacity 属性很相似,不同之处在于通过 filter,一些浏览器为了提升性能会提供硬件加速)

filter - CSS:层叠样式表 | MDN

特点

  1. 占据空间
  2. 响应事件
  3. 支持动画

11. 全局属性 hidden

全局属性 hidden 是一个布尔属性,如果一个元素设置了这个属性,它就不会被显示(本质上是使用 display: none

hidden - HTML(超文本标记语言) | MDN

特点

  1. 不占据空间
  2. 不响应事件
  3. 不支持动画

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-37.html b/daily-notes/issue-37.html index 665f03076..9dc851a2e 100644 --- a/daily-notes/issue-37.html +++ b/daily-notes/issue-37.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

VuePress 迁移至 VitePress

为什么要从 VuePress 迁移至 VitePress

因为颜值即正义VitepressVuePress 好看太多太多了

安装依赖

依赖说明

  • node 18.x
  • pnpm 7.x
  • vitepress 1.0.0-alpha.46
  • vue 3.2.47
  • vuepress 2.0.0-beta.60 (标注之前用的 VuePress 版本)

创建 .npmrc 文件,配置内容如下(不使用 pnpm 的可以忽略)

sh
auto-install-peers=true
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

VuePress 迁移至 VitePress

为什么要从 VuePress 迁移至 VitePress

因为颜值即正义VitepressVuePress 好看太多太多了

安装依赖

依赖说明

  • node 18.x
  • pnpm 7.x
  • vitepress 1.0.0-alpha.46
  • vue 3.2.47
  • vuepress 2.0.0-beta.60 (标注之前用的 VuePress 版本)

创建 .npmrc 文件,配置内容如下(不使用 pnpm 的可以忽略)

sh
auto-install-peers=true
 
 registry=https://registry.npmmirror.com

安装 vitepress 相关依赖

sh
pnpm add -D vitepress vue

修改 package.json 中的 scripts

sh
# dev 命令
 npm pkg set scripts.dev="vitepress dev docs --port=8732"
@@ -187,7 +187,7 @@
       'nav-bar-title-after': () => h(Visitor)
     })
 })

颜值对比

不得不说差的有点多

首页

VuePress 首页VitePress 首页

内容页

VuePress 内容页VitePress 内容页

VuePress 内容页VitePress 内容页

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-38.html b/daily-notes/issue-38.html index b969f0c56..f60d9ad28 100644 --- a/daily-notes/issue-38.html +++ b/daily-notes/issue-38.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 VitePress 打造个人前端导航网站

最近,我的一个朋友向我展示了他的前端导航网站。恰巧我正在将自己的博客从 VuePress 升级到 VitePress。受到他的启发,我想基于 VitePress 打造一个自己的前端导航网站。

说明

  • 鉴于网上一大堆教你 VitePress 搭建自己的博客,本文就不在重复教你了,只说明下打造前端导航的重点部分

  • 如果你需要学习 VitePress 的基础知识,可以参考我的另一篇文章: 从 VuePress 迁移至 VitePress

环境和依赖

  • node 18.x
  • pnpm 7.x
  • vitepress 1.0.0-alpha.48

分析需求

首先,这个前端导航页只是博客中的一个模块,所以需要满足下面这些功能

  • 布局
    • 导航栏
    • 页脚
    • 本页目录(用于快速跳转)
  • 导航内容的 UI 样式应与整站的界面风格一致
    • 站点图标
    • 站点名称
    • 站点描述
    • 站点链接
  • 支持主题切换(毕竟 VitePress 自带了主题功能)

基于这些需求和我的一些懒人属性,我决定就地取材,从 VitePress 中搜刮我需要的元素,然后逐步开发和完善前端导航页面。

页面布局

基于就地取材,我们先来分析下 VitePress 提供的四种布局配置

  • layout: doc 文档布局(默认)
    • 解析 Markdown 内置 VitePress 提供的所有样式
    • 具有侧边栏、导航栏、页脚、本页目录
  • layout: page 页面布局
    • 解析 Markdown 但不会获得任何默认样式
    • 具有侧边栏、导航栏、页脚
  • layout: home 首页布局
    • 解析 Markdown 但不会获得任何默认样式
    • 具有侧边栏、导航栏、页脚
    • 支持 herofeatures
  • layout: false 无布局(纯空白页)
    • 解析 Markdown 但不会获得任何默认样式

综上考虑,我们选取 layout: doc 来开发

修改 VitePress 主题

因为 layout: doc 主要是提供给文档使用的,其页面宽度有限,同时为了更好的样式隔离,为其添加一个 layoutClass 方便我们更好的去自定义样式

docs/.vitepress/theme 目录下新建 index.ts 文件

ts
import { h, App } from 'vue'
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 VitePress 打造个人前端导航网站

最近,我的一个朋友向我展示了他的前端导航网站。恰巧我正在将自己的博客从 VuePress 升级到 VitePress。受到他的启发,我想基于 VitePress 打造一个自己的前端导航网站。

说明

  • 鉴于网上一大堆教你 VitePress 搭建自己的博客,本文就不在重复教你了,只说明下打造前端导航的重点部分

  • 如果你需要学习 VitePress 的基础知识,可以参考我的另一篇文章: 从 VuePress 迁移至 VitePress

环境和依赖

  • node 18.x
  • pnpm 7.x
  • vitepress 1.0.0-alpha.48

分析需求

首先,这个前端导航页只是博客中的一个模块,所以需要满足下面这些功能

  • 布局
    • 导航栏
    • 页脚
    • 本页目录(用于快速跳转)
  • 导航内容的 UI 样式应与整站的界面风格一致
    • 站点图标
    • 站点名称
    • 站点描述
    • 站点链接
  • 支持主题切换(毕竟 VitePress 自带了主题功能)

基于这些需求和我的一些懒人属性,我决定就地取材,从 VitePress 中搜刮我需要的元素,然后逐步开发和完善前端导航页面。

页面布局

基于就地取材,我们先来分析下 VitePress 提供的四种布局配置

  • layout: doc 文档布局(默认)
    • 解析 Markdown 内置 VitePress 提供的所有样式
    • 具有侧边栏、导航栏、页脚、本页目录
  • layout: page 页面布局
    • 解析 Markdown 但不会获得任何默认样式
    • 具有侧边栏、导航栏、页脚
  • layout: home 首页布局
    • 解析 Markdown 但不会获得任何默认样式
    • 具有侧边栏、导航栏、页脚
    • 支持 herofeatures
  • layout: false 无布局(纯空白页)
    • 解析 Markdown 但不会获得任何默认样式

综上考虑,我们选取 layout: doc 来开发

修改 VitePress 主题

因为 layout: doc 主要是提供给文档使用的,其页面宽度有限,同时为了更好的样式隔离,为其添加一个 layoutClass 方便我们更好的去自定义样式

docs/.vitepress/theme 目录下新建 index.ts 文件

ts
import { h, App } from 'vue'
 import { useData } from 'vitepress'
 import Theme from 'vitepress/theme'
 
@@ -378,7 +378,7 @@
 layoutClass: m-nav-layout
 + outline: [2, 3, 4]
 ---

防止我们的站点标题被收录到页面目录下

页面目录

最终效果展示

最终效果展示最终效果展示

后续可能会添加的功能

  • 支持隐藏标题、描述、icon
  • 布局大小设置

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-39.html b/daily-notes/issue-39.html index 613c3ad62..26c975217 100644 --- a/daily-notes/issue-39.html +++ b/daily-notes/issue-39.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

VitePress 生成站点地图

安装依赖

环境和依赖版本

  • node 18.x
  • pnpm 7.x
  • vitepress 1.0.0-alpha.51
  • sitemap 7.1.1
sh
pnpm add -D sitemap

修改配置文件

docs/.vitepress/config.ts

ts
import { createWriteStream } from 'node:fs'
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

VitePress 生成站点地图

安装依赖

环境和依赖版本

  • node 18.x
  • pnpm 7.x
  • vitepress 1.0.0-alpha.51
  • sitemap 7.1.1
sh
pnpm add -D sitemap

修改配置文件

docs/.vitepress/config.ts

ts
import { createWriteStream } from 'node:fs'
 import { resolve } from 'node:path'
 import { SitemapStream } from 'sitemap'
 import { defineConfig, PageData } from 'vitepress'
@@ -56,7 +56,7 @@
     await new Promise((r) => writeStream.on('finish', r))
   }
 })

相关 issues

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-4.html b/daily-notes/issue-4.html index 94d66cff0..b5e5085a0 100644 --- a/daily-notes/issue-4.html +++ b/daily-notes/issue-4.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 SVG 做动画

今天发现一个好玩的动画,想当然以为是 GIF 或者 CSS3 的成果,结果这想当然不靠谱,居然是 SVG 写的,于是就网上一堆操作寻找资料,自己再来个 demo

demo 代码及示例

其实 demo 是为了 2.0 准备的

在线示例

html
<!DOCTYPE html>
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 SVG 做动画

今天发现一个好玩的动画,想当然以为是 GIF 或者 CSS3 的成果,结果这想当然不靠谱,居然是 SVG 写的,于是就网上一堆操作寻找资料,自己再来个 demo

demo 代码及示例

其实 demo 是为了 2.0 准备的

在线示例

html
<!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
@@ -88,7 +88,7 @@
     </svg>
   </body>
 </html>

animate 相关语法介绍

只介绍用到的,其他的可以看下文的相关链接

  • attributeName: 要变化的元素属性名称

  • calcMode: 控制动画的速度

  • values: 给动画设置多个关键值点

  • dur: 动画的持续时间

  • begin: 动画的延迟时间

  • repeatCount: 动画执行的次数

相关资料

超级强大的 SVG SMIL animation 动画详解SVG 元素参考 | MDN

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-41.html b/daily-notes/issue-41.html index 24344bb1b..c5d937ad8 100644 --- a/daily-notes/issue-41.html +++ b/daily-notes/issue-41.html @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

获取软件内置浏览器的 User-Agent

有的时候我们需要获取软件内置浏览器的 User-Agent,以便于我们做一些特殊的处理

User-Agent

User-Agent(用户代理)是一个用于识别客户端(通常是网络浏览器)类型和版本的字符串。它是由客户端在向服务器发送请求时自动包含的头部信息之一

User-Agent 字符串提供了关于客户端应用程序、操作系统、设备和版本的信息,以便服务器可以根据这些信息提供适合客户端的响应内容。服务器可以根据 User-Agent 字符串来确定如何呈现网页、提供适当的样式和功能,或者根据客户端的能力做出其他定制化的处理

User-Agent - HTTP | MDN

获取 User-Agent

js
const userAgent = navigator.userAgent

解析 User-Agent

访问以下网站,在线解析 User-Agent

通过以下库,解析 User-Agent

以钉钉为例获取其内置浏览器的 User-Agent

AndroidiOS 版钉钉打开外部链接时,会调用钉钉内置浏览器打开,可以获取到钉钉内置浏览器的 User-Agent

但在 PC 版钉钉打开外部链接时,会调用默认浏览器打开,导致无法获取钉钉内置浏览器的 User-Agent 信息,这时我们可以通过钉钉的跳转协议去打开外部链接,这样就可以获取到钉钉内置浏览器的 User-Agent

在浏览器中打开以下链接,即可获取钉钉内置浏览器的 User-Agent

使用 User Agent String.Com 解析

sh
dingtalk://dingtalkclient/page/link?url=https%3A%2F%2Fwww.useragentstring.com&pc_slide=true

使用 UserAgentInfo 解析

sh
dingtalk://dingtalkclient/page/link?url=https%3A%2F%2Fwww.useragentinfo.com&pc_slide=true

钉钉内置浏览器的 User-Agent

sh
Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 DingTalk(7.0.10-macOS-28453097) nw Channel/201200 Architecture/x86_64

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

获取软件内置浏览器的 User-Agent

有的时候我们需要获取软件内置浏览器的 User-Agent,以便于我们做一些特殊的处理

User-Agent

User-Agent(用户代理)是一个用于识别客户端(通常是网络浏览器)类型和版本的字符串。它是由客户端在向服务器发送请求时自动包含的头部信息之一

User-Agent 字符串提供了关于客户端应用程序、操作系统、设备和版本的信息,以便服务器可以根据这些信息提供适合客户端的响应内容。服务器可以根据 User-Agent 字符串来确定如何呈现网页、提供适当的样式和功能,或者根据客户端的能力做出其他定制化的处理

User-Agent - HTTP | MDN

获取 User-Agent

js
const userAgent = navigator.userAgent

解析 User-Agent

访问以下网站,在线解析 User-Agent

通过以下库,解析 User-Agent

以钉钉为例获取其内置浏览器的 User-Agent

AndroidiOS 版钉钉打开外部链接时,会调用钉钉内置浏览器打开,可以获取到钉钉内置浏览器的 User-Agent

但在 PC 版钉钉打开外部链接时,会调用默认浏览器打开,导致无法获取钉钉内置浏览器的 User-Agent 信息,这时我们可以通过钉钉的跳转协议去打开外部链接,这样就可以获取到钉钉内置浏览器的 User-Agent

在浏览器中打开以下链接,即可获取钉钉内置浏览器的 User-Agent

使用 User Agent String.Com 解析

sh
dingtalk://dingtalkclient/page/link?url=https%3A%2F%2Fwww.useragentstring.com&pc_slide=true

使用 UserAgentInfo 解析

sh
dingtalk://dingtalkclient/page/link?url=https%3A%2F%2Fwww.useragentinfo.com&pc_slide=true

钉钉内置浏览器的 User-Agent

sh
Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 DingTalk(7.0.10-macOS-28453097) nw Channel/201200 Architecture/x86_64

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-42.html b/daily-notes/issue-42.html index 0716ac0f2..08b203302 100644 --- a/daily-notes/issue-42.html +++ b/daily-notes/issue-42.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修改 node_modules 中的依赖(打补丁)

为什么要修改 node_modules 中的依赖?

  1. 依赖包有 bug,但作者没有及时修复
  2. 依赖包的版本过旧,但不能升级到新版本
  3. 对依赖包的功能有定制化需求时

常见做法

  • 自己维护这个 npm
    • 维护成本较高,周期长
  • 直接修改 node_modules 中的依赖
    • 适合应急,周期短
    • 修改只在本地生效
    • 适合对 npm 包的修改不需要发布的情况
  • node_modules 中的依赖打补丁
    • 适合应急,周期短
    • 提交补丁文件后修改可在本地和远程生效
    • 适合对 npm 包的修改不需要发布的情况

什么是打补丁?

打补丁是一种在不修改原始文件的情况下对文件进行增量修改的技术,它可以用来修复 bug、添加功能、或者改变行为。

打补丁的原理是使用 diff 工具来比较两个文件(或目录)之间的差异,并生成一个补丁文件(patch file),这个补丁文件记录了如何从一个文件(或目录)变成另一个文件(或目录)所需要做的修改,然后使用 patch 工具来将补丁文件应用到原始文件(或目录)上,从而实现修改。

打补丁有以下优点:

  • 补丁文件通常很小,可以节省磁盘空间和网络带宽
  • 补丁文件可以被提交到版本控制系统中,方便追踪和管理
  • 补丁文件可以在不同的平台和环境中使用,提高兼容性和可移植性
  • 补丁文件可以在安装或更新依赖包后自动应用,减少手动操作

如何打补丁

不同的包管理器,打补丁的方法也不同,但其原理都是一样的

  1. 在项目目录下生成一个 patches 文件夹,里面存放着所有的补丁文件(其补丁内容为 diff 格式)
  2. npm install 后自动应用补丁

使用 pnpmyarn v2+

pnpmyarn v2+ 都提供了 patch 命令,可以直接使用

pnpm 为例

添加补丁,该命令会将指定的软件包提取到一个可以随意编辑的临时目录中供我们修改

sh
pnpm patch <pkg name>@<version>
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

修改 node_modules 中的依赖(打补丁)

为什么要修改 node_modules 中的依赖?

  1. 依赖包有 bug,但作者没有及时修复
  2. 依赖包的版本过旧,但不能升级到新版本
  3. 对依赖包的功能有定制化需求时

常见做法

  • 自己维护这个 npm
    • 维护成本较高,周期长
  • 直接修改 node_modules 中的依赖
    • 适合应急,周期短
    • 修改只在本地生效
    • 适合对 npm 包的修改不需要发布的情况
  • node_modules 中的依赖打补丁
    • 适合应急,周期短
    • 提交补丁文件后修改可在本地和远程生效
    • 适合对 npm 包的修改不需要发布的情况

什么是打补丁?

打补丁是一种在不修改原始文件的情况下对文件进行增量修改的技术,它可以用来修复 bug、添加功能、或者改变行为。

打补丁的原理是使用 diff 工具来比较两个文件(或目录)之间的差异,并生成一个补丁文件(patch file),这个补丁文件记录了如何从一个文件(或目录)变成另一个文件(或目录)所需要做的修改,然后使用 patch 工具来将补丁文件应用到原始文件(或目录)上,从而实现修改。

打补丁有以下优点:

  • 补丁文件通常很小,可以节省磁盘空间和网络带宽
  • 补丁文件可以被提交到版本控制系统中,方便追踪和管理
  • 补丁文件可以在不同的平台和环境中使用,提高兼容性和可移植性
  • 补丁文件可以在安装或更新依赖包后自动应用,减少手动操作

如何打补丁

不同的包管理器,打补丁的方法也不同,但其原理都是一样的

  1. 在项目目录下生成一个 patches 文件夹,里面存放着所有的补丁文件(其补丁内容为 diff 格式)
  2. npm install 后自动应用补丁

使用 pnpmyarn v2+

pnpmyarn v2+ 都提供了 patch 命令,可以直接使用

pnpm 为例

添加补丁,该命令会将指定的软件包提取到一个可以随意编辑的临时目录中供我们修改

sh
pnpm patch <pkg name>@<version>
 
 # 🌰
 pnpm patch @astrojs/cli-kit@0.2.3

生成补丁文件到项目中(默认保存在项目根目录下的 patches 目录中)

sh
# <path> 是之前提取的临时目录
@@ -42,7 +42,7 @@
 
 # 4. 生成补丁 <pkg name> 是上一步修改的依赖包名称
 npx patch-package <pkg name>

参考

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-43.html b/daily-notes/issue-43.html index 494505207..14691e271 100644 --- a/daily-notes/issue-43.html +++ b/daily-notes/issue-43.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 rollup 打包用户脚本(user script)

用户脚本 OR 油猴脚本

用户脚本(user script)是指在浏览器中运行的脚本,用于自定义网页的行为和外观。这些脚本可以修改网页内容、添加新的功能、自动执行任务、屏蔽广告、修改样式等等。在油猴(Tampermonkey)插件中,用户脚本也被称为油猴脚本,因为这个插件专门用于编写、运行、管理用户脚本

为什么要使用 rollup 打包

最近在更新我的 油猴脚本 —— 115 小助手 时有点越来越头大(维护不动了),其头大的原因有:

  • 单文件开发(代码量越来越大)
  • 公共函数需要手动复制粘贴
  • CSS 需要放在 JavaScript,没有智能提示
  • 虽说用了 TypeScript 但当时只想着有个 TypeScript 项目可以练手,不至于学了就忘

配置 rollup

安装 rollup(当前使用的是 3.x 版本)

sh
pnpm add -D rollup

编写 rollup 配置文件 rollup.config.js

js
import { defineConfig } from 'rollup'
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 rollup 打包用户脚本(user script)

用户脚本 OR 油猴脚本

用户脚本(user script)是指在浏览器中运行的脚本,用于自定义网页的行为和外观。这些脚本可以修改网页内容、添加新的功能、自动执行任务、屏蔽广告、修改样式等等。在油猴(Tampermonkey)插件中,用户脚本也被称为油猴脚本,因为这个插件专门用于编写、运行、管理用户脚本

为什么要使用 rollup 打包

最近在更新我的 油猴脚本 —— 115 小助手 时有点越来越头大(维护不动了),其头大的原因有:

  • 单文件开发(代码量越来越大)
  • 公共函数需要手动复制粘贴
  • CSS 需要放在 JavaScript,没有智能提示
  • 虽说用了 TypeScript 但当时只想着有个 TypeScript 项目可以练手,不至于学了就忘

配置 rollup

安装 rollup(当前使用的是 3.x 版本)

sh
pnpm add -D rollup

编写 rollup 配置文件 rollup.config.js

js
import { defineConfig } from 'rollup'
 
 import pkg from './package.json' assert { type: 'json' }
 
@@ -132,7 +132,7 @@
     })
   ]
 })

也可以使用 rollup-plugin-userscript

其他说明

  • 使用了 pnpm 作为包管理器,如果你使用的是 npmyarn,请自行替换命令
  • 完整的配置文件请参阅 tampermonkey-scripts | maomao

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-44.html b/daily-notes/issue-44.html index e744c88c3..6be3172e3 100644 --- a/daily-notes/issue-44.html +++ b/daily-notes/issue-44.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 shell 脚本复制项目信息到剪切板

这是去年朋友跟我交流的一个问题,最近在整理吃灰笔记时挖出来的(当时写了笔记,但没写完)

聊天记录
44-144-2

实现步骤

  1. 打开冰箱
  2. 把大象放进冰箱
  3. 关闭冰箱

1. 获取当前项目名

一般来说我们的项目名就是当前的文件夹名称

  • PWD: 表示当前工作目录的路径(一个常用的环境变量)

获取到当前工作目录的路径后,可以使用以下两种方法对其进行处理

使用 basename 命令

sh
$(basename $PWD)
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 shell 脚本复制项目信息到剪切板

这是去年朋友跟我交流的一个问题,最近在整理吃灰笔记时挖出来的(当时写了笔记,但没写完)

聊天记录
44-144-2

实现步骤

  1. 打开冰箱
  2. 把大象放进冰箱
  3. 关闭冰箱

1. 获取当前项目名

一般来说我们的项目名就是当前的文件夹名称

  • PWD: 表示当前工作目录的路径(一个常用的环境变量)

获取到当前工作目录的路径后,可以使用以下两种方法对其进行处理

使用 basename 命令

sh
$(basename $PWD)
 
 # 在终端中输出
 echo $(basename $PWD)

使用字符串操作

sh
${PWD##*/}
@@ -51,7 +51,7 @@
     echo "\033[33m当前目录不存在 .git 配置\033[0m"
   fi
 }

使用效果

使用效果

如果只关心将项目名和分支名复制到剪贴板,可直接使用配置别名版本

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-45.html b/daily-notes/issue-45.html index bcf17122a..ce81b9153 100644 --- a/daily-notes/issue-45.html +++ b/daily-notes/issue-45.html @@ -28,10 +28,10 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

浏览器的自动播放策略

最近有个项目被坑到了,正好记录一下

自动播放即网页加载完成后能否立即播放音视频

以 Chrome 为例(以下为自动播放策略)

  • 始终允许静音自动播放
  • 在以下情况下,允许带声音的自动播放
    • 用户已经在当前域进行了交互操作(点击触摸滑动等)
    • 用户将当前网站添加到移动设备上的主屏幕或在桌面上安装了 PWA
    • 在桌面设备上:用户的媒体互动指数超过一定阈值(意味着用户之前播放过有声视频)
  • iframe 会继承父级页面的自动播放策略(需要父窗口满足自动播放条件)

媒体互动指数

媒体互动指数 (MEI Media Engagement Index) 衡量的是个人在网站上观看媒体的倾向

Chrome 的方法是统计每个来源的访问次数与重要媒体播放事件的比率

  • 媒体(音频/视频)的用时必须超过 7 秒
  • 音频必须存在且已取消静音
  • 包含该视频的标签页处于有效状态
  • 视频的尺寸(以像素为单位)必须大于 200x140

MEI 是一个数字,可以在 about://media-engagement 中进行查看;其值越高,表示用户对该站点的媒体参与度越高

  • 媒体互动指数的计算规则不透明

  • 媒体互动指数的计算规则在不同的浏览器版本上可能会有差异

最佳实践

交互后播放

  1. 先尝试自动播放
  2. 自动播放失败后,引导用户进行交互
  3. 用户交互后再进行播放

一般会在视频区添加一个全局按钮,用户点击后触发交互操作,并自动播放

交互后播放声音

先静音播放,然后根据能否自动播放判断是否取消静音

  1. 能自动播放,取消静音
  2. 不能自动播放,引导用户进行交互操作后取消静音

关键点:通过 AudioContext 判断其上下文的状态

js
const ctx = new AudioContext();
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

浏览器的自动播放策略

最近有个项目被坑到了,正好记录一下

自动播放即网页加载完成后能否立即播放音视频

以 Chrome 为例(以下为自动播放策略)

  • 始终允许静音自动播放
  • 在以下情况下,允许带声音的自动播放
    • 用户已经在当前域进行了交互操作(点击触摸滑动等)
    • 用户将当前网站添加到移动设备上的主屏幕或在桌面上安装了 PWA
    • 在桌面设备上:用户的媒体互动指数超过一定阈值(意味着用户之前播放过有声视频)
  • iframe 会继承父级页面的自动播放策略(需要父窗口满足自动播放条件)

媒体互动指数

媒体互动指数 (MEI Media Engagement Index) 衡量的是个人在网站上观看媒体的倾向

Chrome 的方法是统计每个来源的访问次数与重要媒体播放事件的比率

  • 媒体(音频/视频)的用时必须超过 7 秒
  • 音频必须存在且已取消静音
  • 包含该视频的标签页处于有效状态
  • 视频的尺寸(以像素为单位)必须大于 200x140

MEI 是一个数字,可以在 about://media-engagement 中进行查看;其值越高,表示用户对该站点的媒体参与度越高

  • 媒体互动指数的计算规则不透明

  • 媒体互动指数的计算规则在不同的浏览器版本上可能会有差异

最佳实践

交互后播放

  1. 先尝试自动播放
  2. 自动播放失败后,引导用户进行交互
  3. 用户交互后再进行播放

一般会在视频区添加一个全局按钮,用户点击后触发交互操作,并自动播放

交互后播放声音

先静音播放,然后根据能否自动播放判断是否取消静音

  1. 能自动播放,取消静音
  2. 不能自动播放,引导用户进行交互操作后取消静音

关键点:通过 AudioContext 判断其上下文的状态

js
const ctx = new AudioContext();
 const canAutoPlay = ctx.state === 'running';
 ctx.close();

相关资料

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-46.html b/daily-notes/issue-46.html index 44332d64e..1c1cb81f4 100644 --- a/daily-notes/issue-46.html +++ b/daily-notes/issue-46.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

判断用户为移动端设备的若干种方式

判断 userAgent

userAgent 返回当前浏览器的用户代理字符串,通常用于判断客户端使用的操作系统、浏览器或其他软件信息

javascript
function isMobileAgent() {
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

判断用户为移动端设备的若干种方式

判断 userAgent

userAgent 返回当前浏览器的用户代理字符串,通常用于判断客户端使用的操作系统、浏览器或其他软件信息

javascript
function isMobileAgent() {
   const userAgent = navigator.userAgent.toLowerCase();
   return /iphone|ipad|ipod|ios|android|windows phone|blackberry|bb|playbook|opera mini|kindle|silk|fennec|mobile/.test(userAgent);
 }
  • iphone|ipad|ipod: 苹果移动设备
  • ios: iOS 系统(一些特殊情况)
  • android: 安卓设备
  • windows phone: Windows Phone 设备
  • blackberry|bb|playbook: 黑莓设备及其平板
  • opera mini: Opera Mini 浏览器,通常用于移动设备
  • kindle|silk: 亚马逊的 Kindle 和 Silk 浏览器
  • fennec: Firefox 移动版浏览器
  • mobile: 一个通用的关键字,通常出现在移动设备的用户代理字符串中

更全面的正则可参考 rustdesk/flutter/web/js/src/globals.js,代码简化如下

js
function isMobileAgent() {
@@ -67,7 +67,7 @@
 }

判断是否支持触摸事件

maxTouchPoints 返回当前设备支持的最大同时触摸接触点数

js
function isTouchDevice() {
   return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
 }

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-47.html b/daily-notes/issue-47.html index 2bdf0c419..44329cf8d 100644 --- a/daily-notes/issue-47.html +++ b/daily-notes/issue-47.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在 GitHub Actions 中触发其他仓库的 Actions

为了偷懒,在发布日常笔记时能够自动触发博客的构建和部署

以茂茂的两个笔记仓库举 🌰

生成并添加 GitHub 个人访问令牌

  1. 请参考 GitHub 官方文档:创建 personal access token确保选中了 workflows 权限
  2. 将生成的 GitHub 个人访问令牌添加到源仓库的 Secrets 中

详细教程请查看 配置 Secrets | 茂茂物语

在源仓库中创建工作流

在源仓库中创建或修改已有的 GitHub Actions 工作流文件,例如 .github/workflows/trigger-notes-workflow.yml,内容如下:

yaml
name: Trigger Notes Actions
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在 GitHub Actions 中触发其他仓库的 Actions

为了偷懒,在发布日常笔记时能够自动触发博客的构建和部署

以茂茂的两个笔记仓库举 🌰

生成并添加 GitHub 个人访问令牌

  1. 请参考 GitHub 官方文档:创建 personal access token确保选中了 workflows 权限
  2. 将生成的 GitHub 个人访问令牌添加到源仓库的 Secrets 中

详细教程请查看 配置 Secrets | 茂茂物语

在源仓库中创建工作流

在源仓库中创建或修改已有的 GitHub Actions 工作流文件,例如 .github/workflows/trigger-notes-workflow.yml,内容如下:

yaml
name: Trigger Notes Actions
 
 on:
   workflow_dispatch: # 手动触发
@@ -58,7 +58,7 @@
       - name: Checkout
         uses: actions/checkout@v3
       # 添加其他步骤,如安装依赖、构建等
  • on: repository_dispatch: types: [build-and-deploy]:监听来自 repository_dispatch 的自定义事件 build-and-deploy

按照以上步骤配置后,每当源仓库满足触发条件时,目标仓库的构建和部署流程将自动启动

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-48.html b/daily-notes/issue-48.html index 1fd99581e..0bd0a8c35 100644 --- a/daily-notes/issue-48.html +++ b/daily-notes/issue-48.html @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

漫画 APP 资源汇总

记录一些漫画 APP 和相关的图源插件

安卓漫画 APP

APK 版本说明

以 tachiyomiJ2K 举 🌰

  • tachiyomij2k-arm64-v8a-v1.7.4.apk: 64-bit ARM 架构的新版本安卓和平板设备
  • tachiyomij2k-armeabi-v7a-v1.7.4.apk: 32-bit ARM 架构的老版本安卓和平板设备
  • tachiyomij2k-v1.7.4.apk: 通用版本
  • tachiyomij2k-x86-v1.7.4.apk: 32 位 x86 架构的安卓平板电脑和模拟器
  • tachiyomij2k-x86_64-v1.7.4.apk: 64 位 x86 架构的安卓平板电脑和模拟器

推荐图源仓库

下载上面的 APK 安装后添加插件仓库即可使用(插件安装后需要信任才可使用)

相关项目

Yealico

Yealico 是 iOS 端看漫画、动漫和影视剧的神器

邀请码:66de08788bfc99a5ca6870b0533d8ac8

相关资料

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

漫画 APP 资源汇总

记录一些漫画 APP 和相关的图源插件

安卓漫画 APP

APK 版本说明

以 tachiyomiJ2K 举 🌰

  • tachiyomij2k-arm64-v8a-v1.7.4.apk: 64-bit ARM 架构的新版本安卓和平板设备
  • tachiyomij2k-armeabi-v7a-v1.7.4.apk: 32-bit ARM 架构的老版本安卓和平板设备
  • tachiyomij2k-v1.7.4.apk: 通用版本
  • tachiyomij2k-x86-v1.7.4.apk: 32 位 x86 架构的安卓平板电脑和模拟器
  • tachiyomij2k-x86_64-v1.7.4.apk: 64 位 x86 架构的安卓平板电脑和模拟器

推荐图源仓库

下载上面的 APK 安装后添加插件仓库即可使用(插件安装后需要信任才可使用)

相关项目

Yealico

Yealico 是 iOS 端看漫画、动漫和影视剧的神器

邀请码:66de08788bfc99a5ca6870b0533d8ac8

相关资料

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-5.html b/daily-notes/issue-5.html index 114ecdd06..30a93250a 100644 --- a/daily-notes/issue-5.html +++ b/daily-notes/issue-5.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Tree-Shaking 相关笔记

今天同事做完项目改造 Code Review 时,对 api 的导出形式有了点小讨论,于是今天的学习就有了

改造前

js
export const get1 = () => {}
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Tree-Shaking 相关笔记

今天同事做完项目改造 Code Review 时,对 api 的导出形式有了点小讨论,于是今天的学习就有了

改造前

js
export const get1 = () => {}
 
 export const get2 = () => {}
 
@@ -49,7 +49,7 @@
 const get = 'get'
 
 api[get + '1']()

再次打包分析,发现 tree-shaking 失效了,get1 get2 get3 都还在代码里面

在线 Demo

结论

  • 术语版:当你使用模块整体加载语法不使用属性名表达式时不影响 tree-shaking
  • 通俗版:当你 import * as xx from 'xxx' 引入一个模块,使用字符串拼接的形式调用 xx 的方法时是不可以去除没有用到的代码(今天有人说我被 997 搞的表达能力不行了)

相关知识点

Tree-Shaking 相关学习资料

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-50.html b/daily-notes/issue-50.html index cddf3de94..bc8b119f8 100644 --- a/daily-notes/issue-50.html +++ b/daily-notes/issue-50.html @@ -28,12 +28,12 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

从 VSCode 迁移到 Cursor

记录下最近从 VSCode 迁移到 Cursor 的配置过程

Cursor 是一款专为 AI 编程而构建的代码编辑器,它将 AI 助手集成到编辑器中,提供智能的代码补全、建议和解释,帮助开发者提高编码效率和代码质量

修改活动栏布局

Cursor 的活动栏默认是水平的,用起来很别扭

  1. 打开 VSCode,按 Ctrl/⌘ + , 打开设置
  2. 设置 workbench.activityBar.orientationvertical

Ctrl 为 Windows 下的快捷键, 为 Mac 下的快捷键

迁移 VSCode 的扩展、主题、设置、和快捷键

以下操作均在 Cursor 中完成

根据官网文档 Migrate from VS Code 的指引,操作步骤如下:

  1. Ctrl/⌘ + Shift + J 打开设置
  2. 点击 VS Code Import 栏下的 Import 按钮

导入后发现如下问题

  • settings.json 文件中丢失了注释
  • 未导入代码片段
  • 扩展导入不全
    • 很多扩展导入后无法正常使用(插件文件已导入,但扩展列表中没有)

经过一番折腾,发现还是手动导入好

手动导入 settings.json 和代码片段

方案一:直接复制文件

目录说明

  • Mac
    • VSCode 目录 /Users/电脑用户名/Library/Application Support/Code/User/
    • Cursor 目录 /Users/电脑用户名/Library/Application Support/Cursor/User/
  • Windows
    • VSCode 目录 C:\Users\电脑用户名\AppData\Roaming\Code\User
    • Cursor 目录 C:\Users\电脑用户名\AppData\Roaming\Cursor\User

文件说明

  • settings.json:用户的设置文件
  • snippets:用户的全局代码片段
  • keybindings.json:用户的自定义快捷键配置

方案二:在编辑器打开对应配置文件再复制

适合文件较少的配置

  • 打开 settings.json 文件
    • 打开 VSCode,按 Ctrl/⌘ + , 打开设置
    • 点击右上角的 打开设置 / Open Settings (JSON)
  • 打开代码片段文件
    • 点击左下角的设置按钮
  1. 打开 VSCode,按 Ctrl/⌘ + , 打开设置
  2. 点击右上角的 打开设置 / Open Settings (JSON)
  3. 复制 settings.json 文件中的内容
  4. 打开 Cursor,按 Ctrl/⌘ + , 打开设置
  5. 点击右上角的 打开设置 / Open Settings (JSON)
  6. 将复制的内容粘贴到打开的 settings.json 文件中

手动导入扩展

1. 获取 VSCode 的扩展列表

sh
code --list-extensions > $HOME/vscode_extensions.txt

获取后可以编辑 vscode_extensions.txt 文件挑选需要的扩展

2. 在 Cursor 中安装扩展

使用 while 循环逐行读取扩展列表并安装

sh
while read extension; do
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

从 VSCode 迁移到 Cursor

记录下最近从 VSCode 迁移到 Cursor 的配置过程

Cursor 是一款专为 AI 编程而构建的代码编辑器,它将 AI 助手集成到编辑器中,提供智能的代码补全、建议和解释,帮助开发者提高编码效率和代码质量

修改活动栏布局

Cursor 的活动栏默认是水平的,用起来很别扭

  1. 打开 VSCode,按 Ctrl/⌘ + , 打开设置
  2. 设置 workbench.activityBar.orientationvertical

Ctrl 为 Windows 下的快捷键, 为 Mac 下的快捷键

迁移 VSCode 的扩展、主题、设置、和快捷键

以下操作均在 Cursor 中完成

根据官网文档 Migrate from VS Code 的指引,操作步骤如下:

  1. Ctrl/⌘ + Shift + J 打开设置
  2. 点击 VS Code Import 栏下的 Import 按钮

导入后发现如下问题

  • settings.json 文件中丢失了注释
  • 未导入代码片段
  • 扩展导入不全
    • 很多扩展导入后无法正常使用(插件文件已导入,但扩展列表中没有)

经过一番折腾,发现还是手动导入好

手动导入 settings.json 和代码片段

方案一:直接复制文件

目录说明

  • Mac
    • VSCode 目录 /Users/电脑用户名/Library/Application Support/Code/User/
    • Cursor 目录 /Users/电脑用户名/Library/Application Support/Cursor/User/
  • Windows
    • VSCode 目录 C:\Users\电脑用户名\AppData\Roaming\Code\User
    • Cursor 目录 C:\Users\电脑用户名\AppData\Roaming\Cursor\User

文件说明

  • settings.json:用户的设置文件
  • snippets:用户的全局代码片段
  • keybindings.json:用户的自定义快捷键配置

方案二:在编辑器打开对应配置文件再复制

适合文件较少的配置

  • 打开 settings.json 文件
    • 打开 VSCode,按 Ctrl/⌘ + , 打开设置
    • 点击右上角的 打开设置 / Open Settings (JSON)
  • 打开代码片段文件
    • 点击左下角的设置按钮
  1. 打开 VSCode,按 Ctrl/⌘ + , 打开设置
  2. 点击右上角的 打开设置 / Open Settings (JSON)
  3. 复制 settings.json 文件中的内容
  4. 打开 Cursor,按 Ctrl/⌘ + , 打开设置
  5. 点击右上角的 打开设置 / Open Settings (JSON)
  6. 将复制的内容粘贴到打开的 settings.json 文件中

手动导入扩展

1. 获取 VSCode 的扩展列表

sh
code --list-extensions > $HOME/vscode_extensions.txt

获取后可以编辑 vscode_extensions.txt 文件挑选需要的扩展

2. 在 Cursor 中安装扩展

使用 while 循环逐行读取扩展列表并安装

sh
while read extension; do
   cursor --install-extension "$extension" --force
 done < $HOME/vscode_extensions.txt
  • --force 参数用于强制安装扩展
  • 安装完成后,运行 rm $HOME/vscode_extensions.txt 删除扩展列表文件

一键迁移命令

sh
code --list-extensions | while read extension; do
   cursor --install-extension "$extension" --force
-done

扩展安装失败

使用上述命令后,还是会有些扩展安装失败,需要手动安装

命令行提示找不到扩展

命令行提示找不到扩展

手动搜索是可以的

手动搜索是可以的

语言包

迁移插件时不会迁移语言包,需要手动安装

安装语言包

sh
cursor --install-extension MS-CEINTL.vscode-language-pack-zh-hans

修改设置

  1. 打开设置面板 Ctrl/⌘ + Shift + P
  2. 输入 Configure Display Language
  3. 选择 zh-cn

Cursor 使用技巧

AI 快捷键

  • Ctrl/⌘ + K 在光标处插入 AI 生成的代码
  • Ctrl/⌘ + I 对选中的代码进行快速智能编辑和补全,直接在编辑器中显示建议
  • Ctrl/⌘ + Shift + I 打开独立的智能编辑面板,提供更详细的编辑建议和交互选项(功能和 Ctrl/⌘ + I 一样)
  • Ctrl/⌘ + L 打开 AI 聊天面板,可以与 AI 进行对话交互

聊天中的 @ 符号

在 AI 对话框中可以使用 @ 符合添加对应上下文

  • @Files 引入文件,使用文件内容进行 AI 分析
  • @Folders 引入文件夹,可以让 AI 了解整个项目结构
  • @Code 当前选中的代码,将选中的代码片段发送给 AI 分析
  • @Docs 引用内置的第三方文档内容进行 AI 分析
  • @Git 引入 Git 相关信息,如提交历史、分支等
  • @Codebase 引入整个代码库的上下文,让 AI 了解项目全貌
  • @Web 允许 AI 访问网络资源获取信息
  • @Chat 引用之前的对话内容
  • @Definitions 引入代码中的定义,如函数、类等

提示词

Cursor Directory 收录了大量 Cursor 的提示词,可以参考使用

.cursorignore 文件

Cursor 会根据 .cursorignore 文件中的内容忽略一些文件或文件夹,可以用来排除一些不希望被 AI 分析的文件

如有转载或 CV 的请标注本站原文地址

- +done

扩展安装失败

使用上述命令后,还是会有些扩展安装失败,需要手动安装

命令行提示找不到扩展

命令行提示找不到扩展

手动搜索是可以的

手动搜索是可以的

语言包

迁移插件时不会迁移语言包,需要手动安装

安装语言包

sh
cursor --install-extension MS-CEINTL.vscode-language-pack-zh-hans

修改设置

  1. 打开设置面板 Ctrl/⌘ + Shift + P
  2. 输入 Configure Display Language
  3. 选择 zh-cn

Cursor 使用技巧

AI 快捷键

  • Ctrl/⌘ + K 在光标处插入 AI 生成的代码
  • Ctrl/⌘ + I 对选中的代码进行快速智能编辑和补全,直接在编辑器中显示建议
  • Ctrl/⌘ + Shift + I 打开独立的智能编辑面板,提供更详细的编辑建议和交互选项(功能和 Ctrl/⌘ + I 一样)
  • Ctrl/⌘ + L 打开 AI 聊天面板,可以与 AI 进行对话交互

聊天中的 @ 符号

在 AI 对话框中可以使用 @ 符合添加对应上下文

  • @Files 引入文件,使用文件内容进行 AI 分析
  • @Folders 引入文件夹,可以让 AI 了解整个项目结构
  • @Code 当前选中的代码,将选中的代码片段发送给 AI 分析
  • @Docs 引用内置的第三方文档内容进行 AI 分析
  • @Git 引入 Git 相关信息,如提交历史、分支等
  • @Codebase 引入整个代码库的上下文,让 AI 了解项目全貌
  • @Web 允许 AI 访问网络资源获取信息
  • @Chat 引用之前的对话内容
  • @Definitions 引入代码中的定义,如函数、类等

提示词

Cursor Directory 收录了大量 Cursor 的提示词,可以参考使用

.cursorignore 文件

Cursor 会根据 .cursorignore 文件中的内容忽略一些文件或文件夹,可以用来排除一些不希望被 AI 分析的文件

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-51.html b/daily-notes/issue-51.html new file mode 100644 index 000000000..cb2fc3b2f --- /dev/null +++ b/daily-notes/issue-51.html @@ -0,0 +1,35 @@ + + + + + + 魅族 21 Pro 安装 Google 服务 | 茂茂物语 + + + + + + + + + + + + + + + + + + + + + + + + +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

魅族 21 Pro 安装 Google 服务

记录下安装 Google 服务的过程,方便后续参考

开启谷歌服务

  1. 打开 设置
  2. 点击 辅助功能
  3. 开启 谷歌基础服务

登录谷歌账号

  1. 打开 设置
  2. 点击 辅助功能
  3. 点击 Google
  4. 点击 Google 账号 进行登录

更新 Google Play 服务

默认情况下 Google Play 不会显示在桌面,需要手动更新才能显示

  1. 打开 Google Play Store | APKMirror
  2. 下拉找到 All versions 点击最新版本(默认第一个为最新版本)
  3. 在新页面的 Download Google Play Store xx.xx.xx 中找到带 APK 标签的进行下载和安装

安装谷歌相机

如有转载或 CV 的请标注本站原文地址

+ + + + \ No newline at end of file diff --git a/daily-notes/issue-6.html b/daily-notes/issue-6.html index 1ee895e3a..ae6f2a0b4 100644 --- a/daily-notes/issue-6.html +++ b/daily-notes/issue-6.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在项目中使用 ESLint 和 Prettier(以 React + TypeScript 为例)

使用 CRA 初始化项目

sh
npx create-react-app my-app --template typescript
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在项目中使用 ESLint 和 Prettier(以 React + TypeScript 为例)

使用 CRA 初始化项目

sh
npx create-react-app my-app --template typescript
 # or
 yarn create react-app my-app --template typescript

使用 ESLint

安装依赖

CRA 自带了 eslint,不用额外安装

sh
yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react

配置文件 .eslintrc.js 介绍

根目录新建 .eslintrc.js 文件

js
module.exports = {
   // 运行环境
@@ -75,7 +75,7 @@
   ]
 }
  1. .prettierignore

配置 Prettier 忽略文件

sh
package.json
 tsconfig.json

添加脚本命令

package.jsonscripts 配置项中写入 "fix": "prettier --write ./src"

相关资料

ESLint RulesPrettier Options

其他

使用 husky、lint-staged、commitlint 构建前端工作流

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-7.html b/daily-notes/issue-7.html index 417bec51d..19dbbe5b2 100644 --- a/daily-notes/issue-7.html +++ b/daily-notes/issue-7.html @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 jsdelivr 加速 Github 仓库资源

当我们使用 Github 仓库资源时,会因为一些奇怪的原因而掉链子,但我们可以通过 jsdelivr 做 CDN 加速

jsdelivr 是一个免费的开源 CDN

使用方式

https://cdn.jsdelivr.net/gh/ Github 用户名/仓库名/资源路径

默认会访问 master 分支下的资源,可以通过 仓库名拼接 @ + release / commit / branch 来访问特定版本下的资源

例子

https://raw.githubusercontent.com/maomao1996/Vue-mmPlayer/master/screenshots/1.jpg

https://cdn.jsdelivr.net/gh/maomao1996/Vue-mmPlayer/screenshots/1.jpg

github 转 jsdelivr 链接 | 在线工具

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 jsdelivr 加速 Github 仓库资源

当我们使用 Github 仓库资源时,会因为一些奇怪的原因而掉链子,但我们可以通过 jsdelivr 做 CDN 加速

jsdelivr 是一个免费的开源 CDN

使用方式

https://cdn.jsdelivr.net/gh/ Github 用户名/仓库名/资源路径

默认会访问 master 分支下的资源,可以通过 仓库名拼接 @ + release / commit / branch 来访问特定版本下的资源

例子

https://raw.githubusercontent.com/maomao1996/Vue-mmPlayer/master/screenshots/1.jpg

https://cdn.jsdelivr.net/gh/maomao1996/Vue-mmPlayer/screenshots/1.jpg

github 转 jsdelivr 链接 | 在线工具

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/daily-notes/issue-8.html b/daily-notes/issue-8.html index acbe39213..c60ac9e58 100644 --- a/daily-notes/issue-8.html +++ b/daily-notes/issue-8.html @@ -28,7 +28,7 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 huskylint-stagedcommitlint 构建前端工作流

作用

可以帮助我们在 commit 前,对代码和 commit messages 进行 lint

介绍

  • husky 是一个 Git Hooks 工具,让你操作 Git Hooks 变得更容易
  • lint-staged 可以只对 git 暂存文件运行 lint 从而提高速度
  • commitlint 检查 git commit messages 是否符合规范
  • commitizen 获得有关提交消息格式的即时反馈,并提示您输入必填字段。

安装

sh
yarn add -D husky lint-staged @commitlint/cli @commitlint/config-conventional commitizen cz-conventional-changelog

使用

  • package.json
json
{
+    
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

使用 huskylint-stagedcommitlint 构建前端工作流

作用

可以帮助我们在 commit 前,对代码和 commit messages 进行 lint

介绍

  • husky 是一个 Git Hooks 工具,让你操作 Git Hooks 变得更容易
  • lint-staged 可以只对 git 暂存文件运行 lint 从而提高速度
  • commitlint 检查 git commit messages 是否符合规范
  • commitizen 获得有关提交消息格式的即时反馈,并提示您输入必填字段。

安装

sh
yarn add -D husky lint-staged @commitlint/cli @commitlint/config-conventional commitizen cz-conventional-changelog

使用

  • package.json
json
{
   "...": "...",
   "scripts": {
     "commit": "git-cz"
@@ -50,7 +50,7 @@
 }
  • 根目录创建 commitlint.config.js
js
module.exports = {
   extends: ['@commitlint/config-conventional']
 }

@commitlint/config-conventional type 说明

type含义
feat新功能
fix修复 bug
docs修改文档
style代码格式修改
refactor重构(即不是新增功能,也不是修复 bug)
perf更改代码以提高性能
test增加测试
build构建过程或辅助工具的变动
ci修改项目持续集成流程
chore其他类型的提交
revert恢复上一次提交

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/daily-notes/issue-9.html b/daily-notes/issue-9.html index d3cfa09d6..c1aa49f41 100644 --- a/daily-notes/issue-9.html +++ b/daily-notes/issue-9.html @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

package.json 相关知识

版本说明

字段说明
^1.0.0会匹配所有 1.x.x版本,保持一致 major version (大于等于当前版本,小于 2.0.0)
~1.0.0会匹配所有 1.0.x版本,保持一致 minor version (大于等于当前版本,小于 1.1.0)
1.x会根据 x 的位置来匹配对应规则

npm 包入口文件定义

字段说明

字段说明支持环境
main用于指定 npm 包的入口文件browser / node
module用于指定 es modules 规范的入口文件browser / node
browser用于指定 npm 包在 browser 环境下的入口文件browser

优先级说明

详细资料 - package.json 中 你还不清楚的 browser,module,main 字段优先级

流程图

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

package.json 相关知识

版本说明

字段说明
^1.0.0会匹配所有 1.x.x版本,保持一致 major version (大于等于当前版本,小于 2.0.0)
~1.0.0会匹配所有 1.0.x版本,保持一致 minor version (大于等于当前版本,小于 1.1.0)
1.x会根据 x 的位置来匹配对应规则

npm 包入口文件定义

字段说明

字段说明支持环境
main用于指定 npm 包的入口文件browser / node
module用于指定 es modules 规范的入口文件browser / node
browser用于指定 npm 包在 browser 环境下的入口文件browser

优先级说明

详细资料 - package.json 中 你还不清楚的 browser,module,main 字段优先级

流程图

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/efficiency/bookmark-scripts.html b/efficiency/bookmark-scripts.html index 52e885fae..6146e0a0c 100644 --- a/efficiency/bookmark-scripts.html +++ b/efficiency/bookmark-scripts.html @@ -38,7 +38,7 @@ document.querySelector('#column-left').style.display = document.querySelector('#column-left').style.display === 'none' ? 'block' : 'none' })()

切换 Telegram 侧边栏显隐

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/online-tools.html b/efficiency/online-tools.html index ee550f4de..bebeff1df 100644 --- a/efficiency/online-tools.html +++ b/efficiency/online-tools.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

在线工具

开发常用

沙箱

正则

代码编译

JS 相关

Vue

CSS 预处理器

代码生成

CSS 相关

SVG 相关

CDN

图片处理

在线抠图

图片压缩

图片生成

作图工具

文件处理

  • 在线格式转换
    • CloudConvert 在线文件转换器,支持 200+ 种格式、支持自定义设置、图片可在线预览(英文界面)
    • Convertio 在线转换文件的简单工具,支持 300+ 种格式、支持自定义设置(最大 100M)
  • PDF Editor Free 在线编辑 PDF 文件

休闲娱乐

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/software/android.html b/efficiency/software/android.html index 6341e7531..6ae0e232c 100644 --- a/efficiency/software/android.html +++ b/efficiency/software/android.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Android 平台

Legado 阅读

  1. 自定义书源,自己设置规则,抓取网页数据,规则简单易懂,软件内有规则说明
  2. 列表书架,网格书架自由切换
  3. 书源规则支持搜索及发现,所有找书看书功能全部自定义,找书更方便
  4. 订阅内容,可以订阅想看的任何内容,看你想看
  5. 支持替换净化,去除广告替换内容很方便
  6. 支持本地 TXT、EPUB 阅读,手动浏览,智能扫描
  7. 支持高度自定义阅读界面,切换字体、颜色、背景、行距、段距、加粗、简繁转换等
  8. 支持多种翻页模式,覆盖、仿真、滑动、滚动等
  9. 软件开源,持续优化,无广告

legado | Github

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/software/browser.html b/efficiency/software/browser.html index cda288141..73d06144a 100644 --- a/efficiency/software/browser.html +++ b/efficiency/software/browser.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

浏览器设置与扩展

扩展商店

体验优化

翻译

  • Relingo 识别网站中的生词并翻译(可根据自己的情况设置英语等级)、YouTube 支持双语字幕,生词高亮字幕
  • 沉浸式翻译 免费的又好用的沉浸式双语对照翻译
  • Saladict 沙拉查词 一款专业划词翻译扩展,为交叉阅读而生。涵盖中英日韩法德西语,支持复杂的划词操作、网页翻译、生词本与 PDF 浏览
  • 彩云小译 全文翻译(中英对照)
  • 划词翻译 划词翻译

开发常用

  • Vue.js devtools 用于调试 Vue.js 应用程序
  • React Developer Tools 用于调试 React 应用程序
  • Redux DevTools 用于调试应用程序 Redux 状态更改
  • WEB 前端助手(FeHelper) 包括字符串编解码、图片 base64 编码、代码压缩、美化、JSON 格式化、正则表达式、时间转换工具、二维码生成器、编码规范检测、页面性能检测、栅格检测、JS 运行效率分析
  • Lighthouse 网站性能测评工具
  • JSON Formatter JSON 格式化
  • 掘金 在新标签页展示聚合内容,包含前端、Android、iOS、后端、产品、设计六大频道,每个频道内都有一到多个内容源

GitHub 相关

油猴

油猴脚本推荐

其他工具

技巧

打开不安全网页

在当前页面任意地方点击,直接输入 thisisunsafe 后回车就能访问

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/software/cross-platform.html b/efficiency/software/cross-platform.html index 3982a3b1c..c2c9336f3 100644 --- a/efficiency/software/cross-platform.html +++ b/efficiency/software/cross-platform.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

多平台软件

效率神器 uTools

  1. 强大的插件化
  2. 多功能输入框,支持文本、截图、图片、文件、文件夹
  3. 自动识别 / 粘贴
  4. 全局快捷键
  5. 云端数据同步
  6. 支持 Windows、Mac、Linux

软件官网

下载神器 Motrix

  1. 界面清爽简洁
  2. 支持 BT 和磁力链任务
  3. 支持选择性下载 BT 部分文件
  4. 基于 Aria2
  5. 自动更新 Tracker 服务器列表

brew 安装

sh
brew install motrix

SwitchHosts

Hosts 管理工具

  1. Hosts 文件语法高亮
  2. 快速切换 Hosts
  3. 在线 Hosts 方案
  4. 系统托盘图标快速切换

brew 安装

sh
brew install --cask switchhosts

SwitchHosts | Github

QtScrcpy

通过 USB 或 TCP/IP 连接 Android 设备,并进行显示和控制

  1. 不需要 root 权限
  2. 最多支持 16 个安卓设备同时连接
  3. 支持自定义按键映射
  4. 可同时控制所有连接设备

QtScrcpy | Github

图床工具 PicGo

一个用于快速上传图片并获取图片 URL 链接的工具

  1. 支持 GitHub、七牛云、腾讯云、又拍云、阿里云 OSS、SM.MS V2、Imgur
  2. 支持拖拽图片上传
  3. 支持快捷键上传剪贴板里第一张图片
  4. 支持右键图片文件通过菜单上传
  5. 支持自定义复制到剪贴板的链接格式、
  6. 丰富的插件系统

Sourcetree

  1. 界面简洁、美观
  2. 简化 Git 日常操作,对新人友好易上手
  3. 支持 Git 工作流,规范开发流程
  4. 支持 Git 和 Mercurial 两种 VCS
  5. 支持自定义脚本执行

性能优化设置

  1. 打开 设置 => Diff
  2. 忽略文件模式 中添加 package-lock.json, yarn.lock

brew 安装

sh
brew install --cask sourcetree

软件官网

无损音视频切割合并神器 LosslessCut

  1. 免费开源、支持中文
  2. 简单易用
  3. 无损切割合并音视频(无须重新编码)

LosslessCut | Github

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/software/mac.html b/efficiency/software/mac.html index e5a7ba32d..867f45569 100644 --- a/efficiency/software/mac.html +++ b/efficiency/software/mac.html @@ -144,7 +144,7 @@ # 卸载 sudo wechattweak-cli --uninstall

WeChatTweak-macOS | Github

IINA

视频播放器

  1. 界面简洁、美观,契合 macOS 设计风格
  2. 功能强大,设置以播放体验为中心
  3. 支持鼠标和触控板手势
  4. 在线字幕、缩略图预览、画中画等

brew 安装

sh
brew install --cask iina

MacZip

专为 macOS 而设计的压缩软件

  1. 界面简洁、美观,完美兼容 Mojave
  2. 支持超过 20 种压缩格式
  3. 批量文件加密

软件官网

腾讯柠檬清理

  1. 界面简洁清新
  2. 支持垃圾清理、文件查重、软件卸载
  3. 支持微信、QQ、XCode、Sketch 深度扫描清理

软件官网

截图神器 IShot

  1. 区域截图、窗口截图、多窗口截图、延时截图、长截图、滚动截图
  2. 快速标注(矩形、圆形、横线、箭头、画笔、马赛克、文字标记、序号标签、局部高亮)
  3. 支持截图导圆角、阴影调节
  4. 贴图、取色

超级右键 iRightMouse

  1. 多种格式的右键新建文件
  2. 快速移动文件
  3. 常用目录设置
  4. 快速打开终端、vscode 等

翻译软件 Bob

  1. 支持划词、截图、输入翻译
  2. 支持翻译多开
  3. 自动识别语种
  4. 可自定义插件

菜单栏图标管理 Hidden Bar

  1. 简单易用、支持全局快捷键
  2. 免费开源、支持中文

brew 安装

sh
brew install --cask hiddenbar

音量管理 BackgroundMusic

  1. 背景音乐管理
  2. 设置各个应用程序的音量
  3. 录制系统音频

brew 安装

sh
brew install --cask background-music

BackgroundMusic | Github

窗口管理神器 Rectangle

比系统分屏更强大,支持快捷键分屏、支持三个及以上分屏

brew 安装

sh
brew install --cask rectangle

应用快捷启动神器 Thor Launcher

通过设定快捷键,快速在应用之间切换

快捷键提示 CheatSheet

长按 Command 即可查看当前应用的快捷键提示

显示器控制 MonitorControl

  1. 控制外接显示器的亮度和音量
  2. 支持键盘控制亮度和音量

brew 安装

sh
brew install --cask monitorcontrol

MonitorControl | Github

显示器设置 BetterDisplay

主要用于解决外接显示器不清晰问题(4k 以下),部分功能与 MonitorControl 重叠

  1. 解锁 HiDPI (Retina 显示)
  2. 自定义分辨率
  3. 创建虚拟显示器
  4. 创建显示器的画中画窗口
  5. 控制显示器的亮度和音量

brew 安装

sh
brew install --cask betterdisplay

操作方法 - 以 BetterDisplay v1.4.15 为例

  1. 下载 - 安装 - 打开
  2. 点击导航栏小图标
  3. 点击面板最下面的设置按钮
    1. 点击『Display
    2. 选择扩展显示器
    3. 勾选『Edit the system configuration of this display
    4. 添加自定义分辨率(可选)
      1. 勾选『『Add custom scaled resolutions
      2. 设置自己需要的分辨率(如 1600x900
    5. 修改 Default resolution 选项
      1. 勾选『Edit default resolution
      2. 设置自己需要的分辨率(如 1920x1080@60
  4. 保存并应用设置(设置完以后可关闭软件,不需要一直开着)

BetterDisplay | Github

剪贴板管理器 Maccy

  1. 免费开源、支持中文
  2. 简单易用、支持复制图片和文件
  3. 快速唤起(SHIFT (⇧) + COMMAND (⌘) + C
  4. 强大的历史记录管理(最多 999 条)
  5. 丰富的个性化配置(可以忽略指定应用)

brew 安装

sh
brew install --cask maccy

录屏神器 Kap

  1. 免费开源
  2. 支持全屏录制、自定义录制区域、只录某个窗口
  3. 支持显示鼠标点击位置
  4. 支持导出为 GIF、MP4、WebM 或 APNG
  5. 支持插件扩展

brew 安装

sh
brew install --cask kap

视频转 GIF Gifski

将视频转换为高质量的 GIF

  1. 免费开源
  2. 操作简单
  3. 支持视频剪辑
  4. 支持调整分辨率、FPS、质量、倍速、播放次数等参数

其他版本 —— 聚合官网

命令行版本可通过 brew 安装

sh
brew install gifski

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/software/vscode.html b/efficiency/software/vscode.html index e03fe890d..adc186b3c 100644 --- a/efficiency/software/vscode.html +++ b/efficiency/software/vscode.html @@ -459,7 +459,7 @@ "description": "markdown 行内代码" } }

其他

扩展插件开发

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/software/webstorm.html b/efficiency/software/webstorm.html index 484361041..461711993 100644 --- a/efficiency/software/webstorm.html +++ b/efficiency/software/webstorm.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

WebStorm 配置

获取许可证

使用开源项目免费申请 JetBrains 全家桶开源许可证

常用插件

  1. 进入「设置 - Plugins/插件 - Marketplace
  2. 复制插件名后进行搜索安装
  • Chinese ​(Simplified)​ Language Pack / 中文语言包 编辑器汉化
  • GitHub Copilot 代码智能提示
  • GitToolBox 增强内置的 Git 功能(猪哥推荐)
  • .env files support .env 文件键值字符串高亮
  • .ignore .env 提示哪些文件可以被 ignore
  • CodeGlance Pro 在侧边栏显示代码缩略图(猪哥推荐)
  • WakaTime 统计代码编写时间 (WakaTime 官网)

插件市场

主题美化

主题插件

  • Atom Material Icons 图标美化
  • Atom OneDark Theme Atom OneDark 主题
  • Material Theme UI Material Design 主题
  • One Dark theme 暗黑风格主题

配色方案

自定义背景图

  1. 进入 设置 - 外观和行为 - Appearance
  2. 点击 BACKGROUND IMAGE

汉化

老版本

  • 方案一
    • 进入 文件 - 设置 - Plugins - Marketplace
    • 搜索 Chinese ​(Simplified)​ Language Pack EAP 下载安装
  • 方案二
  • 方案三
    • 查看本地 WebStorm 版本
      • 进入 帮助 - 关于
      • 找到 Build #WS- 后面的数字
    • 打开 Chinese ​(Simplified)​ Language Pack EAP
    • 点击 Versions 选择对应编辑器再搜索对应版本下载(当找不到一样的版本时,可以看列表的第二栏版本范围,找包含你编辑器的版本下载就行)
    • 通过磁盘安装刚下载的文件

磁盘安装

配置 Prettier 保存格式化

新版本

  1. 进入 WebStorm - Settings - 框架和语言 - JavaScript - Prettier
  2. 勾选 执行“重新格式化代码”操作时(R)保存时(S)
  3. 进入 WebStorm - Settings - 工具 - 保存时的操作
  4. 勾选 重新格式化代码运行 Prettier

老版本可使用 File Watchers 方案

  1. 进入 文件 - 设置 - 工具 - File Watchers
  2. 点击 + 选择 Prettier
  3. File type 修改为你需要的文件类型,通用可选 Any

webpack 项目识别 alias

  1. 进入 文件 - 设置 - 框架和语言 - JavaScript - Webpack
  2. webpack 配置文件地址修改为对应地址
    1. vue-cli2.x: 项目地址 + \build\webpack.base.conf.js
    2. vue-cli3.x 及以上: 项目地址 + \node_modules\@vue\cli-service\webpack.config.js

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/efficiency/software/windows.html b/efficiency/software/windows.html index 8d4c6ddfd..ed572d1a7 100644 --- a/efficiency/software/windows.html +++ b/efficiency/software/windows.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Windows 平台

激活工具

激活神器 Microsoft-Activation-Scripts

使用 HWID / Ohook / KMS38 / Online KMS 激活方法的 Windows 和 Office 激活器

使用方法

  1. 右键单击 Windows 开始菜单,然后选择 PowerShell
  2. 复制并粘贴下面的代码,然后按 Enter
sh
irm https://get.activated.win | iex

Office Tool Plus

一个用于部署、激活 Office、Visio、Project 的强大工具

终端神器 Cmder

  1. 便携,解压即可用
  2. 支持子窗口
  3. 自带 gitls 等命令
  4. 自定义配置项

搜索神器 Everything

  1. Windows 平台最快的文件搜索软件
  2. 支持整词、路经匹配搜索
  3. 支持正则表达式搜索

软件官网

效率神器 Wox

  1. 可以搜索安装的程序,支持中文拼音模糊搜索
  2. 搜索浏览器书签
  3. 可以调用 Everything 进行快速全局搜索
  4. 网页搜索功能
  5. 支持插件扩展
  6. 支持自定义主题

视频播放神器 PotPlayer

  1. 界面简洁,可自定义皮肤
  2. 功能强大,设置以播放体验为中心
  3. 纯粹的本地播放器
  4. 视频/音频格式支持非常全面

压缩/解压神器 bandizip

  1. 界面简洁、清新
  2. 集 压缩/解压/浏览/编辑 为一体
  3. 支持处理乱码
  4. 支持通过对文件完整性的检查来判断压缩包是否受损
  • 最新版存在广告,需要无广告的可下载 6.x 版本

软件官网

音量管理神器 EarTrumpet

  1. 基于 Microsoft Store 托管的 UWP 应用程序,可自动更新,性能影响小
  2. 默认播放设备管理
  3. 支持明 / 暗模式和所有强调色
  4. 支持快捷键设置
  5. 在播放设备之间移动应用

看图神器 Honeyview

  1. 支持众多图片格式,如 PSD 文件预览
  2. 对图像格式进行批量转换和调整
  3. 可以显示包括 GPS 信息在内的 JPEG 格式的 EXIF 信息

软件官网

壁纸神器 Wallpaper Engine

  1. 内存占用低
  2. 支持视频、网页、2D、3D、GIF 等类型壁纸
  3. 强大的创意工坊拥有海量壁纸可供选择

系统优化工具 Dism++

  1. 基于 Windows 系统原生功能 Dism 开发的增强工具
  2. 体积小,解压即用,方便快捷
  3. 集成空间清理、系统管理/优化、热备份还原等功能于一体

隐私优化 WPD

  1. 隐私管理
  2. 预装应用卸载
  3. 绿色免费、支持中文

软件官网

微信/QQ/TIM 防撤回补丁

  1. 支持微信/QQ/TIM 防撤回
  2. 支持微信多开

微信/QQ/TIM 防撤回补丁 | Github

微信清理工具 CleanMyWechat

  1. 自动识别微信账号,支持用户选择自定义路径
  2. 同时管理多个账号,保留配置参数,打开即用
  3. 自由设置想要删除的文件类型,包括图片类缓存、文件、图片、视频
  4. 自由设置需要删除的文件的距离时间,默认 365 天
  5. 删除后的文件放置在回收站中,检查后自行清空,防止删错需要的文件

CleanMyWechat | Github

任务栏透明 TranslucentTB

  1. 支持亚克力、模糊、透明、主题色、不透明效果
  2. 支持自定义颜色
  3. 只支持 Windows 10

查重神器 Duplicate Cleaner

  1. 快速查找重复文件、支持多目录
  2. 灵活的搜索设置
  3. 在详细列表中查看所有文件信息
  4. 删除重复文件至回收站
  5. 移动重复文件到新位置

电子书格式转换器 NeatConverter

  1. 完全免费,简单易用
  2. 支持 ePub、Azw3、Mobi、Doc、PDF、TXT 文件的互转

软件官网

系统增强工具 PowerToys

  • Color Picker 颜色选择器

    • 默认启动快捷键: Win + Shift + C
  • FancyZones 窗口管理器

    • 自定义窗口布局
    • 默认启动快捷键: Win + ~
  • File Explorer Add-ons 文件资源管理器

    • 快速预览 SVG 和 Markdown 文件
  • Image Resizer 图像大小调整器

    • 修改图片大小、旋转方向、图片格式
    • 支持批量修改
  • Keyboard Manager 键盘管理器

    • 修改键位映射
  • PowerRename 批量重命名工具

    • 添加文件名前缀、后缀
    • 支持搜索、替换、正则表达式匹配
    • 排除指定的文件、文件夹
    • 预览重命名结果
  • PowerToys Run 快速启动程序

    • 搜索应用程序、文件夹或文件
    • 使用计算器执行简单计算
    • 默认启动快捷键: Alt + Space
  • PowerToys | Github

  • 安装文档

网速监控悬浮窗 TrafficMonitor

  1. 显示当前实现网络传输速率、CPU 和内存占用率
  2. 支持嵌入到任务栏显示
  3. 支持更换皮肤和自定义皮肤
  4. 历史流量统计

TrafficMonitor | Github

GIF 录制神器 ScreenToGif

  1. 支持屏幕、摄像头、画板录制
  2. 可对 Gif 进行压缩、裁剪、涂鸦、模糊、添加字幕、添加水印、添加进度条等操作
  3. 免费无广告支持免安装使用

按键精灵 KeymouseGo

录制鼠标键盘操作进行自动化操作

KeymouseGo | Github

截图神器 Snipaste

  1. 免费、无广告
  2. 自动检测界面元素区域、像素级的鼠标移动控制、截图范围控制、截图历史记录回放
  3. 标注(矩形、椭圆、线条、箭头、铅笔、马克笔、文字、马赛克、高斯模糊等)
  4. 支持剪贴板中的图像、纯文本、HTML 文本、颜色信息、图像文件转化成图片
  5. 贴图、取色
  6. 支持自定义设置

卸载神器 HiBit Uninstaller

  1. 强制卸载、批量卸载
  2. 安全的清理注册表和垃圾文件
  3. 快捷方式修复
  4. 空文件夹删除
  5. 系统更新补丁管理

软件官网

硬盘分析工具 WizTree

  1. 分析速度极快
  2. 可视化显示空间占用
  3. 支持数据导出
  4. 免费无广告支持免安装使用

软件官网

抢票神器 12306Bypass

  1. 免费可用
  2. 全程自动抢票、自动抢候补、自动识别验证码
  3. 支持多账号

软件官网

文字识别神器 Umi-OCR

  1. 免费开源
  2. 解压即用,离线运行,无需网络
  3. 自带高效率离线 OCR 引擎
  4. 支持命令行、HTTP 接口等多种调用方式
  5. 截图 OCR / 批量 OCR / 二维码 / 数学公式识别

Umi-OCR | Github

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/browser/index.html b/fe/browser/index.html index e826f7f07..3f646c768 100644 --- a/fe/browser/index.html +++ b/fe/browser/index.html @@ -131,7 +131,7 @@ objectStoreRequest.onsuccess = function () { console.log('删除成功') }

在日常开发中可以使用如下类库简化代码量

  • localForage 一个提供 name:value 的简单语法的客户端数据存储垫片,基于 IndexedDB 实现,并在不持支 IndexedDB 的浏览器中自动回退到 WebSQLlocalStorage
  • Dexie.jsIndexedDB 的封装,通过提供更友好和简单语法进行快速的编码开发
  • PouchDBIndexedDB 的封装,通过提供更友好和简单语法进行快速的编码开发

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/coding/index.html b/fe/coding/index.html index 7ec314747..7c272c488 100644 --- a/fe/coding/index.html +++ b/fe/coding/index.html @@ -300,7 +300,7 @@ } } }

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/concept/module.html b/fe/concept/module.html index 34230c742..a97aea003 100644 --- a/fe/concept/module.html +++ b/fe/concept/module.html @@ -90,7 +90,7 @@ log, } })

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/concept/page-rendering.html b/fe/concept/page-rendering.html index 35426c288..7d8b82b9d 100644 --- a/fe/concept/page-rendering.html +++ b/fe/concept/page-rendering.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

前端页面渲染方式

CSR 客户端渲染

CSR 客户端渲染(Client Side Rendering)

客户端渲染是指浏览器在请求页面 URL 后,服务端直接返回一个空的静态 HTML 文件,这个 HTML 文件需要再加载 JavaScript 脚本和 CSS 样式表,浏览器加载和执行这些文件去动态改变 DOM 树的结构,使页面渲染成用户所需要的界面,这种动态渲染的方式就是客户端渲染 (CSR)

优点

  • 局部刷新:无需每次都进行完整页面请求
  • 懒加载:首次加载时可以只加载可视区域内的数据
  • 丰富的站点交互
  • 减轻服务器压力
  • 前后端分离

缺点

  • 不利于 SEO
  • 首屏渲染慢:需要等待 JavaScript 脚本文件加载完毕后才开始渲染页面

SEO

SEO(Search Engine Optimization):搜索引擎优化,利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名。目的是让其在行业内占据领先地位,获得品牌收益。

SSR 服务端渲染

SSR 服务端渲染(Server Side Rendering)

服务端渲染是指浏览器在请求页面 URL 时,服务端将我们需要的 HTML 文本组装好,并返回给浏览器,这个 HTML 文本被浏览器解析之后,不需要经过 JavaScript 脚本的下载过程,就能直接构建出我们所希望的 DOM 树并展示到页面中。这个服务端组装 HTML 的过程就叫做服务端渲染(SSR)

优点

  • 有利于 SEO
  • 首屏渲染快

缺点

  • 占用服务器资源
  • 用户体验不好:新页面都需要在服务端重新渲染整个页面,不能局部渲染
  • 模板维护成本高

同构渲染

同构渲染是一种现代化服务端渲染方案,实际上是将 CSR 客户端渲染和 SSR 服务端渲染的优势结合起来实现互补;
其流程是先在 Node.js 中进行服务端渲染生成 HTML,然后通过客户端渲染接管页面交互

  • 同构:是指同一套代码可以同时运行在服务端和客户端
    • 路由同构
    • 数据同构
    • 渲染同构
  • 脱水(dehydrate):在服务端渲染直出 HTML 前将预取的数据注入到 window
  • 注水(hydrate):在客户端进行渲染前将 window 上绑定的数据传入到对应组件中

同构渲染流程

为什么需要数据的脱水和注水?

保证服务端和客户端端渲染的组件具有相同的 propsDOM 结构

优点

  • 有利于 SEO
  • 首屏渲染快
  • 局部刷新:无需每次都进行完整页面请求

缺点

  • Node 服务的性能压力
  • 服务端和浏览器环境的差异

开箱即用的 SSR 框架

SSG 静态站点生成

SSG 静态网站生成(Static Site Generation)

静态站点生成是指在构建时就会为每个页面生成包含内容的 HTML 文件,当浏览器在请求页面 URL 时,服务端直接返回 HTML 即可。

优点

  • 有利于 SEO
  • 首屏渲染快
  • 减轻服务器压力

缺点

  • 每次更改内容时都需要重新构建和部署应用程序
  • 无法生成用户相关内容

SSG 应用场景

SSG 适合应用在页面内容在构建时就能确定的场景

  • 静态官网
  • 文档网站

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/css/index.html b/fe/css/index.html index 809475d9b..ec498ebf5 100644 --- a/fe/css/index.html +++ b/fe/css/index.html @@ -113,7 +113,7 @@ 关于 @import 的加载顺序 </body> </html>

然后打开浏览器 network 面板去查看具体资源的加载时间

import.css 排队时间

import

link.css 排队时间

link

所以 @import 的加载顺序要看其写在哪里,而不能一概而论

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/es6/index.html b/fe/es6/index.html index adee5d929..3c5419e81 100644 --- a/fe/es6/index.html +++ b/fe/es6/index.html @@ -576,7 +576,7 @@ }), ) }

Promise 静态方法

  • Promise.resolve()
    • 将传入的参数转为 Promise 对象
      • 参数是一个 Promise 实例则直接返回
      • 参数是一个 thenable 对象(具有 then 方法的对象) 转为 Promise 对象再立即执行 thenable 对象的 then 方法
      • 参数不是具有 then 方法的对象或根本就不是对象时返回一个 fulfilled 状态的新 Promise 对象
      • 没有参数时返回一个 fulfilled 状态的新 Promise 对象
  • Promise.reject()
    • 返回一个 rejected 状态的新 Promise 对象
  • Promise.all()
    • 将多个 Promise 实例,包装成一个新的 Promise 实例,只有所有的 Promise 状态成功才会成功,如果其中一个 Promise 的状态失败就会失败
  • Promise.race()
    • 将多个 Promise 实例,包装成一个新的 Promise 实例,新的 Promise 实例状态会根据最先更改状态的参数实例而更改状态(可以轻松实现超时方法)
  • Promise.allSettled() (ES2020)
    • 将多个 Promise 实例,包装成一个新的 Promise 实例,新的 Promise 实例只有等到所有这些参数实例都返回结果,不管是 fulfilled 还是 rejected ,包装实例才会结束,一旦结束,状态总是 fulfilled
  • Promise.any() (ES2021)
    • 将多个 Promise 实例,包装成一个新的 Promise 实例,只要参数实例有一个变成 fulfilled 状态,包装实例就会变成 fulfilled 状态;如果所有参数实例都变成 rejected 状态,包装实例才会变成 rejected 状态

Promise 实现 简易实现、A+ 规范实现、原型方法、静态方法实现

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/html/index.html b/fe/html/index.html index 525c0d867..501336ab8 100644 --- a/fe/html/index.html +++ b/fe/html/index.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

HTML 理论知识点

HTML 语义化

HTML 语义化是指根据内容的结构化(内容语义化)来选择合适的标签(代码语义化),即用正确的标签做正确的事情

语义化的优点

HTML 语义化增强文档的可识别性

  • 可以使页面在没有 CSS 样式表的情况下也能呈现出很好的内容结构
  • 有利于 SEO 优化(爬虫依赖 HTML 的标签来确定渲染关键字的权重)
  • 方便其他设备解析(屏幕阅读器、盲人阅读器)提升了用户体验
  • 增强了代码的可读性和可维护性

常用的语义化标签

  • <article>:表示文章主体部分
  • <aside>:表示跟文章主体不那么相关的部分,一般包含导航、广告等工具性质的内容
  • <details> 和 <summary>:表示可以查看或隐藏的其他详细信息
  • <figure> 和 <figcaption>:表示与文章相关的图像、照片等流内容
  • <footer>:通常出现在尾部,包含作者信息、相关链接、版权信息等
  • <header>:表示导航或者介绍性的内容
  • <h1> ~ <h6>:表示文章中不同层级的标题
  • <p>:表示文章的段落
  • <main>:表示文章的主要内容
  • <nav>:表示导航
    • header 中大多表示文章目录
    • aside 中大多是关联页面或者是整站地图
  • <section>:表示文章中的“节”或“段”
  • <time>:表示日期或时间

HTML5 标签选择流程图

HTML5 标签选择流程图

HTML 中的语义 —— MDN

HTML 的元素嵌套规则

HTML 元素嵌套规则是指 HTML 标签在嵌套时的合法性,即标签嵌套的顺序和层级

HTML 元素的嵌套合法性

HTML 元素嵌套是否合法由标签的语义决定,即标签的语义决定了标签的嵌套规则

举个 🌰

<h1> 中不能再嵌套 <p>,因为 <p> 是一个段落,而 <h1> 是一个标题,段落不能嵌套在标题中

HTML5 的新特性

HTML5 引入了许多新特性和改进,使得 Web 开发变得更加强大和灵活。HTML5 的新特性主要包括:

  • 语义化标签:引入新的语义化标签,如<header><footer><article><section>等,用于更清晰地表示文档的结构和内容
  • 多媒体支持:提供了<audio><video>元素
  • Canvas 画布: 提供了 <canvas> 元素,允许通过 JavaScript 绘制图形、图表和动画
  • 表单增强:如 <input>type 属性中的 dateemailurl
  • 本地存储:提供了 Web Storage(localStorage 和 sessionStorage)和 IndexedDB,使得浏览器可以在客户端存储数据,以提高性能和离线应用的能力
  • 地理位置 API:提供了 Geolocation API,使得网页可以获取用户设备的地理位置信息
  • Web Workers:允许在后台运行脚本,提高网页的性能和响应性

HTML5 和 H5

  • HTML5 是 HTML 的第五个版本,是 HTML 的最新标准
  • H5 不是一个技术名词,泛指一些富有创意、具有炫酷效果的移动端网页,其通常使用 HTML5、CSS3、JavaScript 等技术来实现丰富的交互和动画效果(这个名词常出现于以下场景)
    • 产品业务:我们有个需求,要做一个 H5 页面来承载 XXX
    • 销售宣传:给客户吹牛逼说我们的 H5 页面很炫酷

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/javascript/clone.html b/fe/javascript/clone.html index 6e29dc75b..bb9af8e47 100644 --- a/fe/javascript/clone.html +++ b/fe/javascript/clone.html @@ -149,7 +149,7 @@ const obj2 = $.extend(true, {}, obj1)

lodash.cloneDeep

js
import { cloneDeep } from 'lodash-es'
 
 const obj2 = cloneDeep(obj1)

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/javascript/conversions.html b/fe/javascript/conversions.html index 213186214..8385c8136 100644 --- a/fe/javascript/conversions.html +++ b/fe/javascript/conversions.html @@ -63,7 +63,7 @@ 'str: ' + obj1 // valueOf => 'str: 2021' 'str: ' + obj2 // valueOf toString => 'str: maomao'

ToString

ToString 用来处理非字符串到字符串的类型转换

ToString 转换规则

  • 基本类型
    • undefined => 'undefined'
    • null => 'null'
    • true => 'true'
    • false => 'false'
    • number
      • 普通数值直接加引号
      • 极小和极大的数字将转换成指数形式的字符串
      • +0 0 -0 => '0'
      • Infinity => 'Infinity'
  • 引用类型会先调用 ToPrimitive 逻辑将其转换成基本类型,如果返回的基本类型不是字符串,再遵循以上规则进行转换

ToBoolean

ToBoolean 用来处理非布尔值到布尔值的类型转换,在 JavaScript 中,布尔类型分为真值(true)和假值(false)

  • 假值:可以被强制类型转换为 false 的值
  • 真值:除假值之外的值

ToBoolean 转换规则

  • 以下值会被转换成假值(false)
    • undefined
    • null
    • false
    • +0 0 -0 NaN
    • ''
  • 除假值之外的值都会被转换成真值(true)

ToNumber

ToNumber 用来处理非数字值到数字值的类型转换

ToNumber 转换规则

  • 基本类型
    • undefined => NaN
    • null => 0
    • true => 1
    • false => 0
    • string
      • 空字符串('') => 0
      • 非数字字符串 => NaN
  • 引用类型会先调用 ToPrimitive 逻辑将其转换成基本类型,如果返回的基本类型不是数值,再遵循以上规则进行转换

显式类型转换

显式类型转换是指显式的去调用类型转换方法

  • 转换成布尔值
    • Boolean()
  • 转换成数值
    • Number()
    • parseInt()
    • parseFloat()
  • 转换成字符串
    • String()

注意点

  • Number() 转换的是整个值
  • parseInt()parseFloat() 转换的是部分值,是对字符串逐个进行解析和转换,如果传入的参数不是字符串,会先对其进行字符串的转换

隐式类型转换

隐式类型转换是指在执行过程中,当实际操作的值与 JavaScript 内部期望得到的值不同时,就会对其做隐式类型转换(即不易察觉的类型转换)
JavaScript 中有以下场景会发生隐式类型转换

  • 相等运算符 (==)
  • 四则运算符 (+ - * /)
  • 关系运算符 (> < >= <=)
  • 逻辑操作符 (&& ||)
  • 条件判断语句
    • if()
    • while()
    • 三元运算符

相等运算符运算规则(重点)

为什么 0 == nullfalse

js
0 == null // false

ECMA-262 规范 7.2.12 小节对相等运算符的描述

  1. 如果 x 不是正常值(比如抛出一个错误),中断执行;
  2. 如果 y 不是正常值,中断执行;
  3. 如果 Type(x)Type(y) 相同,执行严格相等运算 x === y
  4. 如果 xnullyundefined,返回 true
  5. 如果 xundefinedynull,返回 true
  6. 如果 Type(x) 是数值,Type(y) 是字符串,返回 x == ToNumber(y) 的结果;
  7. 如果 Type(x) 是字符串,Type(y) 是数值,返回 ToNumber(x) == y 的结果;
  8. 如果 Type(x) 是布尔值,返回 ToNumber(x) == y 的结果;
  9. 如果 Type(y) 是布尔值,返回 x == ToNumber(y) 的结果;
  10. 如果 Type(x) 是字符串或数值或 Symbol 值,Type(y) 是对象,返回 x == ToPrimitive(y) 的结果;
  11. 如果 Type(x) 是对象,Type(y) 是字符串或数值或 Symbol 值,返回 ToPrimitive(x) == y 的结果;
  12. 返回 false

Type(x)the type of x 的简写,其中的 type 是 ECMA-262 规范中定义的 ECMAScript 语言和规范类型

所以在计算 0 == null 时,由于 0 的类型是数值,null 的类型是 Null(这是规格 4.3.13 小节的规定,是内部 Type 运算的结果,跟 typeof 运算符无关);
因此上面的前 11 步都得不到结果,要到第 12 步才能得到 false

相等运算符 —— ECMAScript 6 入门

相等运算符运算规则总结

  • 同类型比较时,执行严格相等运算 x === y
  • undefinednull 比较时返回 true
  • stringnumber 进行比较时,先将 stringToNumber 处理,再进行比较
  • boolean 与其它类型进行比较时,先将 booleanToNumber 处理,再进行比较
  • 引用类型基本类型 进行比较时,将 引用类型ToPrimitive 处理,再进行比较
  • undefined null 与其它类型的比较时都返回 false

四则运算符运算规则

四则运算符运算规则

  • -(减) *(乘) /(除) 运算符: 先对操作数做 ToNumber 处理再执行运算
  • +(加) 运算符
    • 做一元运算时,对操作数做 ToNumber 处理
    • 做二元运算时
      • 当其中一个操作数为 string 时,将另一个操作数做 ToString 处理再执行字符串拼接
      • 当一个操作数为 number 另一个操作数为基本类型时,将基本类型做 ToNumber 处理再执行运算
      • 当一个操作数为 number 另一个操作数为引用类型时,都会先做 ToString 处理再执行字符串拼接

关系、逻辑、条件运算符运算规则

关系运算符运算规则

  • 将引用类型做 ToPrimitive 处理
  • 如果两个参数都是 string 类型时进行 Unicode 编码 大小比较
  • 否则将两个参数做 ToNumber 处理,再进行数值大小比较

逻辑操作符与条件判断语句

逻辑操作符条件判断语句中都是做 ToBoolean 处理

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/javascript/inherit.html b/fe/javascript/inherit.html index 25f06c2ca..13d8a2f09 100644 --- a/fe/javascript/inherit.html +++ b/fe/javascript/inherit.html @@ -248,7 +248,7 @@ return ColorPoint })(Point)

总结

  • 原型链继承:通过重写子类的原型将父类的实例作为子类的原型
  • 借用构造函数继承:使用父类的构造函数来增强子类实例等同于复制父类的实例给子类(不使用原型)
  • 组合继承:使用原型链继承原型上的属性和方法,通过借用构造函数来实现对实例属性的继承
  • 原型式继承:利用一个空对象作为中介,将某个对象直接赋值给空对象构造函数的原型
  • 寄生式继承:创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象
  • 寄生组合式继承:通过借用构造函数继承属性,再使用寄生式继承来继承父类原型,然后将返回的新对象赋值给子类原型

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/javascript/prototype.html b/fe/javascript/prototype.html index f712501ac..ca3e38bb8 100644 --- a/fe/javascript/prototype.html +++ b/fe/javascript/prototype.html @@ -82,7 +82,7 @@ Function instanceof Function // true // 实际如下 Function.__proto__ === Function.prototype // true

经典图

prototypes

总结

  • 所有的引用类型(数组、对象、函数)都是对象(对象是属性的集合)
  • 所有的函数都是 Function 的实例
  • Object.prototypeFunction.prototype 均由引擎根据 ECMAScript 规范创建的两个特殊对象
  • 所有的函数都有一个 prototype 属性(原型)指向调用该构造函数而创建的实例的原型
  • 所有的对象都有一个 __proto__ 属性(隐式原型)指向创建该对象的函数的 prototype(实例的隐式原型 === 构造函数的原型)
  • 每个对象都拥有一个原型对象,通过 __proto__ 指针指向上一个原型 ,同时原型对象也可能拥有原型,这样一层一层,最终指向 null。这个链式结构被称为原型链

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/javascript/this.html b/fe/javascript/this.html index 7fe3809fd..09e5acb29 100644 --- a/fe/javascript/this.html +++ b/fe/javascript/this.html @@ -57,7 +57,7 @@ console.log('obj1.method.call(obj2) :', obj1.method.call(obj2)) // new 创建的对象 console.log('new Method().method() :', new Method().method())

打印结果如下

在浏览器环境中 this 指向 window 对象

函数调用 this — 浏览器环境

在 Node.js 环境 CommonJS 中 this 指向 global 对象

函数调用 this — CommonJS

在 Node.js 环境 ESModule 中 this 指向 undefined

函数调用 this — ESModule

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/javascript/types.html b/fe/javascript/types.html index 49433e7ce..acc9824be 100644 --- a/fe/javascript/types.html +++ b/fe/javascript/types.html @@ -113,7 +113,7 @@ toString.call(new WeakSet()) // '[object WeakSet]' toString.call(new Map()) // '[object Map]' toString.call(new WeakMap()) // '[object WeakMap]'

toString 方法的在 ECMAScript 5 下的大致执行过程

  1. 如果 thisundefined 返回 [object Undefined]
  2. 如果 thisnull 返回 [object Null]
  3. O 成为 ToObject(this) 的结果
  4. class 成为 O 的内部属性 [[Class]] 的值
  5. 返回由 "[object " class "]" 三个部分组成的字符串

注意点

不同 ECMAScript 版本对 toString 方法的规范都有所不同

Object.prototype.toString 方法的原理

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/monorepo/index.html b/fe/monorepo/index.html index d50ac0567..256ba0bb4 100644 --- a/fe/monorepo/index.html +++ b/fe/monorepo/index.html @@ -13,7 +13,7 @@ - + @@ -51,7 +51,7 @@ ├── .git ├── src └── index.js - └── package.json

Multi-Repo 的优缺点

优点

  • 独立性和分离性 每个项目的版本控制、依赖关系和构建流程上是完全独立的,这种分离可以避免项目之间的潜在干扰和冲突
  • 更灵活的团队结构 不同项目可以由不同的开发团队负责,这使得团队结构更加灵活,每个团队可以独立决策其工作流程、开发工具和版本发布策略
  • 分布式开发 如果项目需要分布式开发,每个项目都可以在不同的代码仓库中进行开发,而无需将所有代码集中在一个仓库中
  • 隔离风险:如果一个项目出现问题不会影响其他项目,这有助于隔离风险确保一个项目的问题不会波及整个代码库

缺点

  • 代码重复 多个项目可能需要共享相同的代码或依赖项时,可能会导致代码重复
  • 版本控制一致性不同仓库中的项目可能使用不同的版本控制策略和工具,这可能导致版本控制一致性的问题。
  • 依赖管理 当多个项目依赖于相同的第三方库时,每个项目都需要单独管理这些依赖关系,会导致依赖管理的复杂性和不一致性
  • 协作难度 在不同的仓库中协同开发可能会变得更加复杂,需要额外的协调和工具,如跨仓库合并请求或协同开发流程

如何选择

  • Monorepo 适用于需要代码共享、版本一致性和跨项目协作的项目
  • Multi-Repo 适用于需要强调项目独立性、分离性和团队灵活性的情况

在选择时主要取决于项目需求、团队结构和偏好,没有哪种方式是绝对正确的,都要根据实际需求结合其优缺点来进行选择,下面是一些常见的考虑因素:

  • 团队结构
  • 团队偏好
  • 项目规模
  • 项目复杂性
  • 项目依赖
  • 项目共享
  • 项目协作

搭建 Monorepo 项目

常见的 Monorepo 实现

  1. 使用 pnpm/npm/yarnworkspace 功能
  2. 再搭配 Monorepo 管理工具
    1. pnpm
    2. lerna
    3. nx
    4. bazel
    5. rushstack

目前主流的方式是使用 pnpm 来做 Monorepo,其无须使用第三方工具就可以进行管理

安装 pnpm

sh
curl -fsSL https://get.pnpm.io/install.sh | sh -
sh
brew install pnpm
sh
npm install -g pnpm

相关资料

安装 | pnpm

创建项目

sh
# 创建并进入 my-monorepo 文件夹
+    └── package.json

Multi-Repo 的优缺点

优点

  • 独立性和分离性 每个项目的版本控制、依赖关系和构建流程上是完全独立的,这种分离可以避免项目之间的潜在干扰和冲突
  • 更灵活的团队结构 不同项目可以由不同的开发团队负责,这使得团队结构更加灵活,每个团队可以独立决策其工作流程、开发工具和版本发布策略
  • 分布式开发 如果项目需要分布式开发,每个项目都可以在不同的代码仓库中进行开发,而无需将所有代码集中在一个仓库中
  • 隔离风险:如果一个项目出现问题不会影响其他项目,这有助于隔离风险确保一个项目的问题不会波及整个代码库

缺点

  • 代码重复 多个项目可能需要共享相同的代码或依赖项时,可能会导致代码重复
  • 版本控制一致性不同仓库中的项目可能使用不同的版本控制策略和工具,这可能导致版本控制一致性的问题。
  • 依赖管理 当多个项目依赖于相同的第三方库时,每个项目都需要单独管理这些依赖关系,会导致依赖管理的复杂性和不一致性
  • 协作难度 在不同的仓库中协同开发可能会变得更加复杂,需要额外的协调和工具,如跨仓库合并请求或协同开发流程

如何选择

  • Monorepo 适用于需要代码共享、版本一致性和跨项目协作的项目
  • Multi-Repo 适用于需要强调项目独立性、分离性和团队灵活性的情况

在选择时主要取决于项目需求、团队结构和偏好,没有哪种方式是绝对正确的,都要根据实际需求结合其优缺点来进行选择,下面是一些常见的考虑因素:

  • 团队结构
  • 团队偏好
  • 项目规模
  • 项目复杂性
  • 项目依赖
  • 项目共享
  • 项目协作

搭建 Monorepo 项目

常见的 Monorepo 实现

  1. 使用 pnpm/npm/yarnworkspace 功能
  2. 再搭配 Monorepo 管理工具
    1. pnpm
    2. lerna
    3. nx
    4. bazel
    5. rushstack

目前主流的方式是使用 pnpm 来做 Monorepo,其无须使用第三方工具就可以进行管理

安装 pnpm

sh
curl -fsSL https://get.pnpm.io/install.sh | sh -
sh
brew install pnpm
sh
npm install -g pnpm

相关资料

安装 | pnpm

创建项目

sh
# 创建并进入 my-monorepo 文件夹
 mkdir my-monorepo
 cd my-monorepo
 
@@ -113,7 +113,7 @@
 
 # 发布到 npm
 pnpm publish -r
  • -r 表示对所有子包执行某个命令

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/network/http.html b/fe/network/http.html index a4980ef2d..33b0b0fdb 100644 --- a/fe/network/http.html +++ b/fe/network/http.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

HTTP

HTTP 全称为 HyperText Transfer Protocol,即超文本传输协议,是一个用于传输超媒体文档(例如 HTML)的应用层协议

HTTP 协议的主要特点

  • 是一个应用层协议
  • 遵循经典的“客户端-服务端”模型(客户端发送请求,服务器返回响应)
  • 灵活可扩展
    • 语义上的自由,只规定了报文的基本格式,报文里的各个组成部分可以由开发者任意定制
    • 传输格式的多样性
  • 无连接: 每完成一个请求就断开连接(HTTP/1.1 后默认开启长连接)
  • 无状态: HTTP 协议对于事务处理没有记忆能力(每个请求之间、浏览器和服务器之间都是相互独立毫无关联的)
  • 可靠传输: HTTP 协议是一个可靠的传输协议(基于 TCP/IP 协议)
  • 明文传输: 协议里的报文直接使用文本形式传输(HTTP/2.0 后改为二进制传输)

HTTP 协议的演变

HTTP 协议演进与各版本特性

HTTP/0.9

1990 年问世

功能简陋,只有一个 GET 方法,且只支持纯文本内容

HTTP/1.0

1996 年 5 月正式发布

  • 任何格式的内容都可以发送
  • 请求和响应增加了头信息
  • 新增方法:POST HEAD
  • 添加了状态码、多字符集支持、权限、缓存、内容编码等功能

HTTP/1.1

1997 年 1 月发布,是目前主流的 HTTP 协议版本

  • 长连接:TCP 连接默认不关闭可以被多个请求复用
  • 管道机制:在同一个 TCP 链接里面,客户端可以同时发送多个请求
  • 分块传输编码
  • 缓存处理:Cache-ControlEtag/If-None-Match
  • 断点续传
  • 增加了 TLS 支持:支持 HTTPS 传输
  • 新增方法:PUT PATCH OPTIONS DELETE

HTTP/1.1 缺点

  • 单路连接请求低效:每个 TCP 连接只能对应一个 HTTP 请求
  • 队头阻塞:当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。
  • 头信息冗余
  • 只允许由客户端主动发起请求
  • 明文传输

HTTP/2.0

2015 年发布,主要基于 SPDY 协议(2009 年谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题)

  • 二进制传输:头信息和数据体都是二进制
  • 多路复用/二进制分帧:在一个 TCP 连接中可以同时发送多个请求
  • 头部压缩(使用 HPACK 算法进行压缩)
  • 服务器推送:允许服务器未经请求主动向客户端发送资源
  • 请求优先级

HTTP/2.0 缺点

  • 建立连接时间长(本质上是 TCP 的问题)
  • 没有彻底解决队头阻塞问题
  • 弱网环境表现不佳

HTTP/3.0

HTTP/3.0 又称为 HTTP Over QUIC,其弃用 TCP 协议,改为使用基于 UDP 协议的 QUIC 协议来实现

  • 实现了类似 TCP 的流量控制、传输可靠性的功能
  • 实现了快速握手功能
  • 集成了 TLS 加密功能
  • 多路复用,彻底解决 TCP 中队头阻塞的问题

HTTP 状态码

HTTP 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。

主要有以下 5 响应类别的状态码

  • 1XX 是信息性状态码,表示接收的请求正在处理
  • 2XX 是成功状态码,表示请求正常处理完毕
  • 3XX 是重定向状态码,表示需要进行附加操作以完成请求
  • 4XX 是客户端错误状态码,表示服务器无法处理请求
  • 5XX 是服务器错误状态码,表示服务器处理请求出错

2XX 成功

  • 200 OK 表示从客户端发来的请求在服务器端被正常处理
  • 204 No Content 表示请求成功但在返回的响应报文中不含实体的主体部分
  • 206 Partial Content 表示客户端进行了范围请求

3XX 重定向

  • 301 Moved Permanently 永久性重定向,表示资源已被分配了新的 URL
  • 302 Found 临时性重定向,表示资源临时被分配了新的 URL
  • 303 See Other 表示资源存在着另一个 URL,应使用 GET 方法定向获取请求的资源
  • 304 Not Modified 表示客户端发送附带条件的请求时,服务器端允许请求访问资源但未满足条件的情况
  • 307 Temporary Redirect 临时重定向,和 302 Found 有着相同的含义

4XX 客户端错误

  • 400 Bad Request 表示请求报文中存在语法错误
  • 401 Unauthorized 表示发送的请求需要有通过 HTTP 认证的认证信息
  • 403 Forbidden 表示对请求资源的访问被服务器拒绝
  • 404 Not Found 表示服务器上无法找到请求的资源

5XX 服务器错误

  • 500 Internal Server Error 表示服务器端在执行请求时发生了错误
  • 503 Service Unavailable 表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求

GET 和 POST 的区别

安全是指请求方法不会破坏服务器上的资源

幂等是指多次执行相同的操作,其结果都是相同的

  • 语义上(最本质的区别)
    • GET 是从服务器获取指定的资源,GET 方法是安全、幂等、可被缓存的
    • POST 是根据请求负荷(报文 body)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST 不安全、不幂等、(大部分实现)不可缓存。

在实际过程中开发者不一定会按照 RFC 规范定义的语义来实现 GETPOST 方法

  • 可以用 GET 方法实现新增或删除数据的请求,这样实现的 GET 方法自然就不是安全和幂等;
  • 可以用 POST 方法实现查询数据的请求,这样实现的 POST 方法自然就是安全和幂等

GET 请求可以带 body 吗?

RFC 规范并没有规定 GET 请求不能带 body。只是因为 RFC 规范定义的 GET 请求是获取资源,所以根据这个语义不需要用到 body。
理论上任何 HTTP 请求都可以带 body,任何 HTTP 请求的 URL 也可以携带查询参数

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/network/tcp.html b/fe/network/tcp.html index f09f7d968..813f5b9de 100644 --- a/fe/network/tcp.html +++ b/fe/network/tcp.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

TCP

TCP(Transmission Control Protocol 传输控制协议)是一个面向连接的可靠的基于字节流的传输层通信协议

TCP 连接

TCP 连接是用于保证可靠性和流量控制维护的某些状态信息的组合,这些信息包括 Socket、序列号和窗口大小

  • Socket:由 IP 地址和端口号组成
  • 序列号:用来解决乱序问题等
  • 窗口大小:用来做流量控制

TCP 四元组

  • 源地址
  • 源端口
  • 目的地址
  • 目的端口

TCP 四元组可以唯一的确定一个连接

三次握手

TCP 连接建立

三次握手是指在建立一个 TCP 连接时客户端和服务器总共要发送 3 个数据包以确认连接的建立

三次握手的过程如下图所示:

TCP 三次握手

最开始时客户端和服务器都处于 CLOSED 状态。然后服务器主动监听某个端口(此时处于 LISTEN 状态)

第一次握手

由客户端发起

客户端会随机初始化一个序列号(client_isn)然后发送一个带有 SYN seq = client_isn 信息的数据包。发送完成后客户端进入 SYN_SEND 状态(连接发送状态)

  • SYN 是一个标志位,为 1 时表示希望建立连接
  • seq = client_isn 是客户端随机初始化的序列号(一个 32 位的无符号数)

第二次握手

由服务器发起

服务器收到客户端的 SYN 报文后,首先会随机初始化自己的序列号(server_isn)然后发送一个带有 SYN ACK seq = server_isn ack = client_isn + 1 信息的数据包。发送完成后服务器进入 SYN_RCVD 状态(连接收到状态)

  • ACK 是一个标志位,表示收到了请求
  • seq = server_isn 是服务器随机初始化的序列号(一个 32 位的无符号数)
  • ack = client_isn + 1 是一个确认应答号,值为客户端序列号 + 1

第三次握手

由客户端发起

客户端收到服务器报文后,会再发送一个带有 ACK ack = server_isn + 1 信息的数据包。发送完成后客户端进入 ESTABLISHED 状态(连接成功状态)服务器收到客户端发送的应答报文包后也会进入 ESTABLISHED 状态

  • ack = server_isn + 1 是一个确认应答号,值为服务器序列号 + 1

三次握手可以保证客户端和服务器能够确认双方的接收和发送能力是否正常

  • 第一次握手:客户端发送 SYN 报文给服务器,服务器接收该报文
    • 客户端什么都不能确认
    • 服务器确认:自己接收正常,对方发送正常
  • 第二次握手:服务器发送 SYN + ACK 报文给客户端,客户端接收该报文
    • 客户端确认:自己发送正常、接收正常,对方发送正常、接收正常
    • 服务器确认:自己接收正常,对方发送正常
  • 第三次握手:客户端发送 ACK 报文给服务器
    • 客户端在第二次握手时已经完成确认
    • 服务器确认:自己发送正常,接收正常,对方发送正常、接收正常

三次握手的作用?

  1. 防止旧的重复连接初始化造成混乱
  2. 同步双方初始序列号(序列号能够保证数据包不重复、不丢弃和按序传输)
  3. 避免资源浪费

为什么不是两次握手?

两次握手无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号

为什么不是四次握手?

因为通过前三次已经可以建立一个可靠的连接,如果再发送第四次确认消息会浪费资源,所以不需要使用更多的通信次数

三次握手过程中,可以携带数据吗?

第一次、第二次握手不可以携带数据,第三次握手可以携带数据,因为在第三次握手时客户端已经处于连接状态,已经知道服务器的接收、发送能力是正常的

四次挥手

TCP 连接断开

四次挥手是指断开一个 TCP 连接时客户端和服务器总共发送 4 个包以确认连接的断开
客户端和服务器双方都可以主动断开连接

四次挥手的过程如下图所示:

TCP 四次挥手

最开始时客户端和服务器都处于 ESTABLISHED 状态

第一次挥手

客户端先发送一个带有 FIN=1 信息的数据包,然后客户端进入 FIN_WAIT_1 状态

第二次挥手

服务器收到客户端的 FIN 报文后,就向客户端发送 ACK 应答报文,然后服务器进入 CLOSED_WAIT 状态
当客户端收到服务器的 ACK 应答报文后会进入 FIN_WAIT_2 状态

第三次挥手

当服务器处理完数据后,会向客户端发送 FIN 报文,之后服务器进入 LAST_ACK 状态

第四次挥手

服务器收到服务器的 FIN 报文后,会回复一个 ACK 应答报文,之后进入 TIME_WAIT 状态
服务器收到了 ACK 应答报文后,就进入了 CLOSED 状态(服务器完成连接的关闭
客户端在经过 2MSL 一段时间后会自动进入 CLOSED 状态(客户端完成连接的关闭

什么是 MSL

MSL 是 Maximum Segment Lifetime(报文最大生存时间)是任何报文在网络上存在的最长时间,超过这个时间报文将会被丢弃

2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务器,客户端又接收到了服务器重发的 FIN 报文,那么 2MSL 时间将重新计时

为什么挥手需要四次?

  • 在关闭连接时客户端向服务器发送 FIN 时,仅表示客户端不再发送数据了但是还能接收数据;
  • 当服务器在收到客户端的 FIN 报文时,会先回一个 ACK 应答报文,而服务器可能还有数据需要处理和发送,等服务器不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

为什么需要 TIME_WAIT 状态?

主动发起关闭连接的一方才有 TIME-WAIT 状态

  1. 防止历史连接中的数据,被后面相同四元组的连接错误的接收;
  2. 保证被动关闭连接的一方,能被正确的关闭;

为什么 TIME_WAIT 等待的时间是 2MSL?

  1. 保证服务器能收到最后的 ACK 应答报文
  2. 让此次 TCP 连接中的所有报文在网络中消失,从而避免前后两个使用相同四元组的连接中的前一个连接的报文干扰后一个连接

假如客户端在送 ACK 后,这个 ACK1MSL 时到达服务器,此时服务器在收到这个 ACK 的前一刹那,一直在重传 FIN,这个 FIN 最坏会在 1MSL 时间内消失。因此从客户端发送 ACK 的那一刹那开始,等待 2MSL 可以保证客户端发送的最后一个 ACK 和服务器发送的最后一个 FIN 都在网络中消失

TCP 和 UDP

TCP 和 UDP 的区别

    1. 连接
    • TCP 是面向连接的传输层协议,传输数据前先要建立连接;
    • UDP 是不需要连接,即刻传输数据。
    1. 服务对象
    • TCP 是一对一的两点服务,即一条连接只有两个端点;
    • UDP 支持一对一、一对多、多对多的交互通信。
    1. 可靠性
    • TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达;
    • UDP 是尽最大努力交付,不保证可靠交付数据。
    1. 拥塞控制、流量控制
    • TCP 有拥塞控制和流量控制机制,保证数据传输的安全性;
    • UDP 没有拥塞控制、流量控制,即使网络非常拥堵了,也不会影响 UDP 的发送速率。
    1. 首部开销
    • TCP 首部长度较长会有一定的开销,首部在没有使用“选项”字段时是 20 个字节,如果使用了“选项”字段则会变长的;
    • UDP 首部只有 8 个字节,并且是固定不变的,开销较小。
    1. 传输方式
    • TCP 是流式传输,没有边界,但保证顺序和可靠;
    • UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。
    1. 分片不同
    • TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
    • UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再传给传输层。

MSS(Maximum Segment Siz)最大分段大小:一个网络包中除去 IP 和 TCP 头部之后所能容纳的 TCP 数据的最大长度 MTU(Maximum Transmission Unit)最大传输单元:一个网络包的最大长度(以太网中一般为 1500 字节)

TCP 和 UDP 的应用场景

  • TCP 面向连接,能保证数据的可靠性交付,因此经常用于:
    • FTP 文件传输
    • HTTP / HTTPS
  • UDP 面向无连接,可随时发送数据,其本身的处理既简单又高效,因此经常用于:
    • 包总量较少的通信,如 DNS 、SNMP 等
    • 视频、音频等多媒体通信
    • 广播通信

TCP 和 UDP 可以同时绑定相同的端口吗?

传输层的端口号是用于识别同一计算机中同时通信的不同应用程序,而 TCP 和 UDP 是两个不同的传输层协议,其在内核中是两个完全独立的软件模块。
当主机收到数据包后,可以在 IP 包头的协议号字段知道该数据包是 TCP 还是 UDP,所以可以根据这个信息确定送给哪个模块 (TCP/UDP) 处理,送给 TCP/UDP 模块的报文根据端口号确定送给哪个应用程序处理。
因此 TCP 和 UDP 各自的端口号是相互独立的,如 TCP 有一个 80 号端口,UDP 也可以有一个 80 号端口,二者并不冲突。

TCP 相关学习文章

TCP 三次握手与四次挥手面试题 —— 小林 coding

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/node/pkg.html b/fe/node/pkg.html index d975defaa..ed99aaea0 100644 --- a/fe/node/pkg.html +++ b/fe/node/pkg.html @@ -13,7 +13,7 @@ - + @@ -67,7 +67,7 @@ // recommend { "licenses": "MIT" -}

文件配置

type

'commonjs' | 'module' 表明包使用的模块语法( Node@14 以上版本支持 ES Module

  • 默认为 commonjs, 对于 mjs 后缀名文件采用 ESM 语法解析

  • 设置为 module 时,对于 cjs 后缀名文件采用 commonjs 语法解析

bin

string | { ${binName}: ${binFilePath} } 声明包的脚本文件

脚本文件一般在文件头以 SheBang 声明运行脚本的语言

sh
npm install demo -g
+}

文件配置

type

'commonjs' | 'module' 表明包使用的模块语法( Node@14 以上版本支持 ES Module

  • 默认为 commonjs, 对于 mjs 后缀名文件采用 ESM 语法解析

  • 设置为 module 时,对于 cjs 后缀名文件采用 commonjs 语法解析

bin

string | { ${binName}: ${binFilePath} } 声明包的脚本文件

脚本文件一般在文件头以 SheBang 声明运行脚本的语言

sh
npm install demo -g
 
 d
 # log: Npm is COOL
js
#!/usr/bin/env node
@@ -80,7 +80,7 @@
 }
sh
.
 ├── bin
    └── demo.js
-└── package.json

files

Array<string> 指明将此项目作为依赖包安装时包含的文件,默认为排除以下文件的全部内容:

  • .git
  • CVS
  • .svn
  • .hg
  • .lock-wscript
  • .wafpickle-N
  • .*.swp
  • .DS_Store
  • ._*
  • npm-debug.log
  • .npmrc
  • node_modules
  • config.gypi
  • *.orig
  • package.json / npm-shrinkwrap.json

TIP

files 字段作用类似的还有 .npmignore.gitignore

files 类似于白名单,往往产物内容更少更方便。而 ignore 文件类似于黑名单,需要开发者持续维护

types

string => filePath 声明此项目的 TypeScript 类型文件

TIP

  • typestypings 意义完全相同,可替换使用
  • 当主声明文件命名为 index.d.ts,并且位于包的根目录与 index.js 同级,则可以省略 types 字段,但建议保持良好的声明式习惯

参阅 TypeScript | Docs

main

string 标准化的工具包主入口

默认为 index.js ,主要用于 Node.jscjs 模块

js
const foo = require('foo') // => from "main" field
+└── package.json

files

Array<string> 指明将此项目作为依赖包安装时包含的文件,默认为排除以下文件的全部内容:

  • .git
  • CVS
  • .svn
  • .hg
  • .lock-wscript
  • .wafpickle-N
  • .*.swp
  • .DS_Store
  • ._*
  • npm-debug.log
  • .npmrc
  • node_modules
  • config.gypi
  • *.orig
  • package.json / npm-shrinkwrap.json

TIP

files 字段作用类似的还有 .npmignore.gitignore

files 类似于白名单,往往产物内容更少更方便。而 ignore 文件类似于黑名单,需要开发者持续维护

types

string => filePath 声明此项目的 TypeScript 类型文件

TIP

  • typestypings 意义完全相同,可替换使用
  • 当主声明文件命名为 index.d.ts,并且位于包的根目录与 index.js 同级,则可以省略 types 字段,但建议保持良好的声明式习惯

参阅 TypeScript | Docs

main

string 标准化的工具包主入口

默认为 index.js ,主要用于 Node.jscjs 模块

js
const foo = require('foo') // => from "main" field
 // foo => { value: 1 }
js
// foo.cjs
 module.exports = {
   value: 1,
@@ -145,7 +145,7 @@
       }
     }
   }
-}

脚本配置

scripts

Record<string, string> 带有以下默认生命周期的脚本命令: <pre> | <post>

  • install
  • uninstall
  • start
  • restart
  • stop
  • test
  • pack
  • publish
  • 自定义脚本命令

特殊的 prepareprepublishOnlyscripts 文档

TIP

在 pnpm@6 与 yarn2 中, preinstall 将在 install 后执行,而不是在 install 之前

为此 pnpm 提供了 pnpm:devPreinstall 钩子以兼容开发者的使用习惯

config

Record<string, string> process.env 配置命令行的环境变量

js
#!/usr/bin/env node
+}

脚本配置

scripts

Record<string, string> 带有以下默认生命周期的脚本命令: <pre> | <post>

  • install
  • uninstall
  • start
  • restart
  • stop
  • test
  • pack
  • publish
  • 自定义脚本命令

特殊的 prepareprepublishOnlyscripts 文档

TIP

在 pnpm@6 与 yarn2 中, preinstall 将在 install 后执行,而不是在 install 之前

为此 pnpm 提供了 pnpm:devPreinstall 钩子以兼容开发者的使用习惯

config

Record<string, string> process.env 配置命令行的环境变量

js
#!/usr/bin/env node
 
 console.log(process.env.npm_package_config_port) // 8732
 console.log(process.env.npm_package_config_foo) // bar
json
{
@@ -181,7 +181,7 @@
     "cpu": ["!arm"]
   }
 }

第三方配置

sideEffects

boolean | Array<string => filePath> 声明存在副作用的模块,用于 Webpack 等打包工具的导出优化

对于模块是否有副作用的定义,基本是指开发者在设计时是否产生了副作用,而不必关心经过打包工具处理后的最终产物。

unpkg

string => filePath 在发布到 npm 后,可以使用此字段为项目对应的文件开启 CDN 服务,默认为 main

TIP

参阅 unpkg | docs

jsdelivr

string => filePath 类似于 unpkg

cosmiconfig

基于 cosmiconfig 实现的相关配置仅在此简单罗列常用工具

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/rollup/index.html b/fe/rollup/index.html index 3bb77910a..ec26cf49e 100644 --- a/fe/rollup/index.html +++ b/fe/rollup/index.html @@ -173,7 +173,7 @@ "private": true, "types": "./index.d.ts" }

WARNING

子包的 name 必须要以 @types/ 开头,否则 TypeScript 无法自动加载

编写 index.d.ts

ts
declare const unsafeWindow: Window

在主包中安装 types 子包

sh
pnpm add -Dw @types/shared-types

相关资料

参考了 tsconfig/bases | GitHub 的相关代码

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/typescript/base.html b/fe/typescript/base.html index c2897b62b..ba53063ba 100644 --- a/fe/typescript/base.html +++ b/fe/typescript/base.html @@ -584,7 +584,7 @@ type Result = ReturnType<typeof add> // Result: number
  • 声明泛型变量 T 表示一个函数类型
  • 声明占位变量 R,此时并不确定函数具体返回类型
  • T 类型为函数类型,则根据函数类型上下文推导出 R 具体类型并返回,否则则返回 any 类型
  • 在上述例子中,add 即为返回 number 类型的函数,由此推断出 Rnumber

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/typescript/challenges.html b/fe/typescript/challenges.html index c56695bd9..b98083225 100644 --- a/fe/typescript/challenges.html +++ b/fe/typescript/challenges.html @@ -420,7 +420,7 @@ type PercentageParser<A extends string> = A extends `${CheckPrefix<infer L>}${infer R}` ? [L, ...CheckSuffix<R>] : ['', ...CheckSuffix<A>]
  • CheckPrefix 用来判断是否有 +- 前缀,如果不存在则返回 never 表示没有符号
  • CheckSuffix 用来判断是否有 % 后缀
    • 存在 % 时返回的数组最后一个元素是 %
    • 不存在 % 时返回的数组最后一个元素是空字符串

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/typescript/triple-slash-directives.html b/fe/typescript/triple-slash-directives.html index d129468c4..8ed47301b 100644 --- a/fe/typescript/triple-slash-directives.html +++ b/fe/typescript/triple-slash-directives.html @@ -34,7 +34,7 @@ // 绝对路径 /// <reference path="D:/project/types/index.d.ts" />

/// <reference types="..." />

用于引入 @types 包中的类型声明文件

ts
/// <reference types="node" />

/// <reference lib="..." />

引用 TypeScript 提供的内置的 lib 类型声明文件,如 es2015dom

ts
/// <reference lib="es2015" />

/// <reference no-default-lib="true"/>

告诉 TypeScript 编译器不要自动引入 lib.d.ts 文件

ts
/// <reference no-default-lib="true" />

编译选项

当使用 /// <reference> 时,需要确保 TypeScript 编译器知道如何处理这些指令。可以通过以下编译选项来配置:

  • --noResolve:禁用自动解析模块,编译器不会自动解析 /// <reference> 中的文件
  • --noLib:禁用所有默认标准库文件,需要手动指定 /// <reference>
ts
// 在 TypeScript 文件顶部手动引入 ES2015 标准库
 /// <reference lib="es2015" />

其他说明

使用场景

  • 使用模块系统:如果项目使用 ES6 模块或 CommonJS,通常不需要使用 /// <reference>,而是通过 import 引入模块
  • 优先使用 tsconfig.json 配置:大多数项目应使用 tsconfig.json 来管理类型文件的引用,这样更简洁和可维护
  • 使用场景:如果在没有模块系统的环境中开发,或者需要处理全局变量、全局类型时,/// <reference> 会派上用场

注意事项

  • /// <reference> 必须出现在文件的顶部,且不能包含其他代码或注释
  • 路径必须有效且正确,否则 TypeScript 编译器无法找到并加载引用的文件

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/typescript/tsconfig.html b/fe/typescript/tsconfig.html index 6f3ad1824..fd954ef00 100644 --- a/fe/typescript/tsconfig.html +++ b/fe/typescript/tsconfig.html @@ -160,7 +160,7 @@ }, "references": [{ "path": "./tsconfig.base.json" }] }

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/typescript/utility-types.html b/fe/typescript/utility-types.html index 9f39535f9..85867f276 100644 --- a/fe/typescript/utility-types.html +++ b/fe/typescript/utility-types.html @@ -112,7 +112,7 @@ // 结果:'maomao'

Capitalize<StringType> 将字符串首字母转换为大写

Capitalize<StringType> 将字符串首字母转换为大写

举 🌰

ts
type result = Uncapitalize<'maomao'>
 // 结果:'Maomao'

Uncapitalize<StringType> 将字符串首字母转换为小写

Uncapitalize<StringType> 将字符串首字母转换为小写

举 🌰

ts
type result = Uncapitalize<'Maomao'>
 // 结果:'maomao'

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/fe/webpack/index.html b/fe/webpack/index.html index 21f4e8eea..89249169b 100644 --- a/fe/webpack/index.html +++ b/fe/webpack/index.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Webpack

Webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具

核心概念

  • entry 编译的入口文件
  • output 如何输出以及在哪里输出
  • module Webpack 一切皆模块,一个模块对应一个文件
  • chunk 代码块,由多个 module 组成
  • loader Webpack 通过不同的 loader 对模块的源代码进行转换
  • plugin 插件 Webpack 在打包构建的生命周期中提供了不同的 hooks 允许调用方能够对打包的资源注入自己的逻辑处理
  • compiler 编译器,把控整个 Webpack 打包的构建流程
  • compilation 每一次构建的上下文对象包含了当次构建的所有信息
  • dependence 记录模块间依赖关系

构建流程

Init 初始化阶段

  1. 解析命令行与 webpack.config.js 配置的参数,合并生成最后的配置
  2. 创建 compiler 对象并开始启动插件
    1. 调用 createCompiler 函数创建 compiler 对象
    2. 遍历注册的 Plugins 并执行其 apply 方法
    3. 调用 new WebpackOptionsApply().process 方法,根据配置内容动态注入相应插件
      1. 调用 EntryOptionPlugin 插件,该插件根据 entry 值注入 DynamicEntryPluginEntryPlugin 插件
      2. 根据 devtool 值注入 Sourcemap 插件
        1. SourceMapDevToolPlugin
        2. EvalSourceMapDevToolPlugin
        3. EvalDevToolModulePlugin
      3. 注入 RuntimePlugin 用于根据代码内容动态注入 webpack 运行时
    4. 调用 compiler.compile 方法开始执行构建

Make 构建阶段

  1. 读入文件内容
  2. 调用 Loader 将模块转译为标准的 JS 内容
  3. 调用 acorn 生成 AST 语法树
  4. 分析 AST 确定模块依赖列表
  5. 解析模块依赖(对每一个依赖模块重新执行上述流程,直到生成完整的模块依赖图 —— ModuleGraph 对象)

Seal 生成阶段

  1. 遍历模块依赖图并执行操作
    1. 代码转译,如 import 转换为 require 调用
    2. 分析运行时依赖
  2. 合并模块代码与运行时代码并生成 chunk
  3. 执行产物优化操作
    1. Tree-shaking
    2. 压缩
    3. Code Split
  4. 输出结果(根据配置确定输出的路径和文件名,把文件内容写入到文件系统)

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/hashmap.json b/hashmap.json index 6adfe301b..b84a1d347 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"analysis_cli_create-vue.md":"yXq-5e4o","analysis_react_18.2.0_base_fiber.md":"DqCllNiB","analysis_react_18.2.0_base_file.md":"CQsWCe_Y","analysis_react_18.2.0_base_idea.md":"BJfJVAJf","analysis_react_18.2.0_base_jsx.md":"Bj7WZ1BO","analysis_react_18.2.0_base_mode-process.md":"C0scj_FX","analysis_react_18.2.0_base_virtual-dom.md":"CX2jfIJe","analysis_react_18.2.0_process_begin-work.md":"DT3a_JiE","analysis_react_18.2.0_process_commit-before-mutation-effects.md":"CMXSBdgW","analysis_react_18.2.0_process_commit-layout-effects.md":"D9JZvtbx","analysis_react_18.2.0_process_commit-mutation-effects.md":"DO0h-djX","analysis_react_18.2.0_process_commit-root.md":"CBQeFSMc","analysis_react_18.2.0_process_complete-work.md":"Dca_Lxe-","analysis_react_18.2.0_process_init.md":"DYqr6Ajp","analysis_react_18.2.0_process_schedule-update-on-fiber.md":"N_HdZEcy","analysis_react_18.md":"Bj0tDRSQ","analysis_react_interview.md":"Bu8cJ0jo","analysis_utils_await-to-js.md":"BdTNg4wE","analysis_utils_clsx.md":"eDkDkEq1","analysis_utils_only-allow.md":"DxU-W68o","daily-notes_index.md":"C_05FM_c","daily-notes_issue-1.md":"C4mMosak","daily-notes_issue-10.md":"BSz_zPio","daily-notes_issue-11.md":"B8y3fdD9","daily-notes_issue-12.md":"aISK3ygm","daily-notes_issue-13.md":"CKltqrzq","daily-notes_issue-14.md":"BYu_eGLp","daily-notes_issue-15.md":"BKBSr2Jt","daily-notes_issue-16.md":"Z9XfFNvl","daily-notes_issue-17.md":"DIapiEbH","daily-notes_issue-18.md":"CEgbOswc","daily-notes_issue-19.md":"CZ9M6K_v","daily-notes_issue-2.md":"D80vKY6U","daily-notes_issue-20.md":"B7OIlH8B","daily-notes_issue-21.md":"CDyvrv8l","daily-notes_issue-22.md":"BuUb9HM5","daily-notes_issue-23.md":"DYIZ-qkk","daily-notes_issue-24.md":"CNNVIBRx","daily-notes_issue-25.md":"9viYc34y","daily-notes_issue-26.md":"aIsdq10P","daily-notes_issue-27.md":"Bb6Ngr00","daily-notes_issue-28.md":"BC3jJR5d","daily-notes_issue-29.md":"Bz-ZAdTO","daily-notes_issue-3.md":"DYvhQCvb","daily-notes_issue-30.md":"BKlJDHYL","daily-notes_issue-31.md":"BZpSNKHR","daily-notes_issue-33.md":"zbRu64ac","daily-notes_issue-34.md":"D3OY2KTu","daily-notes_issue-35.md":"gRrMe1Ki","daily-notes_issue-36.md":"CfnX15FB","daily-notes_issue-37.md":"CMpAcN91","daily-notes_issue-38.md":"Dr43-n3R","daily-notes_issue-39.md":"BHt4dqYc","daily-notes_issue-4.md":"TTSHhdbq","daily-notes_issue-41.md":"DNLNfpWY","daily-notes_issue-42.md":"BMdDh6vN","daily-notes_issue-43.md":"mAVPMvpz","daily-notes_issue-44.md":"BUfRnltY","daily-notes_issue-45.md":"BTENVm_R","daily-notes_issue-46.md":"CJaEttnA","daily-notes_issue-47.md":"BTuik0f0","daily-notes_issue-48.md":"BuavBV6t","daily-notes_issue-5.md":"Y6o7WUWN","daily-notes_issue-50.md":"AawO9fIs","daily-notes_issue-6.md":"Cqn09IBm","daily-notes_issue-7.md":"C6ua3uI8","daily-notes_issue-8.md":"B-AfTmVh","daily-notes_issue-9.md":"DIGqTN_B","efficiency_bookmark-scripts.md":"COfNcGsh","efficiency_online-tools.md":"8A_brfLc","efficiency_software_android.md":"BJ1_ks0H","efficiency_software_browser.md":"DdDPR285","efficiency_software_cross-platform.md":"B-xPNZ-3","efficiency_software_mac.md":"BfUZdqfO","efficiency_software_vscode.md":"BTSCqjIC","efficiency_software_webstorm.md":"C4f3V4vw","efficiency_software_windows.md":"CwBuphQg","fe_browser_index.md":"BZBxfGhK","fe_coding_index.md":"CyzbIz_F","fe_concept_module.md":"DxX1Jzn4","fe_concept_page-rendering.md":"Crn4UGUy","fe_css_index.md":"C1Z5fJxw","fe_es6_index.md":"Py6cpHZi","fe_html_index.md":"DAApHNQf","fe_javascript_clone.md":"DJoDyhes","fe_javascript_conversions.md":"HNtnnTWi","fe_javascript_inherit.md":"CuuS2whO","fe_javascript_prototype.md":"6MpwYev9","fe_javascript_this.md":"B0X6h3nI","fe_javascript_types.md":"l2bDpkeH","fe_monorepo_index.md":"C7rO54Ic","fe_network_http.md":"BKjH5mMh","fe_network_tcp.md":"D1KPSAUn","fe_node_pkg.md":"BKRyM3y-","fe_rollup_index.md":"85iSDhmK","fe_typescript_base.md":"CwmBAaNF","fe_typescript_challenges.md":"BUWdQoYk","fe_typescript_triple-slash-directives.md":"CVkjI10H","fe_typescript_tsconfig.md":"C0cZUt09","fe_typescript_utility-types.md":"npD0V8Pt","fe_webpack_index.md":"B_8xE4d1","index.md":"BZPRc_Kt","mao.md":"DxEaPOpo","nav.md":"BuoLDEOc","pit_browser.md":"BXb7O5oa","pit_css.md":"KUTJC7oA","pit_editor.md":"Dor5Xkgu","pit_h5.md":"DgPDJ25e","pit_javascript.md":"zf0x6cfi","pit_library.md":"fwkuazt0","pit_npm.md":"B7725AhM","pit_pc.md":"BNWrMkAt","pit_typescript.md":"DRJ8qDFa","pit_wechat.md":"5Df7u_1w","workflow_css_spec.md":"Ct2coWD5","workflow_css_tricks.md":"CDO2n8b8","workflow_git_command.md":"Dm0xNlnG","workflow_git_index.md":"BZgssJJx","workflow_html_tricks.md":"m0zZDByK","workflow_layouts_border_index.md":"DNINtWYh","workflow_layouts_effects_text.md":"CmjlsH19","workflow_layouts_progress_index.md":"BCDylDwE","workflow_library_csv.md":"dR1KIvUW","workflow_library_dayjs.md":"C7eBLzYu","workflow_library_gsap.md":"D_M9aHeu","workflow_library_tailwindcss.md":"ByDQ3IrY","workflow_node_npm.md":"COOJSx_a","workflow_sass_index.md":"DEWIcCzH","workflow_style-guide.md":"D89Haepf","workflow_terminal_shell.md":"BebXHLFb","workflow_terminal_toolkit.md":"cSK-wb5e","workflow_terminal_zsh.md":"dI2UmAq0","workflow_tricks_index.md":"DSKHNOYK","workflow_utils_library.md":"CQuzP0rN","workflow_utils_regexp.md":"CC54oVLL","workflow_utils_snippets.md":"Cxu3quYE","workflow_vue_index.md":"BfNuxkij"} +{"analysis_cli_create-vue.md":"yXq-5e4o","analysis_react_18.2.0_base_fiber.md":"DqCllNiB","analysis_react_18.2.0_base_file.md":"CQsWCe_Y","analysis_react_18.2.0_base_idea.md":"BJfJVAJf","analysis_react_18.2.0_base_jsx.md":"Bj7WZ1BO","analysis_react_18.2.0_base_mode-process.md":"C0scj_FX","analysis_react_18.2.0_base_virtual-dom.md":"CX2jfIJe","analysis_react_18.2.0_process_begin-work.md":"DT3a_JiE","analysis_react_18.2.0_process_commit-before-mutation-effects.md":"CMXSBdgW","analysis_react_18.2.0_process_commit-layout-effects.md":"D9JZvtbx","analysis_react_18.2.0_process_commit-mutation-effects.md":"DO0h-djX","analysis_react_18.2.0_process_commit-root.md":"CBQeFSMc","analysis_react_18.2.0_process_complete-work.md":"Dca_Lxe-","analysis_react_18.2.0_process_init.md":"DYqr6Ajp","analysis_react_18.2.0_process_schedule-update-on-fiber.md":"N_HdZEcy","analysis_react_18.md":"Bj0tDRSQ","analysis_react_interview.md":"Bu8cJ0jo","analysis_utils_await-to-js.md":"BdTNg4wE","analysis_utils_clsx.md":"eDkDkEq1","analysis_utils_only-allow.md":"DxU-W68o","daily-notes_index.md":"DrbQEmyg","daily-notes_issue-1.md":"C4mMosak","daily-notes_issue-10.md":"BSz_zPio","daily-notes_issue-11.md":"B8y3fdD9","daily-notes_issue-12.md":"aISK3ygm","daily-notes_issue-13.md":"CKltqrzq","daily-notes_issue-14.md":"BYu_eGLp","daily-notes_issue-15.md":"BKBSr2Jt","daily-notes_issue-16.md":"Z9XfFNvl","daily-notes_issue-17.md":"DIapiEbH","daily-notes_issue-18.md":"CEgbOswc","daily-notes_issue-19.md":"CZ9M6K_v","daily-notes_issue-2.md":"D80vKY6U","daily-notes_issue-20.md":"B7OIlH8B","daily-notes_issue-21.md":"CDyvrv8l","daily-notes_issue-22.md":"BuUb9HM5","daily-notes_issue-23.md":"DYIZ-qkk","daily-notes_issue-24.md":"CNNVIBRx","daily-notes_issue-25.md":"9viYc34y","daily-notes_issue-26.md":"aIsdq10P","daily-notes_issue-27.md":"Bb6Ngr00","daily-notes_issue-28.md":"BC3jJR5d","daily-notes_issue-29.md":"Bz-ZAdTO","daily-notes_issue-3.md":"DYvhQCvb","daily-notes_issue-30.md":"BKlJDHYL","daily-notes_issue-31.md":"BZpSNKHR","daily-notes_issue-33.md":"zbRu64ac","daily-notes_issue-34.md":"D3OY2KTu","daily-notes_issue-35.md":"gRrMe1Ki","daily-notes_issue-36.md":"CfnX15FB","daily-notes_issue-37.md":"CMpAcN91","daily-notes_issue-38.md":"Dr43-n3R","daily-notes_issue-39.md":"BHt4dqYc","daily-notes_issue-4.md":"TTSHhdbq","daily-notes_issue-41.md":"DNLNfpWY","daily-notes_issue-42.md":"BMdDh6vN","daily-notes_issue-43.md":"mAVPMvpz","daily-notes_issue-44.md":"BUfRnltY","daily-notes_issue-45.md":"BTENVm_R","daily-notes_issue-46.md":"CJaEttnA","daily-notes_issue-47.md":"BTuik0f0","daily-notes_issue-48.md":"BuavBV6t","daily-notes_issue-5.md":"Y6o7WUWN","daily-notes_issue-50.md":"AawO9fIs","daily-notes_issue-51.md":"B9SDbeoB","daily-notes_issue-6.md":"Cqn09IBm","daily-notes_issue-7.md":"C6ua3uI8","daily-notes_issue-8.md":"B-AfTmVh","daily-notes_issue-9.md":"DIGqTN_B","efficiency_bookmark-scripts.md":"COfNcGsh","efficiency_online-tools.md":"8A_brfLc","efficiency_software_android.md":"BJ1_ks0H","efficiency_software_browser.md":"DdDPR285","efficiency_software_cross-platform.md":"B-xPNZ-3","efficiency_software_mac.md":"BfUZdqfO","efficiency_software_vscode.md":"BTSCqjIC","efficiency_software_webstorm.md":"C4f3V4vw","efficiency_software_windows.md":"CwBuphQg","fe_browser_index.md":"BZBxfGhK","fe_coding_index.md":"CyzbIz_F","fe_concept_module.md":"DxX1Jzn4","fe_concept_page-rendering.md":"Crn4UGUy","fe_css_index.md":"C1Z5fJxw","fe_es6_index.md":"Py6cpHZi","fe_html_index.md":"DAApHNQf","fe_javascript_clone.md":"DJoDyhes","fe_javascript_conversions.md":"HNtnnTWi","fe_javascript_inherit.md":"CuuS2whO","fe_javascript_prototype.md":"6MpwYev9","fe_javascript_this.md":"B0X6h3nI","fe_javascript_types.md":"l2bDpkeH","fe_monorepo_index.md":"KCsXh0q5","fe_network_http.md":"BKjH5mMh","fe_network_tcp.md":"D1KPSAUn","fe_node_pkg.md":"DegpvfnG","fe_rollup_index.md":"85iSDhmK","fe_typescript_base.md":"CwmBAaNF","fe_typescript_challenges.md":"BUWdQoYk","fe_typescript_triple-slash-directives.md":"CVkjI10H","fe_typescript_tsconfig.md":"C0cZUt09","fe_typescript_utility-types.md":"npD0V8Pt","fe_webpack_index.md":"B_8xE4d1","index.md":"BZPRc_Kt","mao.md":"DxEaPOpo","nav.md":"BuoLDEOc","pit_browser.md":"BXb7O5oa","pit_css.md":"KUTJC7oA","pit_editor.md":"ajctGNTx","pit_h5.md":"DgPDJ25e","pit_javascript.md":"zf0x6cfi","pit_library.md":"fwkuazt0","pit_npm.md":"B7725AhM","pit_pc.md":"BNWrMkAt","pit_typescript.md":"DRJ8qDFa","pit_wechat.md":"5Df7u_1w","workflow_css_spec.md":"Ct2coWD5","workflow_css_tricks.md":"CDO2n8b8","workflow_git_command.md":"Dm0xNlnG","workflow_git_index.md":"BZgssJJx","workflow_html_tricks.md":"m0zZDByK","workflow_layouts_border_index.md":"DNINtWYh","workflow_layouts_effects_text.md":"CmjlsH19","workflow_layouts_progress_index.md":"BCDylDwE","workflow_library_csv.md":"dR1KIvUW","workflow_library_dayjs.md":"CxZPm0C6","workflow_library_gsap.md":"D_M9aHeu","workflow_library_tailwindcss.md":"ByDQ3IrY","workflow_node_npm.md":"COOJSx_a","workflow_sass_index.md":"DEWIcCzH","workflow_style-guide.md":"D89Haepf","workflow_terminal_shell.md":"BebXHLFb","workflow_terminal_toolkit.md":"cSK-wb5e","workflow_terminal_zsh.md":"CCt2xNBQ","workflow_tricks_index.md":"DSKHNOYK","workflow_utils_library.md":"CQuzP0rN","workflow_utils_regexp.md":"CC54oVLL","workflow_utils_snippets.md":"Cxu3quYE","workflow_vue_index.md":"BfNuxkij"} diff --git a/index.html b/index.html index 979f47e7c..3a08f301f 100644 --- a/index.html +++ b/index.html @@ -34,7 +34,7 @@ "link": "https://notes.fe-mm.com", "icon": "https://notes.fe-mm.com/logo.png" }

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/mao.html b/mao.html index 82931f351..b21ae31b0 100644 --- a/mao.html +++ b/mao.html @@ -30,7 +30,7 @@
Skip to content

茂茂 maoamo maoamo1996

sh
吾志所向,一往无前。
                                 -- 一个想躺平的小开发

About:

Contact me:

添加好友时请添加备注,谢谢!

WechatQQEmail

Languages:

HTML5CSS3JavaScriptTypeScriptShell ScriptMarkDown

Frameworks, Platforms and Libraries:

WebPackRollupViteReactNext.jsAnt DesignVue.jsExpressJestTaroLodashSassLessTailwind CSSSwiper

Editors and Tools:

Visual Studio CodeWebStormGitIterm2ZshHomebrewNode.jsNpmPnpmYarnPrettierESLintVercelNetlify

最后更新于:

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/nav.html b/nav.html index 575670416..63b609ef5 100644 --- a/nav.html +++ b/nav.html @@ -30,7 +30,7 @@
- + \ No newline at end of file diff --git a/pit/browser.html b/pit/browser.html index d77af8229..da465bd81 100644 --- a/pit/browser.html +++ b/pit/browser.html @@ -110,7 +110,7 @@ 6697, // IRC + TLS 10080, // Amanda };

kRestrictedPorts | Chromium

解决方法

  1. 修改项目启动端口为其他可访问的端口(推荐)
  2. 修改浏览器启动参数放开端口限制
    1. MacOS 系统:通过终端命令 open -a "Google Chrome" --args --explicitly-allowed-ports=6000,6666 启动浏览器
    2. Windows 系统:在桌面快捷方式上右键,选择 属性,在 目标 后面添加 --explicitly-allowed-ports=6000,6666 后保存,再通过快捷方式启动浏览器

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/css.html b/pit/css.html index 67ab98e90..0f7e57512 100644 --- a/pit/css.html +++ b/pit/css.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

CSS 踩坑记录

记录个人遇到过或他人分享的 CSS 相关踩坑记录

flex 项目上设置 width 无效

在使用 flex 布局时,给项目设置 width 无效

解决方法

  1. 使用 flex-basis 代替 width
  2. 使用 min-width 代替 width
  3. 设置 flex-shrink: 0 禁止项目缩小,再设置 width

:visited 不支持 animation

在本博客站点中,整了花里胡哨的颜色动画,但是发现 :visited 伪类不支持 animation,导致无法实现效果(各种访问过的链接颜色错乱)

:visited 选择器知识点

:visited 伪类表示用户已访问过的链接,它只支持下列 CSS 属性,其他属性无效

  • color
  • background-color
  • border-color
  • outline-color
  • fillstroke 属性的颜色部分

相关资料

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/editor.html b/pit/editor.html index c43e504c5..5039272b9 100644 --- a/pit/editor.html +++ b/pit/editor.html @@ -13,7 +13,7 @@ - + @@ -28,8 +28,8 @@ -
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

编辑器踩坑记录

在 VSCode 使用 GUI 时提示 xxx: command not found

husky 为例

在 VSCode 中使用 GUI(源代码管理 - 输入框)进行 git commit 时,提示 Git: .husky/commit-msg: line 4: npx: command not found

原因

  1. 使用了 fnmnvm 存在了多个版本的 Node.js
  2. 在终端外部启动的 GUI 不会初始化 Node.js,导致 $PATH 中没有 Node.js
  3. 当使用 VSCode GUI 时,就会导致 Node.js 相关的命令丢失

解决方法

一共有如下几种方案

  1. 通过 VSCode 的 code 命令打开编辑器(使用命令行进入到项目目录 code .
  2. 添加 ~/.config/husky/init.sh~/.huskyrc 文件(内容如下)

~/.huskyrc 高版本已弃用

bash
eval "$(fnm env --use-on-cd)"
bash
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

shell 启动文件快速且轻量级时可直接在 ~/.config/husky/init.sh~/.huskyrc 配置如下

Oh My ZSH: 你们针对我?

sh
. ~/.zshrc

如有转载或 CV 的请标注本站原文地址

- +
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

编辑器踩坑记录

在 VSCode 使用 GUI 时提示 xxx: command not found

husky 为例

在 VSCode 中使用 GUI(源代码管理 - 输入框)进行 git commit 时,提示 Git: .husky/commit-msg: line 4: npx: command not found

原因

  1. 使用了 fnmnvm 存在了多个版本的 Node.js
  2. 在终端外部启动的 GUI 不会初始化 Node.js,导致 $PATH 中没有 Node.js
  3. 当使用 VSCode GUI 时,就会导致 Node.js 相关的命令丢失

解决方法

一共有如下几种方案

  1. 通过 VSCode 的 code 命令打开编辑器(使用命令行进入到项目目录 code .
  2. 添加 ~/.config/husky/init.sh~/.huskyrc 文件(内容如下)

~/.huskyrc 高版本已弃用

bash
eval "$(fnm env --use-on-cd)"
bash
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

shell 启动文件快速且轻量级时可直接在 ~/.config/husky/init.sh~/.huskyrc 配置如下

Oh My ZSH: 你们针对我?

sh
. ~/.zshrc

如有转载或 CV 的请标注本站原文地址

+ \ No newline at end of file diff --git a/pit/h5.html b/pit/h5.html index 931a7d9ff..62854e3e6 100644 --- a/pit/h5.html +++ b/pit/h5.html @@ -38,7 +38,7 @@ } document.querySelector('body').addEventListener('touchmove', onTouchMove)

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/javascript.html b/pit/javascript.html index 69abbae33..8f1135289 100644 --- a/pit/javascript.html +++ b/pit/javascript.html @@ -41,7 +41,7 @@ size('𠮷') // 1 size('😀') // 1 size('👩‍👩‍👧‍👧') // 1

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/library.html b/pit/library.html index 906bd418b..5787b7e9c 100644 --- a/pit/library.html +++ b/pit/library.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

第三方库踩坑记录

记录个人遇到或他人分享的第三方库相关踩坑记录

moment 迁移到 dayjs

在做 webpack 构建优化时,会使用 antd-dayjs-webpack-plugin 插件将 moment 替换为 dayjs

在迁移时需要注意这些方法的部分参数不一致

  • add 增加时间
  • subtract 减少时间
  • startOf 开始时间
  • endOf 结束时间
描述moment 支持的参数dayjs 支持的参数
years year Y yyears year y
months month Mmonths month M
weeks week wweeks week w
days day ddays day d
hours hour H hhours hour h
minutes minute mminutes minute m
seconds second sseconds second s
毫秒milliseconds millisecond msmilliseconds millisecond ms

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/npm.html b/pit/npm.html index 2da4e7c05..caccceebb 100644 --- a/pit/npm.html +++ b/pit/npm.html @@ -48,7 +48,7 @@ electron_mirror=https://npmmirror.com/mirrors/electron profiler_binary_host_mirror=https://npmmirror.com/mirrors/node-inspector chromedriver_cdnurl=https://npmmirror.com/mirrors/chromedriver

npm 包中的文件丢失

最近在发布自己的 npm 包时,发现包中的文件未完全上传,导致安装后缺少文件

npm 上传时默认会忽略这些文件

  • .*.swp
  • ._*
  • .DS_Store
  • .git
  • .gitignore
  • .hg
  • .npmignore
  • .npmrc
  • .lock-wscript
  • .svn
  • .wafpickle-*
  • config.gypi
  • CVS
  • npm-debug.log

npm ignored | GitHub

解决方法

  1. 将需要上传的文件添加到 package.jsonfiles 字段中
  2. 修改文件名

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/pc.html b/pit/pc.html index 3c88c3690..0c9258f58 100644 --- a/pit/pc.html +++ b/pit/pc.html @@ -55,7 +55,7 @@ ) }) }

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/typescript.html b/pit/typescript.html index 6f80da1ee..5443951cf 100644 --- a/pit/typescript.html +++ b/pit/typescript.html @@ -40,7 +40,7 @@ } } }

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/pit/wechat.html b/pit/wechat.html index fffccef35..a2f5e5348 100644 --- a/pit/wechat.html +++ b/pit/wechat.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

微信开发踩坑记录

记录个人遇到或他人分享的微信开发踩坑记录相关踩坑记录

微信 H5 页面分享出去是明文链接不是卡片

在微信开发者工具中,点击右上角的分享按钮,选择转发给朋友,可以分享出去的是卡片,但在手机上进行分享操作时,分享出去的是明文链接

原因

微信开放全域名访问后出现的限制,在聊天窗口直接通过点击链接进入页面进行转发时会被微信拦截,导致分享出去的是明文链接

关于《微信外部链接内容管理规范》的更新说明

解决方法

不直接通过点击群聊单聊里面的明文链接进入页面,而是通过其他方式进入页面

  1. 将链接配置在公众号菜单中,通过菜单进入页面
  2. 将链接通过聊天发送给公众号,再点击链接进入页面
  3. 生成二维码,通过扫描二维码进入页面
  4. 将链接添加到收藏夹,通过收藏夹进入页面

公众号分享出去不是卡片而是链接 | 微信开放社区

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 3f36fa278..5145ff8ab 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://notes.fe-mm.com/analysis/cli/create-vue2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/fiber2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/file2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/idea2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/jsx2023-12-19T11:58:36.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/mode-process2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/virtual-dom2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/begin-work2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-before-mutation-effects2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-layout-effects2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-mutation-effects2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-root2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/complete-work2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/init2023-12-19T11:58:36.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/schedule-update-on-fiber2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/182024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/interview2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/utils/await-to-js2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/utils/clsx2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/utils/only-allow2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/daily-notes/https://notes.fe-mm.com/daily-notes/issue-1https://notes.fe-mm.com/daily-notes/issue-10https://notes.fe-mm.com/daily-notes/issue-11https://notes.fe-mm.com/daily-notes/issue-12https://notes.fe-mm.com/daily-notes/issue-13https://notes.fe-mm.com/daily-notes/issue-14https://notes.fe-mm.com/daily-notes/issue-15https://notes.fe-mm.com/daily-notes/issue-16https://notes.fe-mm.com/daily-notes/issue-17https://notes.fe-mm.com/daily-notes/issue-18https://notes.fe-mm.com/daily-notes/issue-19https://notes.fe-mm.com/daily-notes/issue-2https://notes.fe-mm.com/daily-notes/issue-20https://notes.fe-mm.com/daily-notes/issue-21https://notes.fe-mm.com/daily-notes/issue-22https://notes.fe-mm.com/daily-notes/issue-23https://notes.fe-mm.com/daily-notes/issue-24https://notes.fe-mm.com/daily-notes/issue-25https://notes.fe-mm.com/daily-notes/issue-26https://notes.fe-mm.com/daily-notes/issue-27https://notes.fe-mm.com/daily-notes/issue-28https://notes.fe-mm.com/daily-notes/issue-29https://notes.fe-mm.com/daily-notes/issue-3https://notes.fe-mm.com/daily-notes/issue-30https://notes.fe-mm.com/daily-notes/issue-31https://notes.fe-mm.com/daily-notes/issue-33https://notes.fe-mm.com/daily-notes/issue-34https://notes.fe-mm.com/daily-notes/issue-35https://notes.fe-mm.com/daily-notes/issue-36https://notes.fe-mm.com/daily-notes/issue-37https://notes.fe-mm.com/daily-notes/issue-38https://notes.fe-mm.com/daily-notes/issue-39https://notes.fe-mm.com/daily-notes/issue-4https://notes.fe-mm.com/daily-notes/issue-41https://notes.fe-mm.com/daily-notes/issue-42https://notes.fe-mm.com/daily-notes/issue-43https://notes.fe-mm.com/daily-notes/issue-44https://notes.fe-mm.com/daily-notes/issue-45https://notes.fe-mm.com/daily-notes/issue-46https://notes.fe-mm.com/daily-notes/issue-47https://notes.fe-mm.com/daily-notes/issue-48https://notes.fe-mm.com/daily-notes/issue-5https://notes.fe-mm.com/daily-notes/issue-50https://notes.fe-mm.com/daily-notes/issue-6https://notes.fe-mm.com/daily-notes/issue-7https://notes.fe-mm.com/daily-notes/issue-8https://notes.fe-mm.com/daily-notes/issue-9https://notes.fe-mm.com/efficiency/bookmark-scripts2024-01-12T09:12:24.000Zhttps://notes.fe-mm.com/efficiency/online-tools2024-03-03T15:25:41.000Zhttps://notes.fe-mm.com/efficiency/software/android2024-12-07T10:05:23.000Zhttps://notes.fe-mm.com/efficiency/software/browser2024-02-01T08:42:39.000Zhttps://notes.fe-mm.com/efficiency/software/cross-platform2024-08-29T09:24:45.000Zhttps://notes.fe-mm.com/efficiency/software/mac2024-10-29T11:13:54.000Zhttps://notes.fe-mm.com/efficiency/software/vscode2024-11-27T10:25:24.000Zhttps://notes.fe-mm.com/efficiency/software/webstorm2023-07-03T14:03:12.000Zhttps://notes.fe-mm.com/efficiency/software/windows2024-07-23T13:37:22.000Zhttps://notes.fe-mm.com/fe/browser/2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/coding/2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/concept/module2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/concept/page-rendering2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/css/2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/fe/es6/2024-08-08T14:03:23.000Zhttps://notes.fe-mm.com/fe/html/2024-03-04T15:09:14.000Zhttps://notes.fe-mm.com/fe/javascript/clone2023-09-14T11:55:51.000Zhttps://notes.fe-mm.com/fe/javascript/conversions2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/javascript/inherit2024-06-23T13:46:06.000Zhttps://notes.fe-mm.com/fe/javascript/prototype2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/javascript/this2023-12-17T14:34:21.000Zhttps://notes.fe-mm.com/fe/javascript/types2024-03-03T15:19:25.000Zhttps://notes.fe-mm.com/fe/monorepo/2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/network/http2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/network/tcp2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/node/pkg2024-08-30T10:08:42.000Zhttps://notes.fe-mm.com/fe/rollup/2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/typescript/base2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/typescript/challenges2024-03-24T09:52:11.000Zhttps://notes.fe-mm.com/fe/typescript/triple-slash-directives2024-08-16T11:35:22.000Zhttps://notes.fe-mm.com/fe/typescript/tsconfig2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/fe/typescript/utility-types2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/webpack/2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/2024-08-08T14:28:29.000Zhttps://notes.fe-mm.com/mao2024-11-10T08:35:37.000Zhttps://notes.fe-mm.com/nav2023-06-15T13:34:55.000Zhttps://notes.fe-mm.com/pit/browser2023-12-06T10:43:01.000Zhttps://notes.fe-mm.com/pit/css2024-08-01T09:55:39.000Zhttps://notes.fe-mm.com/pit/editor2024-05-10T07:44:55.000Zhttps://notes.fe-mm.com/pit/h52024-03-31T13:12:56.000Zhttps://notes.fe-mm.com/pit/javascript2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/pit/library2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/npm2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/pc2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/typescript2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/wechat2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/workflow/css/spec2023-09-21T11:49:15.000Zhttps://notes.fe-mm.com/workflow/css/tricks2024-04-03T13:46:28.000Zhttps://notes.fe-mm.com/workflow/git/command2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/workflow/git/2024-05-24T13:51:31.000Zhttps://notes.fe-mm.com/workflow/html/tricks2023-06-14T11:31:37.000Zhttps://notes.fe-mm.com/workflow/layouts/border/2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/workflow/layouts/effects/text2024-07-10T13:06:09.000Zhttps://notes.fe-mm.com/workflow/layouts/progress/2024-03-14T15:08:16.000Zhttps://notes.fe-mm.com/workflow/library/csv2024-03-12T15:16:41.000Zhttps://notes.fe-mm.com/workflow/library/dayjs2023-12-18T15:31:28.000Zhttps://notes.fe-mm.com/workflow/library/gsap2024-02-26T11:30:33.000Zhttps://notes.fe-mm.com/workflow/library/tailwindcss2023-09-14T11:55:51.000Zhttps://notes.fe-mm.com/workflow/node/npm2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/workflow/sass/2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/workflow/style-guide2024-05-24T13:56:07.000Zhttps://notes.fe-mm.com/workflow/terminal/shell2023-11-24T10:21:35.000Zhttps://notes.fe-mm.com/workflow/terminal/toolkit2024-06-03T12:56:29.000Zhttps://notes.fe-mm.com/workflow/terminal/zsh2024-05-08T08:14:18.000Zhttps://notes.fe-mm.com/workflow/tricks/2024-11-10T08:43:47.000Zhttps://notes.fe-mm.com/workflow/utils/library2023-07-23T05:11:33.000Zhttps://notes.fe-mm.com/workflow/utils/regexp2024-05-09T12:20:55.000Zhttps://notes.fe-mm.com/workflow/utils/snippets2024-05-09T12:22:29.000Zhttps://notes.fe-mm.com/workflow/vue/2023-09-14T11:55:51.000Z \ No newline at end of file +https://notes.fe-mm.com/analysis/cli/create-vue2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/fiber2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/file2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/idea2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/jsx2023-12-19T11:58:36.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/mode-process2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/base/virtual-dom2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/begin-work2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-before-mutation-effects2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-layout-effects2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-mutation-effects2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/commit-root2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/complete-work2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/init2023-12-19T11:58:36.000Zhttps://notes.fe-mm.com/analysis/react/18.2.0/process/schedule-update-on-fiber2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/182024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/react/interview2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/utils/await-to-js2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/analysis/utils/clsx2023-10-22T09:51:26.000Zhttps://notes.fe-mm.com/analysis/utils/only-allow2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/daily-notes/https://notes.fe-mm.com/daily-notes/issue-1https://notes.fe-mm.com/daily-notes/issue-10https://notes.fe-mm.com/daily-notes/issue-11https://notes.fe-mm.com/daily-notes/issue-12https://notes.fe-mm.com/daily-notes/issue-13https://notes.fe-mm.com/daily-notes/issue-14https://notes.fe-mm.com/daily-notes/issue-15https://notes.fe-mm.com/daily-notes/issue-16https://notes.fe-mm.com/daily-notes/issue-17https://notes.fe-mm.com/daily-notes/issue-18https://notes.fe-mm.com/daily-notes/issue-19https://notes.fe-mm.com/daily-notes/issue-2https://notes.fe-mm.com/daily-notes/issue-20https://notes.fe-mm.com/daily-notes/issue-21https://notes.fe-mm.com/daily-notes/issue-22https://notes.fe-mm.com/daily-notes/issue-23https://notes.fe-mm.com/daily-notes/issue-24https://notes.fe-mm.com/daily-notes/issue-25https://notes.fe-mm.com/daily-notes/issue-26https://notes.fe-mm.com/daily-notes/issue-27https://notes.fe-mm.com/daily-notes/issue-28https://notes.fe-mm.com/daily-notes/issue-29https://notes.fe-mm.com/daily-notes/issue-3https://notes.fe-mm.com/daily-notes/issue-30https://notes.fe-mm.com/daily-notes/issue-31https://notes.fe-mm.com/daily-notes/issue-33https://notes.fe-mm.com/daily-notes/issue-34https://notes.fe-mm.com/daily-notes/issue-35https://notes.fe-mm.com/daily-notes/issue-36https://notes.fe-mm.com/daily-notes/issue-37https://notes.fe-mm.com/daily-notes/issue-38https://notes.fe-mm.com/daily-notes/issue-39https://notes.fe-mm.com/daily-notes/issue-4https://notes.fe-mm.com/daily-notes/issue-41https://notes.fe-mm.com/daily-notes/issue-42https://notes.fe-mm.com/daily-notes/issue-43https://notes.fe-mm.com/daily-notes/issue-44https://notes.fe-mm.com/daily-notes/issue-45https://notes.fe-mm.com/daily-notes/issue-46https://notes.fe-mm.com/daily-notes/issue-47https://notes.fe-mm.com/daily-notes/issue-48https://notes.fe-mm.com/daily-notes/issue-5https://notes.fe-mm.com/daily-notes/issue-50https://notes.fe-mm.com/daily-notes/issue-51https://notes.fe-mm.com/daily-notes/issue-6https://notes.fe-mm.com/daily-notes/issue-7https://notes.fe-mm.com/daily-notes/issue-8https://notes.fe-mm.com/daily-notes/issue-9https://notes.fe-mm.com/efficiency/bookmark-scripts2024-01-12T09:12:24.000Zhttps://notes.fe-mm.com/efficiency/online-tools2024-03-03T15:25:41.000Zhttps://notes.fe-mm.com/efficiency/software/android2024-12-07T10:05:23.000Zhttps://notes.fe-mm.com/efficiency/software/browser2024-02-01T08:42:39.000Zhttps://notes.fe-mm.com/efficiency/software/cross-platform2024-08-29T09:24:45.000Zhttps://notes.fe-mm.com/efficiency/software/mac2024-10-29T11:13:54.000Zhttps://notes.fe-mm.com/efficiency/software/vscode2024-11-27T10:25:24.000Zhttps://notes.fe-mm.com/efficiency/software/webstorm2023-07-03T14:03:12.000Zhttps://notes.fe-mm.com/efficiency/software/windows2024-07-23T13:37:22.000Zhttps://notes.fe-mm.com/fe/browser/2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/coding/2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/concept/module2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/concept/page-rendering2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/css/2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/fe/es6/2024-08-08T14:03:23.000Zhttps://notes.fe-mm.com/fe/html/2024-03-04T15:09:14.000Zhttps://notes.fe-mm.com/fe/javascript/clone2023-09-14T11:55:51.000Zhttps://notes.fe-mm.com/fe/javascript/conversions2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/javascript/inherit2024-06-23T13:46:06.000Zhttps://notes.fe-mm.com/fe/javascript/prototype2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/javascript/this2023-12-17T14:34:21.000Zhttps://notes.fe-mm.com/fe/javascript/types2024-03-03T15:19:25.000Zhttps://notes.fe-mm.com/fe/monorepo/2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/network/http2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/network/tcp2023-02-17T12:10:21.000Zhttps://notes.fe-mm.com/fe/node/pkg2024-08-30T10:08:42.000Zhttps://notes.fe-mm.com/fe/rollup/2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/typescript/base2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/typescript/challenges2024-03-24T09:52:11.000Zhttps://notes.fe-mm.com/fe/typescript/triple-slash-directives2024-08-16T11:35:22.000Zhttps://notes.fe-mm.com/fe/typescript/tsconfig2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/fe/typescript/utility-types2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/fe/webpack/2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/2024-08-08T14:28:29.000Zhttps://notes.fe-mm.com/mao2024-11-10T08:35:37.000Zhttps://notes.fe-mm.com/nav2023-06-15T13:34:55.000Zhttps://notes.fe-mm.com/pit/browser2023-12-06T10:43:01.000Zhttps://notes.fe-mm.com/pit/css2024-08-01T09:55:39.000Zhttps://notes.fe-mm.com/pit/editor2024-05-10T07:44:55.000Zhttps://notes.fe-mm.com/pit/h52024-03-31T13:12:56.000Zhttps://notes.fe-mm.com/pit/javascript2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/pit/library2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/npm2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/pc2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/typescript2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/pit/wechat2023-11-24T10:26:42.000Zhttps://notes.fe-mm.com/workflow/css/spec2023-09-21T11:49:15.000Zhttps://notes.fe-mm.com/workflow/css/tricks2024-04-03T13:46:28.000Zhttps://notes.fe-mm.com/workflow/git/command2024-05-19T14:47:46.000Zhttps://notes.fe-mm.com/workflow/git/2024-05-24T13:51:31.000Zhttps://notes.fe-mm.com/workflow/html/tricks2023-06-14T11:31:37.000Zhttps://notes.fe-mm.com/workflow/layouts/border/2024-02-01T08:38:37.000Zhttps://notes.fe-mm.com/workflow/layouts/effects/text2024-07-10T13:06:09.000Zhttps://notes.fe-mm.com/workflow/layouts/progress/2024-03-14T15:08:16.000Zhttps://notes.fe-mm.com/workflow/library/csv2024-03-12T15:16:41.000Zhttps://notes.fe-mm.com/workflow/library/dayjs2023-12-18T15:31:28.000Zhttps://notes.fe-mm.com/workflow/library/gsap2024-02-26T11:30:33.000Zhttps://notes.fe-mm.com/workflow/library/tailwindcss2023-09-14T11:55:51.000Zhttps://notes.fe-mm.com/workflow/node/npm2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/workflow/sass/2023-10-10T12:18:08.000Zhttps://notes.fe-mm.com/workflow/style-guide2024-05-24T13:56:07.000Zhttps://notes.fe-mm.com/workflow/terminal/shell2023-11-24T10:21:35.000Zhttps://notes.fe-mm.com/workflow/terminal/toolkit2024-06-03T12:56:29.000Zhttps://notes.fe-mm.com/workflow/terminal/zsh2024-05-08T08:14:18.000Zhttps://notes.fe-mm.com/workflow/tricks/2024-11-10T08:43:47.000Zhttps://notes.fe-mm.com/workflow/utils/library2023-07-23T05:11:33.000Zhttps://notes.fe-mm.com/workflow/utils/regexp2024-05-09T12:20:55.000Zhttps://notes.fe-mm.com/workflow/utils/snippets2024-05-09T12:22:29.000Zhttps://notes.fe-mm.com/workflow/vue/2023-09-14T11:55:51.000Z \ No newline at end of file diff --git a/workflow/css/spec.html b/workflow/css/spec.html index e5ec997f4..7fa96e37a 100644 --- a/workflow/css/spec.html +++ b/workflow/css/spec.html @@ -100,7 +100,7 @@ ::-webkit-resizer { display: none; }

::-webkit-scrollbar | MDN

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/css/tricks.html b/workflow/css/tricks.html index 6ba268fa0..5d43b89c0 100644 --- a/workflow/css/tricks.html +++ b/workflow/css/tricks.html @@ -99,7 +99,7 @@ text-overflow: ellipsis; } </style>

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/git/command.html b/workflow/git/command.html index fecc72504..3b1e17e71 100644 --- a/workflow/git/command.html +++ b/workflow/git/command.html @@ -226,7 +226,7 @@ # 查看所有分支的所有操作记录(包括被删除的 commit 记录和 reset 操作) git reflog

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/git/index.html b/workflow/git/index.html index b9ebd20d9..b55b7d2cc 100644 --- a/workflow/git/index.html +++ b/workflow/git/index.html @@ -213,7 +213,7 @@ # 推送到远程仓库 git push

使用 git-filter-repo 重写 Git 历史

git-filter-repo 是一个用于重写 Git 历史的工具,相较于 git filter-branch 其执行速度更快且功能更为全面

安装

sh
# macOS
 brew install git-filter-repo

修正提交时间为作者提交时间

在使用 git rebase 并将其推送到远程仓库后,GitHub 上显示的是提交时间而非作者提交时间,导致提交记录无法准确查看

在使用前,建议先备份仓库到本地,以防出现意外情况

  1. 检查远程仓库关联

确保在运行 git filter-branch 之后重新关联远程仓库。运行以下命令检查:

sh
git remote -v
  1. 执行修改
sh
git filter-branch --env-filter 'export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"'
  • --env-filter: 用于修改环境变量
  • GIT_COMMITTER_DATE: 提交时间
  • GIT_AUTHOR_DATE: 作者提交时间
  1. 重新关联远程仓库
sh
git remote add origin <之前的远程仓库地>
  1. 推送到远程仓库

master 分支为例,使用以下命令推送修改:

sh
git push -u origin master --force

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/html/tricks.html b/workflow/html/tricks.html index 6f1abcbbc..9a2045f7c 100644 --- a/workflow/html/tricks.html +++ b/workflow/html/tricks.html @@ -33,7 +33,7 @@ <div>手&ensp;&ensp;号: 15912341234</div> <div>电子邮箱: maomao@1996.com</div> </div>
姓  名: 茂茂
手 机 号: 15912341234
电子邮箱: maomao@1996.com

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/layouts/border/index.html b/workflow/layouts/border/index.html index 466d41be5..55f7b0189 100644 --- a/workflow/layouts/border/index.html +++ b/workflow/layouts/border/index.html @@ -59,7 +59,7 @@ -webkit-mask-position: -20px -20px; } </style>

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/layouts/effects/text.html b/workflow/layouts/effects/text.html index 1464f932b..edb658414 100644 --- a/workflow/layouts/effects/text.html +++ b/workflow/layouts/effects/text.html @@ -74,7 +74,7 @@ } } </style>

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/layouts/progress/index.html b/workflow/layouts/progress/index.html index 7c34129dc..a59fa5210 100644 --- a/workflow/layouts/progress/index.html +++ b/workflow/layouts/progress/index.html @@ -84,7 +84,7 @@ -webkit-mask-composite: source-out; } </style>

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/library/csv.html b/workflow/library/csv.html index e4ad7cb04..83511b614 100644 --- a/workflow/library/csv.html +++ b/workflow/library/csv.html @@ -45,7 +45,7 @@ const csvData = stringify(data) fs.writeFile('./file.csv', csvData)

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/library/dayjs.html b/workflow/library/dayjs.html index 9d5757ef6..24f5b1e30 100644 --- a/workflow/library/dayjs.html +++ b/workflow/library/dayjs.html @@ -14,7 +14,7 @@ - + @@ -111,7 +111,7 @@ <span>{{ count.milliseconds() }}</span> </div> </div> -</template>

优点

  • 使用 Day.js 对象的 format 方法进行格式化
    • 无需自己实现格式化函数
    • 个位数时都不需要字符串补位操作
    • 在使用 format 时,在方括号中的字符不会被格式化替换
  • 兼容性良好

缺点

当需求场景超出 Day.js 对象的 format 方法的能力时(即不是标准的年月日时分秒格式)需要自己实现格式化函数

  • 40 天 13 时 14 分 00 秒
  • 52 时 13 分 14 秒
  • 100 分 50 秒

常用预设范围

常用于 antdRangePicker 组件

js
import dayjs from 'dayjs'
+</template>

优点

  • 使用 Day.js 对象的 format 方法进行格式化
    • 无需自己实现格式化函数
    • 个位数时都不需要字符串补位操作
    • 在使用 format 时,在方括号中的字符不会被格式化替换
  • 兼容性良好

缺点

当需求场景超出 Day.js 对象的 format 方法的能力时(即不是标准的年月日时分秒格式)需要自己实现格式化函数

  • 40 天 13 时 14 分 00 秒
  • 52 时 13 分 14 秒
  • 100 分 50 秒

常用预设范围

常用于 antdRangePicker 组件

js
import dayjs from 'dayjs'
 
 // 获取当前的时间
 const now = dayjs()
@@ -184,7 +184,7 @@
   近180天: [now.subtract(180, 'day'), now],
   近一年: [now.subtract(1, 'year'), now],
 }

注意点

  • 相对范围的截止时间为当前时间
  • 绝对范围的截止时间为最后一天的 23:59:00
- + \ No newline at end of file diff --git a/workflow/library/gsap.html b/workflow/library/gsap.html index 5f38ee964..05a359124 100644 --- a/workflow/library/gsap.html +++ b/workflow/library/gsap.html @@ -43,7 +43,7 @@ }) gsap.ticker.lagSmoothing(0) - + \ No newline at end of file diff --git a/workflow/library/tailwindcss.html b/workflow/library/tailwindcss.html index 3bee59759..576d0eaf3 100644 --- a/workflow/library/tailwindcss.html +++ b/workflow/library/tailwindcss.html @@ -118,7 +118,7 @@ expect(css).toBe(expected.trim()) }) })

运行测试

sh
pnpm test
- + \ No newline at end of file diff --git a/workflow/node/npm.html b/workflow/node/npm.html index 5daaa2b50..d4687593c 100644 --- a/workflow/node/npm.html +++ b/workflow/node/npm.html @@ -82,7 +82,7 @@ # 在浏览器中打开指定 npm 包的 GitHub issues npm bugs [package-name]

脚本命令相关

执行顺序:并行执行 &,继发执行 &&

例 1:npm run script1.js & npm run script2.js

例 2:npm run script1.js && npm run script2.js

获取当前正在运行的脚本名称 process.env.npm_lifecycle_event

- + \ No newline at end of file diff --git a/workflow/sass/index.html b/workflow/sass/index.html index ae5dcc5c9..3782c11ec 100644 --- a/workflow/sass/index.html +++ b/workflow/sass/index.html @@ -130,7 +130,7 @@ } @return $result; } - + \ No newline at end of file diff --git a/workflow/style-guide.html b/workflow/style-guide.html index 1a01e2fb1..a76b6c28d 100644 --- a/workflow/style-guide.html +++ b/workflow/style-guide.html @@ -118,7 +118,7 @@ npm pkg set prettier='@femm/prettier' # OR echo "module.exports = require('@femm/prettier')" > .prettierrc.cjs - + \ No newline at end of file diff --git a/workflow/terminal/shell.html b/workflow/terminal/shell.html index e256a8f17..dfbd630ef 100644 --- a/workflow/terminal/shell.html +++ b/workflow/terminal/shell.html @@ -79,7 +79,7 @@ # 移动目录到指定目录 mv ./test ./test1

TIP

常用参数说明

- + \ No newline at end of file diff --git a/workflow/terminal/toolkit.html b/workflow/terminal/toolkit.html index c34d5a3b3..168bd46a8 100644 --- a/workflow/terminal/toolkit.html +++ b/workflow/terminal/toolkit.html @@ -293,7 +293,7 @@ # 查看进程状态 pm2 monit

pm2 | Github

- + \ No newline at end of file diff --git a/workflow/terminal/zsh.html b/workflow/terminal/zsh.html index ec95455d5..bd06cc692 100644 --- a/workflow/terminal/zsh.html +++ b/workflow/terminal/zsh.html @@ -13,7 +13,7 @@ - + @@ -61,7 +61,7 @@ plugins=(其他插件 z) # 使配置生效 -source ~/.zshrc

z | Github

fast-syntax-highlighting

终端语法高亮显示

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

z | Github

fast-syntax-highlighting

终端语法高亮显示

安装

sh
# 在 ~/.zshrc 中配置
 zinit light zdharma-continuum/fast-syntax-highlighting
 
 # 使配置生效
@@ -72,7 +72,7 @@
 plugins=(其他插件 fast-syntax-highlighting)
 
 # 使配置生效
-source ~/.zshrc

Fast Syntax Highlighting | Github

zsh-autosuggestions

根据您的历史记录和完成情况建议您键入的命令

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

Fast Syntax Highlighting | Github

zsh-autosuggestions

根据您的历史记录和完成情况建议您键入的命令

安装

sh
# 在 ~/.zshrc 中配置
 zinit ice lucid wait="0" atload="_zsh_autosuggest_start"
 zinit light zsh-users/zsh-autosuggestions
 
@@ -84,7 +84,7 @@
 plugins=(其他插件 zsh-autosuggestions)
 
 # 使配置生效
-source ~/.zshrc

zsh-autosuggestions | Github

zsh 主题

powerlevel10k

安装

sh
# 在 ~/.zshrc 中配置
+source ~/.zshrc

zsh-autosuggestions | Github

zsh 主题

powerlevel10k

安装

sh
# 在 ~/.zshrc 中配置
 zinit ice depth=1
 zinit light romkatv/powerlevel10k
 
@@ -102,7 +102,7 @@
 # 比如显示当前使用的 node 版本
 
 # 使配置生效
-source ~/.zshrc

常用配置

具体可参考 —— 茂茂的 zsh 配置文件

sh
#--------------------------------------------------#
+source ~/.zshrc

常用配置

具体可参考 —— 茂茂的 zsh 配置文件

sh
#--------------------------------------------------#
 # 加载 p10k 主题
 #--------------------------------------------------#
 zinit ice depth=1
@@ -237,7 +237,7 @@
     fi
   fi
 fi

代理相关说明

同时设置大小写的环境变量来保证兼容性(因为有的应用读取的是大写的环境变量,而有的应用读取的是小写的环境变量)

- + \ No newline at end of file diff --git a/workflow/tricks/index.html b/workflow/tricks/index.html index 68f02e94a..c85e3e960 100644 --- a/workflow/tricks/index.html +++ b/workflow/tricks/index.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

常用的开发小技巧

直观的区分环境

在生产环境和开发环境中使用不同的 favicon 图标和 title,可一目了然地知道当前所处的环境,避免误操作(如调试半天都没问题最后发现是环境不对)

也可使用更多的 favicon 图标和 title 来区分不同的开发环境,如测试环境、预发布环境等

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/utils/library.html b/workflow/utils/library.html index ba93736c2..32ac0737f 100644 --- a/workflow/utils/library.html +++ b/workflow/utils/library.html @@ -29,7 +29,7 @@
Skip to content

鼓励作者:欢迎 star 或打赏犒劳

常用工具库整理

收集个人使用过或遇到的类库,按照类别进行分类,方便查找(不定期更新)

工具库

时间处理

请求处理

精度处理

字符串文本处理

动画

特效

本地存储

滚动处理

事件处理

媒体处理

音视频处理

文件处理

版本号处理

数据校验

编辑器

Markdown

代码高亮

轮播

表单处理

表格

拖放

用户体验

评论系统

开发调试

编译&构建&打包

Webpack 相关

解析相关

自动化工具

lint / 格式化相关

相关辅助工具

CLI 工具

命令行输出美化

站点生成器

如有转载或 CV 的请标注本站原文地址

- + \ No newline at end of file diff --git a/workflow/utils/regexp.html b/workflow/utils/regexp.html index 07b332f92..6c1757678 100644 --- a/workflow/utils/regexp.html +++ b/workflow/utils/regexp.html @@ -50,7 +50,7 @@ /* 以非单词边界匹配 */ '5201314 5201314'.replace(/\B(?=(\d{3})+\b)/g, ',') // '5,201,314 5,201,314' - + \ No newline at end of file diff --git a/workflow/utils/snippets.html b/workflow/utils/snippets.html index cac2a7657..37fa81c3b 100644 --- a/workflow/utils/snippets.html +++ b/workflow/utils/snippets.html @@ -176,7 +176,7 @@ gender, } } - + \ No newline at end of file diff --git a/workflow/vue/index.html b/workflow/vue/index.html index 1bca0f057..b4fd03f06 100644 --- a/workflow/vue/index.html +++ b/workflow/vue/index.html @@ -49,7 +49,7 @@ } } </script>

替换 debounce 过滤器 | Vue.js 官方文档

- + \ No newline at end of file