• Author: Chen Da Yu Tou
  • Making: KRISACHAN

preface

Recently there are a lot of children shoes with fish head said, interview time always ask source code.

There are also a lot of children encountered problems, fish head suggested these children to see the relevant library/framework/project source.

But there are also a lot of children complained to fish head: “the source code is too difficult.”

So is the source really a hard bone to chew?

It’s not.

As a good (or qualified) open source project, the code is certainly not arcane. Not only the code itself, but the project’s accompanying comments, unit tests, sample code, function names, and documentation will certainly help you read the source code.

Let fish head to talk to you about some of my own look at the source code.

(Note: This is not a best practice, it’s just a personal experience and may not apply to everyone. If you have a different opinion, feel free to leave it in the comments section below.)

The body of the

Look at the instructions

Before looking at the source code of an open source project, fishhead will first look at its documentation, not necessarily the detailed API, but will first understand the background of the project, the idea, and the problem to be solved.

For example, let’s take a look at an open source library called Runtime-hooks. Here’s the code:

function withHookAfter (originalFn, hookFn) {
  return function () {
    var output = originalFn.apply(this.arguments)
    hookFn.apply(this.arguments)
    return output
  }
}
Copy the code

This section of the function we understand, is to hijack the original function, and after the original function is executed, the implementation of our own logic. But without relevant business experience, we don’t necessarily understand why we’re doing this, and it’s easy to forget.

But take a look at this excerpt from the author’s description of the library in the documentation:

Given a function that is widely used by the business, can we inject a piece of our own custom logic before and after its execution without changing either the business code that calls it or the function’s source code?

(Source: Practice of front-end code piling based on Prototype chain hijacking)

Oh, so we understand that this way, when we need to hack into a function, we don’t need to do complicated hacks.

Then we understand the meaning of the existence of this function, because of understanding, so this code, naturally remember, in the future encounter similar needs of the scene can easily phase this scheme.

Look at the type file

Since many open source projects are written in TypeScript, there is usually a.d.ts file in the root directory that defines API types.

For example, let’s take a look at ace.js, an open source Web IDE library

Take a look at some of the code in its root directory, ace.d.ts:

export interface EventEmitter {
    once(name: string, callback: Function) :void;
    setDefaultHandler(name: string, callback: Function) :void;
    removeDefaultHandler(name: string, callback: Function) :void;
    on(name: string, callback: Function, capturing? :boolean) :void;
    addEventListener(name: string, callback: Function, capturing? :boolean) :void;
    off(name: string, callback: Function) :void;
    removeListener(name: string, callback: Function) :void;
    removeEventListener(name: string, callback: Function) :void;
}
Copy the code

Using the type annotations above, we can easily see how each API is used.

Sometimes the problem to be solved is just a familiar problem with the API, but some open source projects are not written properly. This is the case above. So sometimes in order to understand an API, I don’t want to spend too much time to find the specific source location. You can open the type file to see how the API works.

See the comments

When we dive into a particular function or file, it’s much easier to understand the code if we know what it does first.

For example, let’s look at Redux.

At the beginning of redux/ SRC/createstore.js there is a comment like this:

Creates a Redux store that holds the state tree. The only way to change the data in the store is to call dispatch() on it.

Create a Redux repository that holds the state tree. The only way to change data in the warehouse is to call Dispatch () on it.

Oh, so from the above comment, we know that the dispatch method is used to schedule data. And it’s the only way to change the data.

The interesting thing is that of the approximately 300 lines of code in this file, an estimated 100 lines are comments, so when we look at the comments, it’s easy to see what it does without looking at the implementation.

When we look at the implementation again, we look at it with the idea that it primarily does this, and the realization becomes easier to understand.

Look at the test sample

In addition to the above methods, we can also look at the test sample. In fact, the test sample is very efficient for us to understand the source code, or quickly get started with an unfamiliar project.

For example we see vuex vuex/test/unit/store. Spec. An example in js:

describe('Store', () => {
  it('committing mutations', () = > {const store = new Vuex.Store({
      state: {
        a: 1
      },
      mutations: {
        [TEST] (state, n) {
          state.a += n
        }
      }
    })
    store.commit(TEST, 2)
    expect(store.state.a).toBe(3)
  })
  it('dispatching actions, with returned Promise', done => {
    const store = new Vuex.Store({
      state: {
        a: 1
      },
      mutations: {
        [TEST] (state, n) {
          state.a += n
        }
      },
      actions: {
        [TEST] ({ commit }, n) {
          return new Promise(resolve= > {
            setTimeout((a)= > {
              commit(TEST, n)
              resolve()
            }, 0)
          })
        }
      }
    })
    expect(store.state.a).toBe(1)
    store.dispatch(TEST, 2).then((a)= > {
      expect(store.state.a).toBe(3)
      done()
    })
  })
})
Copy the code

Even for children’s shoes that do not understand VUex, it is easy to understand that mutations are synchronous and actions are asynchronous through the above two examples. Even with these two examples, we can easily get started with Vuex.

Look at official examples

There is official example, spicy fish head actually found a lot of children’s shoes, is learning a library/framework, does not like to see the official example, instead of like watching all kinds of online tutorials, although the tutorial is not bad, but if the library/framework itself has the official example, then go to secondhand knowledge, have bit of putting the cart before the horse.

For example, we see a webpack webpack/examples/typescript

const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");

module.exports = (env = "development") = > ({
	mode: env,
	entry: {
		output: "./index.ts"
	},
	module: {
		rules: [{test: /\.tsx? $/.loader: "ts-loader".options: {
					transpileOnly: true}}},resolve: {
		extensions: [".ts".".js".".json"]},plugins: [new ForkTsCheckerWebpackPlugin({ async: env === "production"]}}));Copy the code

That’s it. Here’s a typescript configuration that CV directly, so you don’t have to go online and find tutorials that add personal interpretations to confuse you.

conclusion

The above is the fish head daily look at the source code will be concerned about some points.

Of course, this is just some experience of fish head summary, not necessarily applicable to everyone.

And the fish head level is limited, also cannot guarantee 100% error-free.

If you have any different opinions or your own experiences, please feel free to leave them in the comments section below.

Afterword.

If you like to discuss technology, or have any comments or suggestions on this article, you are welcome to add yu Tou wechat friends to discuss. Of course, Yu Tou also hopes to talk about life, hobbies and things with you. You can also scan your wechat account to subscribe to more exciting content. Public account window reply “front-end information”, you can get about 200M front-end interview information, do not miss it.