熬夜写的解析掘金新版本编辑器源码

掘金(字节跳动)MD编辑器源码解析

写在开头
  • 今天在朋友圈发现,掘金运营发布了新的掘金编辑器,作为一位曾经的富文本编辑器开发者,我当然充满了好奇,于是就有了这篇文章

  • 首先找到github源码,https://github.com/bytedance/bytemd,然后克隆下来,就开始了

最近我写了一个前端学架构100集,会慢慢更新,请大家别着急,目前在反复修改推敲内容

正式开始
  • 我本人电脑环境Arm架构Mac,M1芯片那款

  • 环境,nvm控制多个node.js版本,电脑需要全局安装pnpm,用于依赖管理(这里字节跳动是使用的pnpm管理依赖)

如果你比较菜,不懂pnpm,没事,我有文章:https://juejin.cn/post/6932046455733485575

  • 安装项目依赖(这个项目是用的lerna管理依赖):

nvm install 12.17
npm i pnpm -g
pnpm i
  • 在项目本地调试编辑器源码:

npm link或者yalc

如果你比较菜,不会这两种方式,没事,我也有文章:https://mp.weixin.qq.com/s/t6u6snq_S3R0X7b1MbvDVA,总之不会的来公众号翻翻,都有。我的前端学架构100集里面也会都有

React版本的源码解析

先看看在React里面怎么使用的

  • 先引入样式:

import 'bytemd/dist/index.min.css';
  • 再引入组件:

import { Editor, Viewer } from '@bytemd/react';
import gfm from '@bytemd/plugin-gfm';

const plugins = [
  gfm(),
  // Add more plugins here
];

const App = () => {
  const [value, setValue] = useState('');

  return (
    <Editor
      value={value}
      plugins={plugins}
      onChange={(v) => {
        setValue(v);
      }}
    />
  );
};
  • Editor组件入手

import React, { useEffect, useRef } from 'react';
import * as bytemd from 'bytemd';

export interface EditorProps extends bytemd.EditorProps {
  onChange?(value: string): void;
}

export const Editor: React.FC<EditorProps> = ({
  children,
  onChange,
  ...props
}) => {
  const ed = useRef<bytemd.Editor>();
  const el = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!el.current) return;

    const editor = new bytemd.Editor({
      target: el.current,
      props,
    });
    editor.$on('change', (e: CustomEvent<{ value: string }>) => {
      onChange?.(e.detail.value);
    });
    ed.current = editor;

    return () => {
      editor.$destroy();
    };
  }, []);

  useEffect(() => {
    // TODO: performance
    ed.current?.$set(props);
  }, [props]);

  return <div ref={el}></div>;
};

  • 发现一切都是来源于:bytemd这个库,于是我们去找到它的源码~

bytemd的源码入口文件
/// <reference types="svelte" />
import Editor from './editor.svelte';
import Viewer from './viewer.svelte';

export { Editor, Viewer };
export * from './utils';
export * from './types';

好家伙,这个Editor是用sveltejs写的,地址是:https://www.sveltejs.cn/

  • React和Vue都是基于runtime的框架。所谓基于runtime的框架就是框架本身的代码也会被打包到最终的bundle.js并被发送到用户浏览器。

  • 当用户在你的页面进行各种操作改变组件的状态时,框架的runtime会根据新的组件状态(state)计算(diff)出哪些DOM节点需要被更新,从而更新视图

  • 最小的Vue都有58k,React更有97.5k。换句话说如果你使用了React作为开发的框架,即使你的业务代码很简单,你的首屏bundle size都要100k起步。当然100k不算很大,可是事物都是相对的,相对于大型的管理系统来说100k肯定不算什么,可是对于那些首屏加载时间敏感的应用(例如淘宝,京东主页),100k的bundle size在一些网络环境不好的情况或者手机端真的会影响用户体验。那么如何减少框架的runtime代码大小呢?要想减少runtime代码的最有效的方法就是压根不用runtime

所以这里可以看出来,掘金(字节跳动)非常看重性能

什么是Svelte?
  • Svelte是由RollupJs的作者Rich Harris编写的编译型框架,没了解过RollupJs的同学可以去它官网了解一下,它其实是一个类似于Webpack的打包工具。Svelte这个框架具有以下特点:和React,Vue等现代Web框架的用法很相似,它可以允许开发者快速开发出具有流畅用户体验的Web应用。不使用Virtual DOM,也不是一个runtime的库。基于Compiler as framework的理念,会在编译的时候将你的应用转换为原生的DOM操作

这篇文章写得很全面,关于Svelte,https://zhuanlan.zhihu.com/p/97825481,由于本文重点是源码,不是环境,不是框架底层介绍,点到为止,有兴趣的去看文章~

编辑器划分为几个区域
  • 首先是标题区域,输入框,没什么好说的

  • 接下来,应该都是向编辑器插入内容的操作(重点)

  • 右边的改变一些样式和布局的,可以忽略不计

  • 左侧内容区域为编辑区域(重点)

  • 右侧为内容预览区域(重点)

先来一波性能测试

  • 这里我疯狂复制内容,一直粘贴&#x

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值