How to read the source code open source front-end large-scale projects (turn)

About the Author Daniel ants gold dress · data experience technical team

Transfer: https://github.com/ProtoTeam/blog/blob/master/201805/3.md

Currently there are many online "XX source code analysis," this article, but the article analyzes the source code of these limited scope, content and sometimes are not telling the readers are most concerned about. I also noticed that the source code is constantly updated article written source is often outdated. Because of these problems, many students look like their source, their own hands and clothing.

This article is mainly about some tips when reading the front end of a large open source projects such as React, Vue, Webpack, Babel source. The purpose is to let everyone in the face of problems to be solved in order to read the source code, the code can be faster to locate you want to see. Give a man a fish than giving the fishing, we can hope that through this blog, I learned to read the starting point when the front end of large-scale projects source code. When after encountering curious question, you can go to explore their own.

Driver problems - not to look at the source code and look at the source code

First, we must be clear that the purpose to see what the source is?

My personal opinion is, look at the source code to solve the problem. The source code for open source projects and there is nothing very special place, it is also common code. Magnitude of these codes are quite large in general, if you want to learn something from the source directly browse the entire Codebase is undoubtedly the needle in the haystack.

But if the problem is with a look at the source code, for example, want to know about the principles of synthesis of React event system, and want to know what happened before and after setState React, or want to understand the principles of Webpack plug-in system. There may be encountered a bug, I suspect the problem is the framework / tools. In such a case, with a specific target to see the source, it will be targeted.

See the latest version of the source code

Before seeing a saying, look at the first commit source code from the project's beginning to see. If it is to solve the puzzle before the text of the framework / tools produced, that nature depends on the version of the framework / tools currently used in the project.

If it is to learn the source code, I recommend watching the latest source. Because a project is in constant iteration and reconstruction. It may be a complete rewrite different versions. For example Vue 2.x and React 16. Reconstruction has led to some changes in the code architecture, Vue 2.x introduced Vritual DOM, Pull + Push data to detect changes in the way so that the entire structure of the code becomes clearer, so in fact than the 1.x 2.x code easier to read. React 16 rewrite the Reconciler, the introduction of the fiber of this concept, the entire code repository structure more clearly, so more recommended reading.

Pre-conditions

Look to see how the source code, of course, not a shuttle up.

You need to have a basic understanding of the principles of the project before looking at the source code. The so-called principle is, what part of this project, in order to reach the final output, which a few steps to go through the process. These processes, the industry mainstream program, which has several.

View layer frame such as the front end, to render the UI, after assembly to mount, render the like step. Data-driven front-end frame, after Mounted, will enter a loop, the trigger assembly when the user interaction data changes, updated UI. Detecting another embodiment wherein data points Push and Pull two options. UI can be rendered full amount of string replacement templates can also be based on the difference of the amount of Virtual DOM DOM updates.

Another example is some of the tools, Webpack Babel and the front end of these tools are based on plug-ins. The basic workflow is to read the file parsing code into AST, call the plug-in to convert AST, finally generated code. To understand the principle of Webpack, it is necessary to know Webpack based on a call  tapable  module system.

That we need to understand how those too? To understand this, you can go to "XXX-source analysis" series on the major sites and blog. Through these articles, we can have a general understanding of the principles we want to see the framework / tools.

Local build

But in the end we still have to look directly at the source. The author first step is to really look at the source code of the project to the local code repository clone. Then press guide on the building project README, locally build it.

If the front-end framework, we can directly introduced in HTML in a local build-out umd bundle (remember to use development build, or you'll code compression, poor readability), and then write a simple demo, demo in the introduction of a local build. If it is based on Nodejs tool that we can use the command npm link this tool to link local. You can see directly imported file package.json of the project, run the file directly with the node.

Here we must emphasize that large-scale open source projects usually have a Contribution Guide, the purpose is to allow developers who want to contribute faster to use. Inside there is talk about how to build the code locally.

React to, for example, React of  Contributing Guide  in the section on Development Workflow. There are so many words:

The easiest way to try your changes is to run yarn build core,dom --type=UMD and then open fixtures/packaging/babel-standalone/dev.html. This file already uses react.development.js from the build folder so it will pick up your changes.

So React warehouse fixtures / packaging / babel-standalone / dev.html is a handy demo page. We can quickly see changes in our local code on this page.

You can try adding an entry in the log file for the project, see if we can see this sentence log in the console / terminal. If so, congratulations, you can now easily play the project!

Clarify the directory structure

Before looking at specific code, we need to sort out the directory structure of the project, so that we can quickly know where to place the code to find the relevant functions.

We take a look at the directory structure of React. React is a monorepo. That is, a warehouse contains a number of sub-warehouse. We can see a lot of individual packages in the package directory:

After React 16, React code into React Core, Renderer and Reconciler three parts. This is because React is designed so that we can be responsible for mapping data to the Reconciler UI and is responsible for rendering Vritual DOM Renderer to each terminal and React Core apart. React Core contains the class definition React and some top-level API. Most of the rendering and logic in the View layer diff are in Reconciler and Renderer.

Babel is a monorepo. Babel core code is babel-core of this package, Babel open interfaces, so that we can customize the Visitor, to be called when the AST transformations. So Babel warehouse also includes a number of plug-ins, syntax into real fact is that these plug-ins, instead of babel-core itself.

Vuejs typical code, the core code in the src directory by function modules. Because Vue also supports multi-platform rendering, so the platform-dependent code is placed under the platform folders, core folder is Vue core code, compiler is Vue template compiler, the template compiled HTML styles to render function.

Webpack and Babel, as can be said is based on plug-in system. The main source of Webpack in the lib directory, which is the entrance of webpack.js file.

It says the four project directory structure, that we encounter a new open source project, you should understand how its directory structure?

If this project is a monorepo, we need to find the core of the package, then look inside the code.

不是 monorepo 的话,一般来说,如果这个项目是一个 CLI 的工具,那 bin 目录下放的就是命令行界面相关的入口文件,lib 或者 src 下面就是工具的核心代码。如果这个项目是一个前端 View 层框架,那目录结构就和 Vue 类似。

作为验证,大家可以看一下打包工具 parcel 和前端 View 层库 moon 的目录结构。目录结构这个东西往往是大同小异,多看几个项目就熟悉了。

debugger && 全局搜索大法

运行了本地的 build,了解了目录结构,接下来我们就可以开始看源码了!之前说了,我们要以问题驱动,下面我就以 React 调用 setState 前后发生了什么这个问题作为例子。

我们可以在 setState 的地方打一个断点。首先我们要找到 setState 在什么地方。这个时候之前的准备工作就派上用处了。我们知道 React 的共有 API 在 react 这个 package 下面。我们就在那个 package 里面全局搜索。我们发现这个 API 定义在 src/ReactBaseClasses.js 这个文件里。

于是我们就在这里打一个断点:

Component.prototype.setState = function(partialState, callback) {
  invariant(
    typeof partialState === 'object' || typeof partialState === 'function' || partialState == null, 'setState(...): takes an object of state variables to update or a ' + 'function which returns an object of state variables.', ); debugger; this.updater.enqueueSetState(this, partialState, callback, 'setState'); }; 

然后运行本地 React build 的 demo 页面,让组件触发 setState,我们就可以在 Devtool 里看到断点了。

我们走进 this.updater.enqueueSetState 这个调用,就来到了 ReactFiberClassComponent 这个函数中的 enqueueSetState,这里调用了 enqueueUpdate 和 scheduleWork 两个函数,如果要深入 setState 之后的流程,我们只需要再点击  走进这两个函数里看具体的代码就可以了。

如果想看 setState 之前发生了什么,我们只需要看 Devtool 右边的调用栈:

点击每一个 frame 就可以跳到对应的函数中,并且恢复当时的上下文。

结合一步一步的代码调试,我们可以看到框架的函数调用栈。对于每个重要的函数,我们可以在仓库里搜索到源码,进一步研究。

Node 工具的调试方法也是相似的,我们可以在运行 node 命令时加上 --inspect 参数。具体可以看 Debugging Node.js with Chrome DevTools 这篇博客。

其实大家都知道单步调试这种办法,但在哪里打断点才是最关键的。我们在熟悉框架的原理之后,就可以在框架的关键链路上打断点,比如前端 View 层框架的声明周期钩子和 render 方法,Node 工具的插件函数,这些代码都是框架运行的必经之地,是不错的切入点。

如果是为了了解一个特定的问题,大家可以直接在自己觉得有问题的地方打断点。然后把源码运行起来,想办法让代码运行到那个地方。我们在断点可以看到局部变量等等信息,有助于定位问题。

来自开发团队的资源

其实开源项目的开发团队也都致力于让更多的人参与到项目中来,降低项目的门槛。所以我们在线上其实可以找到很多来自开发团队的资源。这些资源可以帮助我们去理解项目的原理。

关注核心开发者

每个项目都有一些核心开发者,比如 React 的 Dan AbramovAndrew Clark 和 Sebastian Markbåge。Webpack 的 Tobias Koppers 和 Sean Larkin。Vue 的 Evan You。我们可以在 Twitter 上关注他们,了解项目的动态。

关注官方博客和演讲视频

如果我们关注了上面的核心开发者,就会发现他们时常会发布一些和源码/项目原理有关的博客或者视频。

React 的官方博客最近就有很多和项目开发有关的博客。

Andrew Clark 一开始就写了一篇介绍 fiber 架构的文档。 Dan Abramov 最近在 JSConf 上对 React 未来的一些新特性的介绍 - Beyond React 16。React 博客中的 Sneak Peek: Beyond React 16 也是对这次 Talk 的介绍。

Evan You 介绍前端框架数据变化侦测原理的 Talk。Vue 文档中也有 Reactivity in Depth 这样的介绍原理的章节。

Sean Larkin 的 Everything is a plugin! Mastering webpack from the inside out 介绍了 Webpack 的核心组件 Tapable。

James Kyle 的 How to Build a Compiler 可以让我们了解 Babel 转译代码的基本流程。

写在最后

本文最核心的观点就是,看源码的目的是为了解决问题。我们鼓励大家在本地把大型项目的源码跑起来,自己随意把玩,研究。因为源码也是普通的代码,并没有太多门槛。唯一的门槛可能就来源于开源项目作者和普通开发者之间的信息不对称,普通开发者对项目的原理和目录结构不够了解。

我们可以从开发者那里获取资源,同时也可以多阅读社区里的源码分析文章,这些都有助于我们理解项目的原理,为后续的源码分析打下基础。

Guess you like

Origin www.cnblogs.com/ygunoil/p/11984037.html