The full text is nearly 10,000 words. . . It's all here, just like it and let's go
I realized early on that being able to read the source code of an open source front-end framework proficiently and efficiently is one of the basic skills that a senior front-end engineer must possess. So in the very early part of my career, I have already made many related attempts. But the result usually ends in failure for a variety of reasons:
- Lack of necessary background knowledge is like reading a bible book
- Do not understand the project structure and design concept, always to no avail
- The target is not focused enough, and the reading process is easy to complicate
- Easy to fall into details and struggle for a long time on unimportant issues
- Easy to chase the branch process, distracting
- Failed to take notes and summarize in time, and failed to crush, reorganize, and internalize knowledge into one's own things
- Have no experience in dealing with particularly complex problems, potentially unconfident
- Insufficient personal perseverance, resilience, or not strong enough sense of purpose, easy to give up when encountering difficulties
- and many more
This list can still be pulled down for a long, long time. In short, there are both my own subjective cognitive limitations and practical and objective reasons. Later, because of the opportunity of work, I read the source code of Vue and mxGraph and found that things were not as difficult as I thought. Later, I read a lot of framework source codes, including Webpack, Webpack-sources, Vite, Eslint, Babel, Vue-cli, Vuex, Uniapp, Lodash, Vetur, Echarts, Emmet, etc., as dull as I slowly figured out some universal methods, and then courageously wrote this article, not dare to say that teaching people how to fish, But at least it should be a start.
So this is an article written for those students who are interested in, preparing, or already reading the source code of the front-end framework. I will throw out some reading skills and principles that I have summed up through my own practice many times, combined with Vetur Source code, specifically explain my thoughts and thoughts in each stage of reading the source code, hoping to inspire readers.
Figure out the goal
Before introducing specific techniques, it is necessary to discuss with readers the motivation of reading the source code, and figure out whether you need to improve your skills in this way. Although learning excellent framework source code does have many self-explanatory benefits, everyone’s Experiences, contexts, demands, and thinking habits are different, and the actual learning effect will inevitably vary greatly from individual or individual at different times. The biggest variable in this is experience, and the goal. Experience varies from person to person. , And it is difficult to make up in a short period of time, there is not much room for discussion; it is worth arguing in terms of goals.
The first level, first figure out why you need to read the source code? There are many possible reasons, such as:
- In order to increase the depth of understanding of the framework and enhance personal ability
- In response to the interview
- In order to solve a difficult bug or performance problem at the moment
- For some reasons, the framework needs to be modified twice
- Anyway, I'm idle and don't know what to learn, try it. . .
- curious
Some of these are very abstract, such as the last "curiosity"; some are very specific, such as "for the second transformation"; and some are between the concrete and the abstract. According to the SMART principle, the more specific and measurable goals are, the easier it is to achieve them. If the reader’s goal is still at a relatively ambiguous and not detailed stage, then the execution process will most likely be overturned. After all, this is a particularly energy-consuming and Patient work.
For this situation, my suggestion is to think about it in a more detailed level. For example, for the last point of "curiosity", you can think about the specific features that make you particularly magical. It is worth spending time and energy to explore in detail. In the context of Vetur, it can be "I want to understand how Vetur's template error prompt and eslint are combined to achieve the error prompt function at the template level", which is very specific and easy to measure.
At the second level, if readers have clear, specific, and measurable goals, they may wish to ask themselves a few questions before starting:
- Do you really need to increase your knowledge of the framework by reading the source code? Are there some lighter, faster iterative learning methods?
- Does the complexity and technical difficulty of your chosen framework match your current capabilities? The best state is that you think you can reach it on tiptoe, too high, not feasible; too low, ROI is not worthwhile.
If after this deliberation, the necessity, feasibility, and relevance are all in line with personal goals, there is no hesitation.
The third layer is to look at the so-called "goals" dialectically-it is not a complete reading of the entire project to be successful. If you can learn new design thinking, tools and methods from some sentences, fragments, and partial modules, or even just It is the naming convention that can be counted as a personal improvement, and it is much more reliable to accumulate less than to promote. Therefore, there is no need to set the goal too high at the beginning. It is best to meet your own needs. If you find that the complexity of the problem domain is constantly expanding and increasing, and you continue to invest a lot of time but there is no obvious result, then It is recommended to decisively give up or request foreign aid, and make a decision after reassessing the goals and feasibility.
In short, this is a problem of anticipatory management. We can refer to the SMART principle more, think from the dimensions of specificity, measurability, feasibility, and relevance, and constantly consider whether we need to do this; how to disassemble the goal and use the goal Reverse the plan and continue to promote personal success.
Reading skills
Understand background knowledge
Knowledge is a understand . Before starting to learn any open source project, it is necessary to spend some time investigating the basic knowledge related to the project, and gradually build a set of your own knowledge system, which includes:
- High-quality reference materials-collect a wave of high-quality learning materials, the collection process can be read through simultaneously
- How the framework works-the so-called portal
- IO-How does the framework interact with the outside world? What kind of operating parameters does it usually accept? What kind of result is output?
- Ecology-A good framework usually has a mature ecosystem behind it, such as Vue. How can framework derivatives make up for the lack of functionality of the framework itself? In what way do they interact with the main frame with what kind of IO? What kind of writing rules do you follow?
- How to breakpoint debugging-this is almost the most effective analysis method, breakpoint debugging can help you understand the role of each line of code in detail.
Note that the goal here is to quickly build an abstraction about this open source project-even an inaccurate knowledge framework, to avoid getting stuck in endless details, just like when reading an article, you can first look at the directory structure Get a rough understanding of the information framework of the article and understand the general content of the article.
For example, when I first started learning Vetur, I only knew that this was a VS Code plug-in, but I didn’t know how to write the plug-in, how to run it, and how to implement language features. So the first thing I did was to read VS Code carefully. Official documentation (fortunately the documentation is very complete, unlike a well-known packaging tool), learn basic knowledge about plug-in development, including:
To further summarize the elements of the VS Code language plug-in:
- How to write the plug-in : through the
contributes
,main
package.json
file, declare the function and entry of the plug-in - how to run : use F5 to start debugging the development phase
- How to write language features : Use lexical highlighting, Language API, Language Server Protocol three types of technology implementation
The amount of knowledge in the field of VS Code is still very large. Learning background knowledge and organizing into this highly structured and highly abstract brain map can give you a higher-level and comprehensive perspective. Ideally, this will be the case when the source code is actually analyzed later. The skeleton context allows you to instinctively map to the knowledge points of a certain aspect, which can get twice the result with half the effort.
Six-step cycle analysis
Next, I will introduce a set of analysis procedures that I often use:
The whole is divided into six steps:
- Understand the project structure
- Find the right entry point
- Access article data at the entry point
- Analyze the code flow at the entry point
- Partial in-depth study
- Timely summary
- After that, continue to set the entry point and repeat the above process until you have a thorough understanding of the problem
This is a set total-points-total perspective and finally builds a complete perspective. The focus is on telling readers at what stage what should be paid attention to, what to ignore, what to input, and what to output. I personally Follow this method to slowly explore the implementation principles of various open source frameworks including Webpack, Babel, Vue, Vetur, and mxGraph.
Understand the project structure
When you first started to read the source code, I believe most people will be very confused and unable to start. This is because the reader lacks a necessary framework knowledge of the project, does not know where the program entry is, what are the key components, and the various folders. What's the role? If you encounter problems, you can't quickly speculate the implementation path.
Therefore, the first step in reading the source code should be to spend some time to analyze and understand the organizational structure of the project. Fortunately, an open source project worthy of in-depth reading and learning usually has strong integrity and consistency. We only need to sort out three clues:
- Analysis project entry
- Analyze which basic tools the project relies on, including compilation tools, such as webpack, Typescript, and babel; basic libraries, such as lodash, tapable, and snabbdom.
- List the important folders and files in the project one by one, and understand how they form an overall structure according to their dependencies.
In the context of vetur, we have learned in the "Understanding Background Knowledge" section above that the VS Code plug-in needs to package.json
file through contributes
and other attributes, so these questions can be package.json
file.
Entry analysis
First of all, we need to identify the entry point of the Vetur application. The role of this step is to help us understand how Vetur contributes new features to VS Code. Analyzing 0614153b39fa05 of package.json
found that there are three configuration items that directly point to the file:
contributes.languages
Specify language configuration filecontributes.grammars
specifies the syntax configuration file"main": "./dist/vueMain.js"
Specify the plug-in execution entry
The three entrances implement three different language features and functions, which are slightly complicated, and it is necessary to expand and understand them separately.
Explore contributes.languages
configuration
Explain one by one, the contributes.languages
configuration information points to the ./languages/***-language-configuration.json
file, such as:
{
// ...
"contributes": {
"languages": [
{
"id": "vue",
"configuration": "./languages/vue-language-configuration.json"
},
{
"id": "vue-html",
"configuration": "./languages/vue-html-language-configuration.json"
}
// ...
]
}
// ...
}
Here is a look back at VS Code [contributes.languages](https://code.visualstudio.com/api/references/contribution-points#contributes.languages)
(thanks to the resource-rich VS Code community):
Contribute definition of a language. This will introduce a new language or enrich the knowledge VS Code has about a language.
contributes.languages
is that the role of the 0614153b39fb1d configuration item is mainly to enhance VS Code's understanding of specific languages. As for how to enhance it? Continue to open the ./languages/vue-language-configuration.json
file in the configuration item:
{
"comments": {
// symbol used for single line comment. Remove this entry if your language does not support line comments
"lineComment": "//",
// symbols used for start and end a block comment. Remove this entry if your language does not support block comments
"blockComment": [
"/*",
"*/"
]
},
// ...
}
The file defines the configuration of language rules such as inline comment, block-level comment, brackets, and folding. The rules are simple and straightforward, and the length of the relationship is not expanded here.
Recall the discovery steps:
contributes.languages
reference materials to understand the role of 0614153b39fb83 configuration- Open the corresponding entry file and guess the role of each configuration item
- Continue to read the reference materials, or modify the configuration, verify the conjecture
Explore contributes.grammars
configuration
contributes.grammars
item contains a lot ./syntaxes/vue-xxx.json
, such as:
{
"contributes": {
"grammars": [
{
"language": "vue",
"scopeName": "source.vue",
"path": "./syntaxes/vue-generated.json",
"embeddedLanguages": {
"text.html.basic": "html",
// ...
}
},
{
"language": "vue-postcss",
"scopeName": "source.css.postcss",
"path": "./syntaxes/vue-postcss.json"
}
// ...
]
}
}
Similarly, let's first check the official website's explanation of the configuration item [contributes.grammars](https://code.visualstudio.com/api/references/contribution-points#contributes.grammars)
Contribute a TextMate grammar to a language. You must provide thelanguage
this grammar applies to, the TextMatescopeName
for the grammar and the file path.
This description is slightly complicated, to the effect that developers can provide a grammatical description of the language in TextMate form grammars
grammars
configuration item contains three attributes:
language
: the name of the languagescopeName
: language classification,scopeName
, can be used for nested grammar definitionpath
: language lexical rules file
Here, the path
attribute points to a more complex configuration file ./syntaxes/vue-xxx.json
. We can then open any of these files. The key content structure is as follows:
{
"name": "Vue HTML",
"scopeName": "text.html.vue-html",
"fileTypes": [],
"uuid": "ca2e4260-5d62-45bf-8cf1-d8b5cc19c8f8",
"patterns": [
// ...
{
"name": "meta.tag.any.html",
"begin": "(<)([A-Z][a-zA-Z0-9:-]*)(?=[^>]*></\\2>)",
"beginCaptures": {
"1": {
"name": "punctuation.definition.tag.begin.html"
},
"2": {
"name": "support.class.component.html"
}
}
}
],
"repository": {
// ...
}
}
According to Highlight Guide Syntax ( https://zjsms.com/e7E5Jdq/ ) a statement there is the most important thing is patterns
property, and patterns
most critical function is to attribute the statement to a regular expression rules of the language lexical analysis, and Assign the lexical corresponding name
naming. For detailed configuration rules, you can continue to refer to the TextMate official website. Here you can understand the function in general, so I won’t go into further details.
Explore main
configuration
Then look down, the third thing worth paying attention to is the main
attribute, the corresponding value in vetur:
"main": "./dist/vueMain.js"
VS Code official website the main
attributes very : 1614153b39fd7b The entry point to your extension , which is the entry point of the plug-in, usually needs to point to the executable JS file, VS Code will execute this entry file export when the plug-in starts activate
method, the content frame is roughly as follows:
import vscode from 'vscode';
export async function activate(context: vscode.ExtensionContext) {
// ... 启动逻辑
}
In Vetur, the activate
function is defined in the client/vueMain.ts
file. Analysis of the source code shows that the function mainly completes the following matters:
- Call the
registerXXXCommands
method to register a series of commands - Call the
initializeLanguageClient
method to initialize the LSP Client object
For the specific functions of these two operations, we will press the button first, and then expand it later.
summary
That's it for the analysis of the entrance. Let's summarize and record the key information first:
- Vetur is essentially a VS Code plug-in, all configurations-including entry points are recorded in the
package.json
file Vetur includes three launch portals:
contributes.languages
: Define some simple basic language configuration, including how to fold and how to commentcontributes.grammars
: Defines a set of lexical rules based on the TextMate engine to implement code highlightingmain
: Defines the startup entry of the plug-in, a series of commands are registered in the entry, and a Language Client object based on the LSP protocol is created at the same time, and the LSP protocol is used to implement advanced features such as code completion, error diagnosis, jump definition, etc.
Up to this point, although we still don't know the implementation details of Vetur, we should have a relatively basic understanding of Vetur's background knowledge and project structure, and we can roughly identify which functions are implemented by which modules.
OK, just keep this vague understanding here, don't spend too much time.
Basic dependency analysis
Next, we need to sort out the basic dependencies of Vetur. The function of this step is to help us understand which basic technologies Vetur may use, such as which engineering tools are used, how to compile, and how to check code.
Vetur’s package.json
file mainly contains three types of information:
- VS Code plug-in configuration information, generally described in the previous section, will not be expanded here
Engineering commands, the core includes:
watch
: The corresponding command isrollup -c rollup.config.js -w
, from which it can be inferred that Vetur is built based on Rollupcompile
: The function is similarwatch
lint
: The corresponding command istslint -c tslint.json **.ts
, from which it can be inferred thattslint
implements code checking based on 0614153b39ffeb
- The
devDependencies
dependencies of the project mainly include typescript, tslint, rollup, vscode-languageclient, husky, mocha, vscode-test, prettier
Then, from this information we can basically infer the following information:
- Vetur uses tools such as Rollup + typescript to perform the build work. According to common sense, executing the
yarn watch
command should be able to start a continuous build process. - Vetur uses tslint to implement code inspection and cooperates with huscky + prettier to complete the formatting work
- Vetur uses mocha + vscode-test to achieve automated testing
File structure
Next, we need to expand a little to look at Vetur's file structure. This step can help us understand Vetur's code structure and elements to a certain extent, and guess where various features are implemented. The file structure of Vetur is roughly as follows:
vetur
├─ .vscode
│ ├─ ...
├─ build
│ ├─ ...
├─ client
│ ├─ client.ts
│ ├─ commands
│ │ ├─ ...
│ ├─ grammar.ts
│ ├─ ...
├─ languages
│ ├─ vue-html-language-configuration.json
│ ├─ ...
├─ scripts
│ ├─ build_grammar.ts
│ └─ tsconfig.json
├─ server
│ ├─ .gitignore
│ ├─ .mocharc.yml
│ ├─ .npmrc
│ ├─ bin
│ │ └─ vls
│ ├─ package.json
│ ├─ rollup.config.js
│ ├─ src
│ │ ├─ ...
├─ syntaxes
│ ├─ markdown-vue.json
│ ├─ pug
│ │ ├─ ...
│ ├─ ...
│ └─ vue.yaml
├─ test
│ ├─ ...
├─ vti
│ ├─ README.md
│ ├─ bin
│ │ └─ vti
│ ├─ package.json
│ ├─ rollup.config.js
│ ├─ src
│ │ ├─ ...
│ ├─ tsconfig.json
│ └─ yarn.lock
├─ tsconfig.options.json
├─ package.json
├─ ...
└─ yarn.lock
Among them, the more critical ones are:
client
: The entry code of the VS Code plug-in. Themain
package.json
file will point to the product of this directoryserver
: Server side in the LSP architecture, the aboveclient
will communicateserver
directory through the LSP protocolsyntaxes
: Vetur’s lexical rules folder, which contains many JSON formats and lexical declarations that comply with TextMate ruleslanguages
: The language configuration information provided by Vetur, the rules are relatively simple, you can understand the role, and you don’t need to go deepvti
: According to thevti/bin/vti
file, it can be inferred that this is the command line tool of Vetur, which can be ignored if it is not in the main processdocs
: According to the content, it can be inferred that this is the introduction document of Vetur, which can be ignored herebuild
: build commands, some of thescript
package.json
file will point to this directory, which can be ignored- A series of basic configuration files, including
tsconfig.json
,package.json
etc., can be ignored first
We can continue to explore the contents of each sub-directory, but just pay attention to it. With the deepening of the source code reading later, the reader's understanding of each directory should continue to iteratively increase, and there is no need to spend too much time now.
summary
Looking back, we first learned some background knowledge, and then spent some time analyzing the entry, basic dependencies, and file structure of the project. Here we can basically infer:
- Vetur is a language plug-in, so it must use lexical highlighting, Language API, Language Server Protocol three types of technologies to realize the core logic, and the content of the
contributes
package.json
file also just verifies this point. - Lexical highlighting related code is concentrated in the
syntaxes
folder - Language Server Protocol related code is concentrated in the
client
andserver
folders - You can use the
yarn watch
command to build continuously, and start debugging with the F5 shortcut key
This information is a necessary condition for the subsequent analysis of the source code, and this process is very similar to learning a new language. Readers can recall that when they first learned JavaScript, experienced learners would not immediately dive into such things as prototypes, variable enhancements, etc. Event loop and other language details, but first learn the basic skeleton of the JavaScript language from a higher-level and more abstract perspective, including functions, loop statements, branch judgment statements, objects, etc., so as to build an abstract structured cognition, and then Fill in the details slowly, with a top-down taste.
Set entry point
After having a basic understanding of the project background and structure, we can formally begin to analyze the source code. First of all, readers need to find an entry point that matches their own state and needs. Essentially, they disassemble the big goal into a series of small goals, and disassemble the big problem into a series of more specific small problems, and then focus on the specific problems. Look at the code.
The so-called entry point can directly target the specific functions of the framework, or the realization of certain underlying mechanisms. Taking Vetur as an example, it implements many features that assist the development of Vue SFC components, including code completion, error diagnosis, and code highlighting. , Jump to definitions, hover prompts, etc. There is a lot of room for digging out of any one of them. If you wander around aimlessly from the beginning, you will definitely not be able to see the reason. In view of my The goal is to learn the development routine of VS Code plug-in through Vetur, so I chose a feature that seems relatively simple: code completion as the first entry point, subsequent learning experience proved that this is a very suitable point, no It's complicated but it can already give me a glimpse of Vetur's core working mechanism, and so on to analyze other advanced features such as code highlighting, code completion, etc., basically it is a very familiar state.
If you have a more specific purpose, such as solving a specific bug, then it should be easier for you to get what you need to do most now; if you still can’t grasp the main points, then it is recommended to go back to the previous "understanding background knowledge" Or the step of "understanding the project structure", continue to explore some contextual information, and then try to ask yourself: What specific function implementation logic should I understand first?
Remember, this is not a one-off sale. If you find that this entry point becomes more and more complicated in the follow-up analysis process, it exceeds the initial expectations, and there is no psychological burden. This is normal, and it is on the side. If you have less and less understanding of the problem domain, you can go back and readjust your goals and find a smaller entry point.
Make good use of search engines
After setting the entry point, the first thing to do is not to open the code and do it, but to search for relevant information in the community. After all, since the media era, many open source frameworks have been thoroughly understood and crushed by countless people. Recomposing articles in various dimensions and following the ideas of these articles to understand the source code will be much more efficient than exploring it on your own.
List several search channels that I often use:
- Search engines like Google and Baidu, Google’s search quality will be much better in physical sense, but there are certain English thresholds
- The official website, community, wiki, github and other official channels of open source projects usually have relatively good information
- Vertical communities such as Segmentfault, Zhihu, Nuggets, and public accounts
- Foreign Medium /StackOverflow community, the quality is very high, many big guys are active on it
If you can’t find the answer after searching, you can try different keyword combinations. The keywords I often use are:
- Xxx source code analysis
- Xxx principle
- How to achieve xxx
If you still can’t find it, you can try another keyword with a similar meaning and make detours. In short, it is to find useful information suitable for the current problem, and help readers to study the source code more quickly and smoothly. This step is especially important for novices.
By the way, I will promote my official account: [Tecvan], long-term focus on the study and analysis of the source code of various front-end frameworks, welcome to subscribe.
Analyze key processes
I talked about Chase before, and finally here we are going to start studying the code seriously.
In fact, the process of source code analysis is particularly like a detective movie. At the beginning, you need to face a bunch of messy clues that seem to be related but not very relevant. The detective needs to find the only factual answer from these thousands of clues. This process usually involves two This is an effective method, one is top-down, summarizing a rough event frame from the perspective of timeline and process, and then further studying the details, from abstract to concrete; the other is bottom-up, finding doubts and then going The upper level scrutinizes layer by layer, sorting out the whole picture of the incident, from the concrete to the abstract.
The two methods have their own applicable scenarios. If you want to understand the implementation principles of certain functional features for learning purposes, you should self-orientate and gradually track down the execution process from the application entrance. After understanding the big framework, Dig into specific details; and if it is to track down a single bug, you should find the problem, trace back the whole picture from the bottom up, and then make changes.
I personally prefer a top-down approach. For example, when I was learning Vetur, I first selected code completion as the entry point, and then server/main.ts
all the way down the main process. Explore step by step, and finally reach the position of actual execution of code completion. Although the actual learning process is not as smooth as it is now said, in the end, such a flowchart is slowly derived:
This flowchart is very important. It basically allows me to understand the two important stages of Vetur:
- During the startup phase, the
vls
type will initialize theprojectService
object, and then listen to various LSP events In the execution phase, when an LSP event is triggered,
vls
will directly delegate the event to theprojectService
object for processing, andprojectService
will do two things:template
region cutting for SFC files, and parse out blocks such as 0614153b3a05e3,script
,style
- For different blocks, call
doComplete
function of themodes/xxx
object to process
Based on this flow chart, logically it can be inferred: all LSP requests will eventually flow to the corresponding **modes**
folder according to the code type, for example:
- For
template
, it will eventually flow to theformat
function of themodes/template/index.ts
- For
style
, the flow goes to the functionmodes/style/index.ts
format
- In the same way, it can be deduced to include advanced features such as code completion, hover prompt, jump to definition, error diagnosis, etc.
This discovery makes the entire Vetur code architecture very flat. When studying specific characteristics later, you can skip the previous pair of LSP request processing and segmentation steps, and directly find the corresponding modes/xxx/index.ts
code.
So, how to analyze the execution flow of the code? There are two methods I personally summarize: static conjecture + dynamic verification , which will be discussed in detail in the next section.
Partially deep
After going through the previous series of steps and reserve enough background knowledge and framework knowledge, we can start to analyze the source code line by line to understand the specific role and implementation of each line, each variable, each function, and each module. Next, I will introduce two effective methodologies:
- static conjecture : "read" the source code, understand the code logic from the surface and make a conjecture
- Dynamic verification : "Run" the source code, use the debug tool to track the code execution process line by line, and modify the original code if necessary to verify the guess
These two methods are not very clear. They usually make speculations while looking at the code. If there are doubts, run them immediately to verify whether the speculation is correct, and the effect is better if they are used flexibly together.
Static analysis-make guesses
The so-called static analysis, to put it bluntly, is to analyze the code line by line and study the role of each variable and each process. It is a hard work that requires basic knowledge and information retrieval capabilities. Although the implementation details of each framework are different, there are still some general techniques that can be discussed:
At the function level, focus on input, output and side effects:
- What structure parameters the function accepts, what changes will happen to these parameters after each statement in the function, or how to affect the execution of the statement
- After the function is executed, what structure results will be returned, who will consume these results in the next step, and whose execution logic will be affected
- In particular, there are many library function implementations that have obvious "side effects", which are not so "pure", including Webpack, Vetur, Eslint, etc.-this will dramatically increase the cost of understanding, so be careful when reading
- In the branch statement, give priority to the main process. The branch process can easily increase the mental burden. Later, you will not recognize who is who.
- For loop statements, you can usually pay attention to the state before and after the loop, and infer the role of the loop through these changes
- For variables and sub-functions, infer the role according to the naming, usually you don’t need to go into too much detail
- Skip the branch logic such as parameter verification and error handling, and grasp the main process! Grasp the point!
- Remember the entry point you want to study. When encountering a particularly complex sub-module, first understand the function in general, click until it is finished, write down this hard bone and go back and use it as a new entry point to continue research
- Learn some commonly used design patterns such as factories, decorators, agents, etc. The usage rate of these patterns is very high
Combining these techniques, readers should still encounter many speculations and questions in the analysis process: what does this function do; this statement is too complicated to understand; there are too many side effects in this loop, and it is impossible to focus on it. It is a good thing to have a problem. It proves that you can start to see the clues. At this time, you need to run the framework, and gradually and dynamically observe the flow of the code to verify your guesses or problems.
Dynamic analysis-verify conjecture
After reading the code statically, I believe that the reader already has some basic inferences and questions about the code logic. Next, you need to run the framework, add breakpoints wherever there are questions, and observe the execution stack, parameter changes, environmental changes, and logic branches. Statement to determine how the input parameters are determined, and who will consume the output results.
However, it may not be easy to modify and run an open source framework. Generally, three points need to be paid attention to:
- If the framework has been connected to some engineering tools, you need to figure out how to compile the source code into a running product. For example, if the Vetur project is connected to tsc + rollup, the corresponding command is
yarn watch/compile
- How to start the debugging mode, for example, in the Vetur scenario, you need to borrow the
.vscode/launch.json
configuration file of VS Code + F5 command to start debugging; and for front-end frameworks such as Vue and React, you usually open the DevTool panel of the browser - How to insert debugging statement, usually add
debugger;
statement in front-end or Node scenario
If you can’t run a piece of code, then you won’t be able to master it, so I will specifically emphasize the need to understand the entry, startup, and debugging methods of the project in the previous section "1614153b3a0a4e understand background knowledge Debugging skills, then this code is equivalent to taking off all the exteriors in front of you, and you can observe the dynamic flow of the code logic line by line and sentence by sentence.
Timely summary
A good memory is never as good as a bad pen. I have spent so much time exploring and verifying. If you do not take notes in time, then this will most likely be useless; and if you do not summarize in time, there is a high probability that the information will not be internalized. The knowledge in your head!
Of course, there is no need to take this matter too hard. The purpose of the summary is to abstract the fragmented information that has been mastered, and remove some details, and then integrate and sort into systematic knowledge, with the emphasis on internalizing it into your own knowledge. Rather than a specific form! So don’t pay attention to perfection, don’t worry about writing the sentences more beautifully, making the pictures look better, and how to come quickly while ensuring the basic logic is smooth.
My personal habit is to open a single visible Feishu document for a topic, and keep taking notes during the reading process-they are all vernacular without any modification. Once I feel that I reach a node, I will immediately make a summary and change the code The process is classified into N steps-try to control within 10, write clear logic and output for each step, and draw some rough flowcharts, timing diagrams, state machines, etc. if conditions permit. Finally, after saving to a certain level, I will go a step further and output external articles or PPT as an acceptance of my own learning results.
The next entry point
Nothing known to humans or products created by humans is absolutely simple. Excellent open source projects are usually very complex combinations. If you just stay at "how to achieve a specific function", you are far from grasping The essence, you still need to continue to explore and analyze its "how to realize and combine multiple single functions"-but not the "multiple" that are independent and independent, but the "multiple" that merge into an organic whole.
So after understanding a certain aspect, we can continue to use the above analysis steps to loop through the next entry point, which can be a complicated problem you left behind, or a new functional feature, follow these fragments and gradually sort out Into a set of more systematic cognition.
Putting it in the context of Vetur, after the first analysis, I basically mastered Vetur's architecture, core process, and code completion , and learned that " all LSP requests will eventually flow according to the type of code. To the corresponding **modes**
folder on the " basic rule. Next, I want to continue to explore the implementation principles of other features, including error diagnosis, jump definitions, intelligent prompts, etc., so I reset the entry point, re-run search, process analysis, partial in-depth, looping and finally summing up a series knowledge, organized into summary online sharing: " how to develop a plug-VS Code language - for example to Vetur ", life for the first time live.
Best Practices
Let’s talk about the best practices that I personally recognize:
- Set specific and measurable goals. Don’t learn for the sake of learning. If you have a real strong demand, don’t hesitate and do it right away.
- Don’t sharpen your knife and chop wood by mistake. Don’t go up to the source code and output crazy. Be sure to take a moment to look at the background and ecology of the framework from a high-level perspective.
- Grasp the big and let go of the small, ignoring the concepts, sentences, tools, and branching logic that are not yet familiar. You have to realize that the learning model of complex things tends to spiral upward and gradually deepens. It is impossible to master all the details and essence in one pass. Too much attention to detail from the beginning will usually drag the entire learning cycle to infinite length. To figure out when and when to ignore the details, and when to grasp it-this has a lot to do with your goal and entry point
- Take notes at any time: Once there are any new discoveries, new problems, make notes and record them, these will become important clues for continued exploration
Summarize at any time:
- The notes record the current and fragmentary discoveries, and the summary connects these clues to form knowledge points.
- In the process of summarizing, you will find more cognitive loopholes, ask more questions, and you can continue to dig in turn
- A good memory is not as good as a bad pen. The results of the exploration will only become your own things when they fall on paper. At the extreme, the learning process without output will often become futile over time.
Learning is a very personal thing after all. The methods, techniques, and principles mentioned above are particularly useful to me, but the actual effect is inevitably different from person to person. If the reader feels particularly uncomfortable during the implementation process, then it can be fine-tuned appropriately. , Slowly figure out the method that suits you more slowly.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。