Skip to main content

5-21

1 Docusaurus 无法处理图片缩放 zoom

表现

无法正常打包

[ERROR] Docusaurus Node/SSR could not render static page

解决方案

<img src="https://cdn.gincool.com//img/image-20211015114938140.png" alt="image-20211015114938140" style="zoom: 25%;" />

// 将zoom去掉
<img src="https://cdn.gincool.com//img/image-20211015114938140.png" alt="image-20211015114938140" />

2 styled-system配置variant(变体)

方式一

import { styleVariants } from './theme.ts'
import { ButtonProps } from './types.ts'

const Button = styled.button<ButtonProps>`
${variant({
variants: styleVariants,
})}
`
// theme.ts
const styleVariants: {
[variant: Variant]: Record<string, string>
} = {
[variants.PRIMARY]: {
backgroundColor: 'primary',
// styled-system 会自动找到 theme.colors.primary
// 那如何找到 theme.colors.gradient.primary 呢?
// 见方法二
color: 'white',
},
[variants.SECONDARY]: {
backgroundColor: 'transparent',
color: 'primary',
border: '2px solid',
borderColor: 'primary',
boxShadow: 'none',
':disabled': {
backgroundColor: 'transparent',
},
},
}
// types.ts
export const variants = {
PRIMARY: "primary",
SECONDARY: "secondary"
} as const

export type Variant = typeof variants[typeof variants]

export interface ButtonProps {
variant: Variant
}

方式二:通过函数找到内容主题

const createStyleVariants = (theme: MyTheme) => {
[variants.PRIMARY]: {
backgroundColor: theme.colors.gradient.primary,
color: 'white',
},
[variants.SECONDARY]: {
backgroundColor: 'transparent',
color: 'primary',
border: '2px solid',
borderColor: 'primary',
boxShadow: 'none',
':disabled': {
backgroundColor: 'transparent',
},
},
}

const Button = styled.button`
${({theme})=> variant({
variants: createStyleVariants(theme),
})}
`

[1] Using theme properties in variants (with typescript) #986.https://github.com/styled-system/styled-system/issues/986

[2] pancake-frontend.https://github.com/pancakeswap/pancake-frontend

3 vscode 多行插入递增数字

🏷:工具

插件

increament selection

image-20220522110550619

方法

多行选中,cmd+option+方向下 或者 按住 cmd同时左键单击其他行

从0开始,直接 cmd+option+i

image-20220522110352125

从指定数字开始,先输入100,选中,再按 cmd+option+i

image-20220522110421706

[1] vscode同时编辑多行,插入递增数字【Increment Selection】.https://blog.csdn.net/qq_36405172/article/details/120240926?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-120240926-blog-90719829.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-120240926-blog-90719829.pc_relevant_default&utm_relevant_index=1

4 vscode 检查单词拼写

插件

Code Spell Checker

image-20220522110800253

效果

错误 蓝线 提示

image-20220522110935368

自动修复,cmd+.

image-20220522111033834

5 Docusaurus 配置gitalk

步骤:1.导出 2.申请application 3.配置gitalk 4.引入

步骤一:导出

yarn run swizzle @docusaurus/theme-classic DocPage/Layout/Main

注意:可以导出很多项目,这里只导出文档的Layout的Main,详见 swizzling

步骤二:申请application

https://github.com/settings/applications/new 申请

注册时Homepage URLAuthorization callback URL都填写网站域名即可,如https://www.banli17.com/

注册完成后,就可以看到 ID 了。

  • clientID、clientSecret: 注册应用后,可以看到。也可以在 github 的settings -> Developer settings -> OAuth Apps看到。
  • repo: 在 github 新建一个项目blog_comment(名字可随意,注意填写的不是github地址,而是项目名),评论会保存到这个项目的 issue 中。

步骤三:引入

// src/theme/GitalkComment.tsx
import React, { Component } from 'react'
import 'gitalk/dist/gitalk.css'
import Gitalk from 'gitalk'

class GitalkComment extends Component {
componentDidMount() {
var gitalk = new Gitalk({
clientID: '54aafde3eb7291b3b28d',
clientSecret: '336373fcdef4b031ecc887d3803424bf7c2cbd4e',
repo: 'gin-blog', // 仓库名称
owner: 'ginlink', // 仓库作者
admin: ['ginlink'],
id: location.pathname, // Ensure uniqueness and length less than 50
distractionFreeMode: false, // Facebook-like distraction free mode
})

gitalk.render('gitalk-container')
}

render() {
return <div id="gitalk-container"></div>
}
}
export default GitalkComment
// src/theme/DocPage/Layout/Main/index.tsx
import GitalkComment from '@site/src/theme/GitalkComment'

...

<div
className={clsx(
'container padding-top--md padding-bottom--lg',
styles.docItemWrapper,
hiddenSidebarContainer && styles.docItemWrapperEnhanced
)}
>
{children}

<BrowserOnly fallback={<div />}>{() => <GitalkComment />}</BrowserOnly>
</div>

[1] 转-如何给Docusaurus添加Gitalk插件.https://sustech-canstudio.github.io/blog/gitalk/

[2] Docusaurus配置Gitalk评论插件.https://juejin.cn/post/7055950681722585119

6 [Babel] You gave us a visitor for the node type StaticBlock but it's not a valid type.

原因

I think there's a babel version inconsistency between CRA@4 and Storybook@6, but I'm not sure what's the proper fix.

解决方案

rm yarn.lock && yarn

[1] Error: You gave us a visitor for the node type StaticBlock but it's not a valid type.https://github.com/storybookjs/storybook/issues/12893

7 uniswap-interface monorepo项目无法正常启动

项目示例见:https://github.com/ginlink/swap

错误一:提示 <ErrorBoundary> 与 React.ReaceNode 问题

原因

@types/react18@types/react17 类型声明并不兼容

解决方案

最外层package.json锁定版本

"resolutions": {
"babel-loader": "8.1.0",
"@types/react": "^17.0.1",
"@web3-react/abstract-connector": "^6.0.7"
}

错误二:i18n类型问题

原因

版本不一致

解决方案

删除所有 @types/lingui 相关内容,lingui其实从v3.0版本后自带类型声明,不需要额外声明

错误三:提示找不到 @web3-react/abstract-connector

原因

由于uniswap中其了别名,而导致@web3-react/abstract-connector并没有正确安装,所以需要手动指定安装该包

解决方案

最外层package.json锁定版本

"resolutions": {
"babel-loader": "8.1.0",
"@types/react": "^17.0.1",
"@web3-react/abstract-connector": "^6.0.7"
}

错误四:提示 ConnectEvent.Update 找不到

原因

依赖问题,别名安装导致找不到正确 @web3-react/types

解决方案

@web3-react/core 从 v8.x降级到v6.x

"@web3-react/core": "^6.0.7",

8 package.json中的 prepare 脚本的作用

进行 yarn 之后自动执行命令

{
"scripts" : {
"prepare": "yarn contracts:compile && yarn graphql:generate && yarn i18n:compile",
}
}

9 [styled-components | nextjs] Warning: Prop className did not match.

原因

没有开启ssr

解决方案

This fixed my issue :

yarn add --dev babel-plugin-styled-components

Then add this to .babelrc file:

{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}

[1] Warning: Prop className did not match. #7322.https://github.com/vercel/next.js/issues/7322

10 cra | nextjs 启动换端口

cra

Linux (tested on Ubuntu 14.04/16.04) and MacOS (tested by @aswin-s on MacOS Sierra 10.12.4):

"start": "PORT=3006 react-scripts start"

or (may be) more general solution by @IsaacPak

"start": "export PORT=3006 react-scripts start"

Windows @JacobEnsor solution

"start": "set PORT=3006 && react-scripts start"

或者可以用 cross-env 跨端定义环境变量

nextjs

{
"scripts": {
"dev": "next -p 3002",
}
}

[1] How to specify a port to run a create-react-app based project?.https://stackoverflow.com/questions/40714583/how-to-specify-a-port-to-run-a-create-react-app-based-project

[2] How to change port in nextjs?.https://medium.com/nextjs/how-to-change-port-in-nextjs-1b99930bb81f

11 npm 别名安装包

{
"devDependencies": {
"web3-react-injected-connector": "npm:@web3-react/injected-connector@^6.0.7",
}
}

use

import { ... } from 'web3-react-injected-connector'

12 react18类型错误

表现

xxx无法分配给node_modules/@types/react/React.ReactNode

原因

由于react将react18置为默认版本,而有些库会并没有限制react版本,所以导致错误的安装了 @types/react@^18

解决方案

最外层package.json锁定 @types/react 版本

"resolutions": {
"babel-loader": "8.1.0",
"@types/react": "^17.0.1",
"@web3-react/abstract-connector": "^6.0.7"
}

[1] Bug: React 18 types broken since the type release a view hours ago #24304.https://github.com/facebook/react/issues/24304

13 一些面试题

实现一个Partial

type MyPartial<T> = {[K in keyof T]?: T[K]};
type MyPartial<T> = {[K in keyof T]?: T[K]};

14 Frax稳定币

TODO

  • Frax稳定币实现逻辑
  • 常用公式

[1] Frax: 混合算法稳定币协议Doc.https://docs.frax.finance/v/zh/

15 Promise实现思路复习

本质

Promise本质上利用了 订阅-发布者模式 ,在then中订阅,在executor中发布,触发的人都是使用者;要注意的是then中的代码是微任务,所以发布的使用要用 queueMicrotask 模拟微任务代码

再动态调整状态、结果(失败和成功)

难点

从整体上看,难点在于 解析结果 ,因为这里涉及到 循环引用链式调用

then方法实现

then(onFulfilled?: any, onRejected?: any) {
// can not return a MyPromise directly,
// because there need promise2's reference
const promise2 = new MyPromise((resolve, reject) => {
if (this.state == PromiseState.PENDING) {
onFulfilled &&
this.fulfilledQueueCallbacks.push(() => {
try {
const x = onFulfilled(this.value)
promiseResolveProcedure(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
})

onRejected &&
this.rejectedQueueCallbacks.push(() => {
try {
const x = onRejected(this.reason)
promiseResolveProcedure(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
})
}


if (this.state == PromiseState.FULFILLED) {
if (onFulfilled) {
try {
const x = onFulfilled(this.value)

promiseResolveProcedure(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
} else {
resolve(this.value)
}
}

if (this.state == PromiseState.REJECTED) {
if (onRejected) {
try {
const x = onRejected(this.reason)
promiseResolveProcedure(promise2, x, resolve, reject)
} catch (err) {
reject(err)
}
} else {
reject(this.reason)
}
}
})

return promise2

// PromiseResolveProcedure mainly solves two problems:
// 1.Resolving circular references
// 2.See if there's a promise inside
function promiseResolveProcedure(that: MyPromise, x: any, resolve: any, reject: any) {
if (that === x) {
return reject(new TypeError('Circular reference'))
}

if (typeof x == 'object' || typeof x == 'function') {
let then: any
try {
then = x.then
} catch (err) {
return reject(err)
}

if (typeof then == 'function') {
const resolvePromise = (y) => {
promiseResolveProcedure(that, y, resolve, reject)
}
const rejectPromise = (r) => {
reject(r)
}

try {
then.call(x, resolvePromise, rejectPromise)
} catch (err) {
if (that.currentState == PromiseState.PENDING) {
reject(err)
}
}
} else {
resolve(x)
}
} else {
resolve(x)
}
}
}

16 为什么switch...case必须包含default

必须包含default,即使default根本不会被匹配

原因见 [1]

[1] Should switch statements always contain a default clause?.https://stackoverflow.com/questions/4649423/should-switch-statements-always-contain-a-default-clause

17 低代码调研

问题一:如何快速开发一款不怎么需要维护的产品?

目的

  • 提高工作效率,减少繁琐重复事务

    主要是一些重复性高、但又很简单的项目,比如静态官网,并不需要分配过多时间去开发

    更多时间应该花在产品上面

  • 开拓个人视野

一些平台

原理

把渲染组件生成JSON格式的抽象树,最终输出为相应的代码

18 池子中币种价格、数量、TVL、Volume之间的关系

问题一:一个币对U的价格是如何计算出来的?

问题二:在一个池子中交易会导致该池子TVL变化吗?

TODO

19 价格影响率的计算方式

问题一:价格影响率的计算的思路是什么?

问题二:有哪几种计算方式?

TODO

20 DAO

问题一:DAO是什么?

问题二:常见DAO方式有哪些?

TODO

21 质押挖矿、交易挖矿的思路是什么?

TODO

22 微前端的了解

sharded

适应场景

  • 拆分巨石应用
  • 兼容历史应用,增量开发

分类

  • 自由组织模块:systemjs模块化
  • 基座模式:single-spa
  • 去中心化:webpack模块联邦

webpack模块联邦

思想

通过webpack将模块打成远端包,本地异步加载远端包,从而实现动态异步导入远端模块

异步导入模块技巧

image-20220528091918006

image-20220528091952391

[1] Micro Frontends.https://micro-frontends.org/

[2] 为什么微前端开始在流行?B站最全微前端解决方案,小厂避雷,大厂必备!.https://www.bilibili.com/video/BV1t84y1F71m?p=1

[3] 微前端在美团外卖的实践.https://tech.meituan.com/2020/02/27/meituan-waimai-micro-frontends-practice.html