Vue2.5.9源碼解讀(2) — build/config.js

const banner =
  '/*!\n' +
  ' * Vue.js v' + version + '\n' +
  ' * (c) 2014-' + new Date().getFullYear() + ' Evan You\n' +
  ' * Released under the MIT License.\n' +
  ' */' 

在生成的文件中添加的vuejs版本、版權、許可聲明信息。

// 爲一些路徑起別名
const aliases = {
  vue: resolve('src/platforms/web/entry-runtime-with-compiler'),
  compiler: resolve('src/compiler'),
  core: resolve('src/core'),
  shared: resolve('src/shared'),
  web: resolve('src/platforms/web'),
  weex: resolve('src/platforms/weex'),
  server: resolve('src/server'),
  entries: resolve('src/entries'),      // 2.5.9版本中已經不存在這個目錄,只是別名模塊中還存在[不影響]
  sfc: resolve('src/sfc')
};
// 判斷別名對象中是否存在傳入參數的第一個元素對應的鍵值
const resolve = p => {
  // 將傳入字符串參數分割成數組,並取出第一個元素
  const base = p.split('/')[0]
  // 如果別名對象中存在第一個元素對應的鍵值,則返回的路徑爲別名對應值與參數除第一個元素外的字符串組成的全路徑,參看示例1。
  if (aliases[base]) {
    return path.resolve(aliases[base], p.slice(base.length + 1))
  } 
  // 否則,返回值爲當前目錄的上一級路徑與參數組成的全路徑,參看示例2。
  else {
    return path.resolve(__dirname, '../', p)
  }
}
// 示例
1. resolve('web/entry-runtime-with-compiler.js'); => [vue-2.5.9/]src/platforms/web/entry-runtime-with-compiler.js
2. resolve('dist/vue.js'); => [vue-2.5.9/]/dist/vue.js

resolve主要是爲了方便操作路徑。

// 可以認爲是編譯的對象的配置,源碼中都有對每個對象的註釋
const builds = {
  // 只運行時(CommonJS). 使用bundlers,如Webpack、Browserify
  'web-runtime-cjs': ...,
  // 運行時+編譯 CommonJS構建(CommonJS)
  'web-full-cjs': ...,
  // 只運行時(ES Modules). 使用支持ES Modules的bundler,如Rollup、Webpack2
  'web-runtime-esm': ...,
  // 運行時+編譯 ES Modules構建(ES Modules)
  'web-full-esm': ...,
  // 只運行時,開發環境構建(Browser)
  'web-runtime-dev': ...,
  // 只運行時,生產環境構建(Browser)
  'web-runtime-prod': ...,
  // 運行時+編譯 開發環境構建(Browser)
  'web-full-dev': ...,
  // 運行時+編譯 生產環境構建(Browser)
  'web-full-prod': ...,
  // web平臺 編譯(CommonJS)
  'web-compiler': ...,
  // web平臺 編譯(Browser)
  'web-compiler-browser': ...,
  // web平臺服務端渲染(CommonJS)
  'web-server-renderer': ...,
  // web平臺服務端渲染(UMD)
  'web-server-basic-renderer': ...,
  // web平臺服務端渲染(CommonJS),使用webpack server插件
  'web-server-renderer-webpack-server-plugin': ...,
  // web平臺服務端渲染(CommonJS),使用webpack client插件
  'web-server-renderer-webpack-client-plugin': ...,
  // weex平臺 運行時 factory (CommonJS)
  'weex-factory': ...,
  // weex平臺 運行時 framework (CommonJS)
  'weex-framework': ...,
  // weex平臺 編譯 (CommonJS)。使用weex的webpack裝載器
  'weex-compiler': ...
};
// 根據不同的process.env.TARGET生成不同的配置
function genConfig (name) {
  const opts = builds[name]
  const config = {
    input: opts.entry,
    external: opts.external,
    plugins: [
      replace({
        __WEEX__: !!opts.weex,
        __WEEX_VERSION__: weexVersion,
        __VERSION__: version
      }),
      flow(),
      buble(),
      alias(Object.assign({}, aliases, opts.alias))
    ].concat(opts.plugins || []),
    output: {
      file: opts.dest,
      format: opts.format,
      banner: opts.banner,
      name: opts.moduleName || 'Vue'
    }
  }
  // 如果有配置env,則修改config.plugins中的process.env.NODE_ENV的值爲配置的env值
  if (opts.env) {
    config.plugins.push(replace({
      'process.env.NODE_ENV': JSON.stringify(opts.env)
    }))
  }
  // 爲config定義一個_name屬性,屬性值爲enumerable和value
  Object.defineProperty(config, '_name', {
    enumerable: false,  // 不可枚舉
    value: name
  })

  return config
}

genConfig根據指定的process.env.TARGET與builds中的鍵做對比,如果在builds中存在對應的鍵,則生成並對應的配置。這裏並沒有做指定的process.env.TARGET不存在於builds中的處理。

if (process.env.TARGET) {
  module.exports = genConfig(process.env.TARGET)
} else {
  exports.getBuild = genConfig
  exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
}

如果指定了process.env.TARGET,則按指定的導出;否則提供getBuild和getAllBuilds方法。

發佈了52 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章