real.js
function Real(options) {
    options = options || {}
    var optimiseOpt = options.optimise || {}
    var precompile = optimiseOpt.precompile
    var compileCache = optimiseOpt.compileCache

    var vm = this
    var NS = conf.namespace
    var _ready = options.ready
    var _created = options.created
    var _destroy = options.destroy
    var _binding
    if (compileCache) {
        _binding = compileCache.hasBinding
    } else {
        _binding = util.hasOwn(options, 'binding') ? options.binding : true
        if (precompile) {
            precompile.hasBinding = _binding
        }
    }
    var _message
    if (!optimiseOpt.noMessage) {
        _message = this._message = new Message()
    }

    this.$id = _cid ++
    this.$name = options.name || ''
    this.$parent = options.parent || null
    this.$binding = !!_binding
    this.$shouldUpdate = options.shouldUpdate
    this.$directives = []
    this.$components = []
    this.$watchers = []
    this._$beforeDestroy = function () {
        _safelyCall(conf[CATCH_KEY], _destroy, vm)
    }


    var el = options.el
    var hasReplaceOption = util.hasOwn(options, 'replace') 
            ? options.replace
            : false
    /**
     *  Mounted element detect
     *  Convert selector to element
     */
    if (util.type(el) == 'string') {
        var sel = el
        if (supportQuerySelector) {
            el = document.querySelector(sel)
        } else if (/^\./.test(sel)) {
            el = _getElementsByClassName(sel.replace(/^\./, ''))
            el && (el = el[0])
        } else if (/^#/.test(sel)) {
            el = document.getElementById(sel.replace(/^#/, ''))
        } else {
            el = null
        }

        if (!el) return consoler.error('Can\'t resolve element by "' + sel + '"')
    }
    
    /**
     * Container element must be a element or has template option
     */
    var isHTMLElement = is.Element(el)
    var children
    if (isHTMLElement && options.template) {
        /**
         * If el is passed and has template option
         * if without "replace", it will render template to innerHTML,
         * otherwise template rendering to innerHTML and replace the component element with
         * root element of template.
         */
        if (util.hasAttribute(el, NS + 'notemplate') || options.notemplate) {
            // skip render template, using with SSR
        } else if (hasReplaceOption) {
            var child = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            children = _fragmentChildren(child)
            if (!children.length) 
                throw new Error('Component with \'replace\' must has a child element of template.', options.template)
            var nextEl = children[0]
            var parent = el.parentNode
            if (parent) {
                parent.replaceChild(nextEl, el)
            }
            _cloneAttributes(el, nextEl)
            el = nextEl
        } else {
            // el is given then set template as innerHTML for the component
            if (is.Fragment(el)){
                consoler.warn('Container element should\'nt a fragment node when "template" is given. Template:\n', options.template)
            } else {
                el.innerHTML = options.template
            }
        }
    } else if (!el && options.template) {
        if (hasReplaceOption) {
            var frag = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            el = _fragmentChildren(frag)[0]
            if (!el) 
                consoler.warn('Component\'s template should has a child element when using \'replace\' option.', options.template)
        }
        if (!el) {
            el = document.createElement('div')
            el.innerHTML = options.template
        }
    } else if (isHTMLElement) {
        if (hasReplaceOption) {
            children = is.Fragment(el) ? _fragmentChildren(el) : el.children
            var hasChildren = children && children.length
            !hasChildren && consoler.warn('Component\'s container element should has children when "replace" option given.')
            if (hasChildren) {
                var oldel = el
                el = children[0]
                if(oldel.parentNode) 
                    oldel.parentNode.replaceChild(el, oldel)
            }
        }
    } else {
        throw new Error('illegal "el" option.')
    }
    var componentDec = NS + 'component'
    var isReplaced
    var hasChildCompoent
    if (hasReplaceOption 
        && util.hasAttribute(el, componentDec) 
        && _getAttribute(el, componentDec) !== options.name) {
        // not same name policy, and make parentVM anonymous
        isReplaced = true
    } else {
        var cname = _getAttribute(el, componentDec)
        if (cname && cname === this.$name) {
            // prevent instance circularly
            _removeAttribute(el, componentDec)
        } else if (cname) {
            hasChildCompoent = true
        }
        // support multiple cid
        var cidKey = '_' + NS + 'cid'
        var cidValue = _getAttribute(el, cidKey) || ''
        if (cidValue) {
            cidValue += ','+this.$id
        } else {
            cidValue = this.$id
        }
        // expose cid to DOM for debug
        // _setAttribute(el, cidKey, cidValue)
    }

    this.$methods = {}
    this.$refs = {}
    
    // from options.data
    var data = _getData(options.data)
    // prop NS-props
    var props = hasChildCompoent ? null : this._$parseProps(el)
    // from DOM interface
    var _data = _getData(options._data)
    this.$data = util.extend(data, props, _data) 

    if (optimiseOpt.bindMethods === false) {
        this.$methods = options.methods
    } else {
        util.objEach(options.methods, function (key, m) {
            vm.$methods[key] = vm[key] = util.bind(m, vm)
        })
    }
    // created lifecycle
    _safelyCall(conf[CATCH_KEY], _created, vm)
    this.$el = el
    // binding watcher
    try {
        util.objEach(options.watch || {}, function (expr, handler) {
            vm.$watchers.push(new Watcher(vm, expr, handler))
        })
    } catch(e) {
        consoler.error('Watch catch error:', e)
    }
    try {
        var $compiledEl = this.$compile(el, null, precompile, compileCache)
        isReplaced && (this.$el = $compiledEl)
    } finally {

        // ready lifecycle
        try {
            _safelyCall(conf[CATCH_KEY], _ready, vm)
        } finally {
            _message && _message.emit('ready')
        }
    }
}
function Real(options) {
    options = options || {}
    var optimiseOpt = options.optimise || {}
    var precompile = optimiseOpt.precompile
    var compileCache = optimiseOpt.compileCache

    var vm = this
    var NS = conf.namespace
    var _ready = options.ready
    var _created = options.created
    var _destroy = options.destroy
    var _binding
    if (compileCache) {
        _binding = compileCache.hasBinding
    } else {
        _binding = util.hasOwn(options, 'binding') ? options.binding : true
        if (precompile) {
            precompile.hasBinding = _binding
        }
    }
    var _message
    if (!optimiseOpt.noMessage) {
        _message = this._message = new Message()
    }

    this.$id = _cid ++
    this.$name = options.name || ''
    this.$parent = options.parent || null
    this.$binding = !!_binding
    this.$shouldUpdate = options.shouldUpdate
    this.$directives = []
    this.$components = []
    this.$watchers = []
    this._$beforeDestroy = function () {
        _safelyCall(conf[CATCH_KEY], _destroy, vm)
    }


    var el = options.el
    var hasReplaceOption = util.hasOwn(options, 'replace') 
            ? options.replace
            : false
    /**
     *  Mounted element detect
     *  Convert selector to element
     */
    if (util.type(el) == 'string') {
        var sel = el
        if (supportQuerySelector) {
            el = document.querySelector(sel)
        } else if (/^\./.test(sel)) {
            el = _getElementsByClassName(sel.replace(/^\./, ''))
            el && (el = el[0])
        } else if (/^#/.test(sel)) {
            el = document.getElementById(sel.replace(/^#/, ''))
        } else {
            el = null
        }

        if (!el) return consoler.error('Can\'t resolve element by "' + sel + '"')
    }
    
    /**
     * Container element must be a element or has template option
     */
    var isHTMLElement = is.Element(el)
    var children
    if (isHTMLElement && options.template) {
        /**
         * If el is passed and has template option
         * if without "replace", it will render template to innerHTML,
         * otherwise template rendering to innerHTML and replace the component element with
         * root element of template.
         */
        if (util.hasAttribute(el, NS + 'notemplate') || options.notemplate) {
            // skip render template, using with SSR
        } else if (hasReplaceOption) {
            var child = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            children = _fragmentChildren(child)
            if (!children.length) 
                throw new Error('Component with \'replace\' must has a child element of template.', options.template)
            var nextEl = children[0]
            var parent = el.parentNode
            if (parent) {
                parent.replaceChild(nextEl, el)
            }
            _cloneAttributes(el, nextEl)
            el = nextEl
        } else {
            // el is given then set template as innerHTML for the component
            if (is.Fragment(el)){
                consoler.warn('Container element should\'nt a fragment node when "template" is given. Template:\n', options.template)
            } else {
                el.innerHTML = options.template
            }
        }
    } else if (!el && options.template) {
        if (hasReplaceOption) {
            var frag = _fragmentWrap(options.template)
            // for get first Element of the template as root element of the component
            el = _fragmentChildren(frag)[0]
            if (!el) 
                consoler.warn('Component\'s template should has a child element when using \'replace\' option.', options.template)
        }
        if (!el) {
            el = document.createElement('div')
            el.innerHTML = options.template
        }
    } else if (isHTMLElement) {
        if (hasReplaceOption) {
            children = is.Fragment(el) ? _fragmentChildren(el) : el.children
            var hasChildren = children && children.length
            !hasChildren && consoler.warn('Component\'s container element should has children when "replace" option given.')
            if (hasChildren) {
                var oldel = el
                el = children[0]
                if(oldel.parentNode) 
                    oldel.parentNode.replaceChild(el, oldel)
            }
        }
    } else {
        throw new Error('illegal "el" option.')
    }
    var componentDec = NS + 'component'
    var isReplaced
    var hasChildCompoent
    if (hasReplaceOption 
        && util.hasAttribute(el, componentDec) 
        && _getAttribute(el, componentDec) !== options.name) {
        // not same name policy, and make parentVM anonymous
        isReplaced = true
    } else {
        var cname = _getAttribute(el, componentDec)
        if (cname && cname === this.$name) {
            // prevent instance circularly
            _removeAttribute(el, componentDec)
        } else if (cname) {
            hasChildCompoent = true
        }
        // support multiple cid
        var cidKey = '_' + NS + 'cid'
        var cidValue = _getAttribute(el, cidKey) || ''
        if (cidValue) {
            cidValue += ','+this.$id
        } else {
            cidValue = this.$id
        }
        // expose cid to DOM for debug
        // _setAttribute(el, cidKey, cidValue)
    }

    this.$methods = {}
    this.$refs = {}
    
    // from options.data
    var data = _getData(options.data)
    // prop NS-props
    var props = hasChildCompoent ? null : this._$parseProps(el)
    // from DOM interface
    var _data = _getData(options._data)
    this.$data = util.extend(data, props, _data) 

    if (optimiseOpt.bindMethods === false) {
        this.$methods = options.methods
    } else {
        util.objEach(options.methods, function (key, m) {
            vm.$methods[key] = vm[key] = util.bind(m, vm)
        })
    }
    // created lifecycle
    _safelyCall(conf[CATCH_KEY], _created, vm)
    this.$el = el
    // binding watcher
    try {
        util.objEach(options.watch || {}, function (expr, handler) {
            vm.$watchers.push(new Watcher(vm, expr, handler))
        })
    } catch(e) {
        consoler.error('Watch catch error:', e)
    }
    try {
        var $compiledEl = this.$compile(el, null, precompile, compileCache)
        isReplaced && (this.$el = $compiledEl)
    } finally {

        // ready lifecycle
        try {
            _safelyCall(conf[CATCH_KEY], _ready, vm)
        } finally {
            _message && _message.emit('ready')
        }
    }
}
Constructor Function and Class.
@param {Object} options Instance options
@return {Object} Real component instance