Writing in the front

Recently in the vue2 source code, found very before never pay attention to the knowledge point, found that vue2 source code does have a lot of places to explore, here began to do a serial, the follow-up will also add vue3 source content. The difference between run-time only and Run-time compiler in VUe2

1. First of all, look at the problems encountered in the source code

When I start reading the source code, I always go directly to the import file and then go directly to the import file. Let’s look at the import file in the vue source code. The corresponding entry file for vue is vue.runtime.common.js

"main": "dist/vue.runtime.common.js",
"module": "dist/vue.runtime.esm.js",
Copy the code

Vue.common.js’ vue.esm.js’ ‘vue.runtime.js… So I feel that this means that VUE has multiple packaged resources that can be brought in. But when are these various VUE files used? With this question in mind, I went to the vue source package file scripts/build.js and found that the package is based on rollup. The configuration can be found in scripts/config.js

web-runtime-cjs-dev': {
    entry: resolve('web/entry-runtime.js'),   
    dest: resolve('dist/vue.runtime.common.dev.js'),
    format: 'cjs',
    env: 'development',
    banner
},
'web-runtime-cjs-prod': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.prod.js'),
    format: 'cjs',
    env: 'production',
    banner
},
...
Copy the code

I also found a list of different vuejs usage scenarios on the Internet

Umd ‘ ‘commonJS’ ‘esModule refers to the corresponding module exported by the JS file. Also, full stands for Runtimeoly, so the question arises, when should I use Runtimeoly and when should I use runtimeoly?

2. Usage scenarios of the two modes

In previous versions of VUe2, when we created a VUE project based on vuE-CLI, we could choose to use a Runtimeonly or run-time Compiler for the created project

However, when vue2 or even VUe3 is created in vuE-CLI, the default mode is runtimeOnly

We can see this from the main field in node_modules/vue/package.json in the created project

The main field represents the specific reference JS path when the package is referenced

"main": "dist/vue.runtime.common.js",

As we know, vue needs to go through the entire template rendering process

Template => ast => Render function => Virtual dom => Patch => DOMCopy the code

In runtimeOnly mode only render => vDOM => patch => DOM in the final render phase

The difference between runtimeOnly and runtimeOnly is compiled at runtime; Run-time compiler is required to compile at runtime

2.1 runtimeonly

The RuntimeOnly pattern needs to be implemented in conjunction with external WebPack

Webpack compiles all.vue ending files into render functions based on the vue-loader implementation, so no recompilation is required at run time, no compiler is required, this version does not come with a compiler, so the files are smaller and the execution is faster, which is the default

Corresponding to main.js (default)

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
Copy the code

2.2 runtime – the compiler

Run-time compiler is used because if the template attribute is present, the run-time compiler version needs to be compiled at runtime, and the run-time compiler version comes with the compiler, so it should be used in this case

In main.js:

import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
    components: {App},
    template: '<App/>'
}).$mount('#app')
Copy the code

In this case, vue.js files are larger and have a performance impact because they need to be compiled at run time

2.3 the source

What is the difference between the two modes in the source code?

Run-time Compiler has more of this code than RuntimeOnly

if (! Options. render) {if (template) {const {render, staticRenderFns } = compileToFunctions(template, { outputSourceRange: process.env.NODE_ENV ! == 'production', shouldDecodeNewlines, shouldDecodeNewlinesForHref, delimiters: options.delimiters, comments: options.comments }, this) options.render = render options.staticRenderFns = staticRenderFns }Copy the code

It can be seen that run-time compiler mode is used when there is no render and the template attribute is available

3. How to change the mode

If the problem is caused by a schema problem, an error is usually reported

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

All Vues now default to RuntimeOnly, so how do you switch between the two modes?

There are three ways

3.1 Directly change the introduction of vue files in main.js

Import Vue from ‘Vue’ : import Vue from ‘Vue /dist/vue.esm.js

3.2 Changing the WebPack configuration

Add the following configuration to vue.config.js

    module.exports = {
        configureWebpack: config => {
            config.resolve = {
                alias: {
                    'vue$': 'vue/dist/vue.js'
                }
            }
        },
    };
Copy the code

3.3 Change the writing method in main.js to a matching one. See above for the specific writing method