美文网首页vue源码分析
Vue --- Runtime + Compiler vs. R

Vue --- Runtime + Compiler vs. R

作者: Wendy81 | 来源:发表于2020-11-02 19:05 被阅读0次

    学习目标:
    一、理解Runtime + Compiler vs. Runtime-only
    二、如何设置Runtime + Compiler 和Runtime-only环境
    三、理解源码实现原理

    理解Runtime + Compiler vs. Runtime-only

    一、如果你需要在客户端编译模板 (比如传入一个字符串给 template 选项,或挂载到一个元素上并以其 DOM 内部的 HTML 作为模板),就将需要加上编译器

    // 需要编译器
    new Vue({
      template: '<div>{{ hi }}</div>'
    })
    

    二、vue-loader 或 vueify 的时候,*.vue 文件内部的模板会在构建时预编译成 JavaScript,则不需要编译器

    // 不需要编译器
    new Vue({
      render (h) {
        return h('div', this.hi)
      }
    })
    

    环境设置

    环境默认是 Runtime-only,vue指向的是'vue/dist/vue.runtime.esm.js'
    如果想要用有编译器的模式的话,操作如下:
    1.在根目录下增加一个vue.config.js
    2.vue.config.js的内容是:

    module.exports = {
        runtimeCompiler:true
    }
    

    问题(理解源码实现原理)

    1.vue.config.js 为什么是这个文件名?
    2.runtimeCompiler:true这个开关属性是如何控制用编译器文件的?


    image.png

    问题1:vue.config.js 为什么是这个文件名?

    查看Service.js文件:
    . 这里的loadUserOptions函数就是用来处理vue.config.js的对象属性的
    . 可以看到这个文件中用到vue.config.js或vue.config.cjs这个名字

      loadUserOptions () {
        // vue.config.c?js
        let fileConfig, pkgConfig, resolved, resolvedFrom
        const esm = this.pkg.type && this.pkg.type === 'module'
    
        const possibleConfigPaths = [
          process.env.VUE_CLI_SERVICE_CONFIG_PATH,
          './vue.config.js',
          './vue.config.cjs'
        ]
        let fileConfigPath
        for (const p of possibleConfigPaths) {
          const resolvedPath = p && path.resolve(this.context, p)
          if (resolvedPath && fs.existsSync(resolvedPath)) {
            fileConfigPath = resolvedPath
            break
          }
        }
    ......
    return resolved
    }
    

    上面的return resolved的最后结果显示为:

    {runtimeCompiler:true}
    

    问题2.runtimeCompiler:true这个开关属性是如何控制用编译器文件的?

    打开文件base.js

          webpackConfig.resolve
            .alias
              .set(
                'vue$',
                options.runtimeCompiler
                  ? 'vue/dist/vue.esm.js'
                  : 'vue/dist/vue.runtime.esm.js'
              )
    

    上面代码可以看到options.runtimeCompiler如果为true,则用到的是有编辑器的文件'vue/dist/vue.esm.js',否则用到的是runtime即'vue/dist/vue.runtime.esm.js'

    问题

    现在问题是如何确定options.runtimeCompiler中的options对象中的runtimeCompiler就是vue.config.js文件中的runtimeCompiler
    1.查看Service.js

      init (mode = process.env.VUE_CLI_MODE) {
        ......
        // load user config
        const userOptions = this.loadUserOptions()
    
        this.projectOptions = defaultsDeep(userOptions, defaults())
        ......
    
        // apply plugins.
        this.plugins.forEach(({ id, apply }) => {
          if (this.pluginsToSkip.has(id)) return
          apply(new PluginAPI(id, this), this.projectOptions)
        })
      }
    

    上面代码我们知道loadUserOptions函数最后返回的就是vue.config.js中的对象

    const { defaults, validate } = require('./options')
    

    defaults得到的是./options中的返回对象值

    this.projectOptions = defaultsDeep(userOptions, defaults())
    

    this.projectOptions就是把vue.config.js+(./options.js的default)合并到一起的对象即是:

    { 
    runtimeCompiler: true,
      publicPath: '/',
      outputDir: 'dist',
      assetsDir: '',
      indexPath: 'index.html',
      filenameHashing: true,
      transpileDependencies: [],
      productionSourceMap: true,
      parallel: true,
      pages: undefined,
      crossorigin: undefined,
      integrity: false,
      css: {},
      lintOnSave: 'default',
      devServer: {} 
    }
    
    // apply plugins.
        this.plugins.forEach(({ id, apply }) => {
          if (this.pluginsToSkip.has(id)) return
          apply(new PluginAPI(id, this), this.projectOptions)
        })
    

    其中apply(new PluginAPI(id, this), this.projectOptions)表示执行this.plugins的函数,其中就包含base.js的文件,参数一个是api,一个是options

    module.exports = (api, options) => {
    ......
          webpackConfig.resolve
            .alias
              .set(
                'vue$',
                options.runtimeCompiler
                  ? 'vue/dist/vue.esm.js'
                  : 'vue/dist/vue.runtime.esm.js'
              )
    .......
    }
    

    this.projectOptions也就是合并到一起的对象故这里的options.runtimeCompiler中的runtimeCompiler属性也就是vue.config.js中的runtimeCompiler

    相关文章

      网友评论

        本文标题:Vue --- Runtime + Compiler vs. R

        本文链接:https://www.haomeiwen.com/subject/rarmvktx.html