Vue源码构建过程__Vue.js
发布于 4 年前 作者 banyungong 1583 次浏览 来自 分享
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

Vue版本2.6.11。

首先,分析任何库的源码一定是从它的package.json中进行分析。

script工具流分析: build命令

"build""node scripts/build.js",

我们可以看到实际上在vue源码中的package.json中运行build命令其实就是相当于运行script/build.js。

定位script/build.js

我们可以看到build.js中引入了很多相关模块,这些我们先不去关注。

// 这里的builds 就是通过getAllBuilds()方法得到
// 执行build命令的时候所有需要打包的vue版本
let builds = require('./config').getAllBuilds()

getAllBuilds()它究竟是什么

// config最底部导出了这个方法。
exports.getAllBuilds = () => Object.keys(builds).map(genConfig)

寻找builds和genConfig

首先builds在代码中可以看到这样一个object

const builds = {
// Runtime only (CommonJS). Used by bundlers e.g. Webpack & Browserify
// builds中每个对象就表示vue需要打包的每个不同的版本
'web-runtime-cjs-dev': {
    // 关于resolve方法在config中有定义
    // 感兴趣的朋友可以去看看,它其实就是通过aliaes获得对应的路径
    
    // entry表示需要打包的入口文件路径
    entry: resolve('web/entry-runtime.js'),
    // dest表示构建打包出口的路径
    dest: resolve('dist/vue.runtime.common.dev.js'),
    // format表示模块,就比如AMD,CMD,ESModules
    format: 'cjs',
    // 模式
    env: 'development',
    // banner其实就是打包代码的一些生成的注释~~~~
    banner
},
'web-runtime-cjs-prod': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.prod.js'),
    format: 'cjs',
    env: 'production',
    banner
},
// Runtime+compiler CommonJS build (CommonJS)
'web-full-cjs-dev': {
    entry: resolve('web/entry-runtime-with-compiler.js'),
    dest: resolve('dist/vue.common.dev.js'),
    format: 'cjs',
    env: 'development',
    alias: { he: './entity-decoder' },
    banner
},
... ]

genConfig()

...
const config = {
input: opts.entry,
external: opts.external,
plugins: [
  flow(),
  alias(Object.assign({}, aliases, opts.alias))
].concat(opts.plugins || []),
output: {
  file: opts.dest,
  format: opts.format,
  banner: opts.banner,
  name: opts.moduleName || 'Vue'
},
onwarn: (msg, warn) => {
  if (!/Circular/.test(msg)) {
    warn(msg)
  }

}
...return config

关于genConfig函数我们可以看到其实就是将builds对象里的内容变成roolup打包工具可以识别格式然后进行return。

过滤 仔细阅读代码,我们可以发现在运行build方法之前会对builds进行一层根据process.argv[2]进行过滤的逻辑处理。

if (process.argv[2]) {
  const filters = process.argv[2].split(',')
  builds = builds.filter(b => {
    return filters.some(f => {
      console.log(b.output,'b.output');
      console.log(b._name,'_name');
      console.log(b,'b');
      // 过滤找到匹配对应参数的retrun
      return b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1
    })
  })
else {
  // filter out weex builds by default
  builds = builds.filter(b => {
    return b.output.file.indexOf('weex') === -1
  })
}

最后就是调用build方法进行逻辑的打包。

❤️ 感谢大家

1.如果喜欢本文,就点个赞支持下吧,你的「赞」是我创作的动力。

2.扫码关注公众号,,大家一起共同交流和进步。

版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 大前端晨曦 原文链接:https://juejin.im/post/6857413239773331463

回到顶部