Reading Vue Source Code - The First Note

Since long, I have had the idea to implement my own frontend utility library to relieve myself from repeated boring stuffs. However, I know I was still not knowledgeable enough to make a move those times. And now, there have been quite a few frontend libraries which fully implement what I once wannted. Among them, React, Angular and Vue stand out. Personally, I think React and Angular are just too good and powerful to learn and Vue could be one really suitable source for learning since it is in fact at the beginning developed by one developer, Evan You. Yeah, kind of like holding the idea, better to learn something easy at first in oder not to get oneself overwhelmed and discouraged.

Coming back to the topic, I finnaly decided to start learning from Vue starting from today. And this would be the first Reading note in the series.

The Development Environment for Vue 0.0.1 - the first git commit of Vue

As early as on 27 Jul 2013, when Vue got the first commit, Vue was called Element as indicated by the package.json in the first commit.

.
├── Gruntfile.js
├── component.json
├── package.json
├── src
│   └── main.js
└── test
    ├── test.html
    └── test.js

From package.json, I can get that, dependencies for Vue at that time was grunt, grunt-component-build, grunt-contrib-watch, grunt-contrib-jshint, grunt-mocha and chai. It would be good to have a look at those dependencies at first.

From component.json, I can get that, the src/main.js is the entry for the whole Node project Vue (which of course compile to JavaScript library for the usage mainly in frontend browser environment) and component/emitter is adopted for event emitting. And the .jshintrc gives some clue about the code style of the Node project Vue.

As the first commit of Vue, the src/main.js in fact does nothing rather than export a constant number 123, that also means this first commit is just one abstracted skeleton or scaffold. Although abstracted, the test part was still included as in the test subfolder, inside which there are two files as test/test.js and test/test.html which is managed by the config in Gruntfile.js under module mocha.

And from the contents of test/test.html and test/test.js, I can get or verify that, mocha and chai (basically for the usage of var assert = chai.assert) are indeed dependencies for testing, the name of Vue at that time was really element and "PhantomJS" may also be intentionally adopted since there is if (navigator.userAgent.indexOf('PhantomJS') < 0) {mocha.run();} inside test/test.html.

That is probably everything I can get from the first git commit of Vue. So it is time to checkout to the following commits, which contains the first implementation of Vue.

The Initial Design of Vue

The second git commit of Vue doesn't official releases the initial implementation of Vue, but just gives a clue that Vue was once considered to be named as Seed as indicated by Gruntfile.js, test/test.html and test/test.js. But this commit does contain the initial design of Vue, as given by the subfolder explorations which is not sensed by Grunt. By the way, the explorations design is much like a beta version of implementation if we regard the src being the released version.

The explorations contains two files that are getset.html and getset-revits-style.html. After checking the contents of both files, I find, there is in fact no differences there although as two files under different names.

And the magic of the intial version of Vue, in fact happens in just one function, that is as following.

function bind (variable) {
    bindings[variable].els = el.querySelectorAll('[' + bindingMark + '="' + variable + '"]')
    ;[].forEach.call(bindings[variable].els, function (e) {
        e.removeAttribute(bindingMark)
    })
    Object.defineProperty(data, variable, {
        set: function (newVal) {
            [].forEach.call(bindings[variable].els, function (e) {
                bindings[variable].value = e.textContent = newVal
            })
        },
        get: function () {
            return bindings[variable].value
        }
    })
}

And the most essential part from my opinion is the Object.defineProperty() which utilises the power of JavaScript via defining the setter method of data and taking bindings[variable] as enclosure.

And this is pretty much for today. To be continued with the 3rd git commit which contains much more and also including the TODO file.


* cached version, generated at 2020-05-06 12:44:10 UTC.

Subscribe by RSS