Vue2源码梳理:源码构建流程与运行时和编译时的版本选择

Vue3 响应式系统源码解析:Proxy 依赖收集与编译时优化 响应式系统是现代前端框架的核心机制,通过拦截数据访问与修改实现视图自动更新。其原理基于依赖收集与触发调度,利用 Proxy 替代 Object.defineProperty 解决新增属性监听与数组索引拦截等痛点,配合 WeakMap 存储依赖关系避免内存泄漏。技术价值在于提升运行时性能与开发体验,应用场景包括单页应用、复杂组件状态管理及模板编译优化。Vue3 源码中,Proxy 拦截、track 与 trigger 机制、微任务调度及 PatchFlag 静态提升共同构成了高效响应式体系,理解这些设计有助于 阅读详情

Vue.js 源码构建


1 )rollup 和 webpack 的对比

  • vuejs的源码呢是基于rollup构建的
  • rollup 和 webpack 都是一个构建工具
    • webpack 它会更强大一些, 会把像图片, css等静态资源通通编译成javascript
    • rollup 更适合一种javscript库的一个编译
      • 它只出了js部分,而其他资源它是不管的,所以它更轻量
      • 在编译后代码也是更友好的
    • 所以 vuejs 就选了rollup做构建

2 )rollup的构建设计

  • vuejs 是发布到 npm 上的一个包, 每个包都是需要一个package.json文件来做描述
  • 它是对项目的描述文件,它的内容实际上是一个标准的 JSON 对象
  • 比如说,常用的属性, name, version, description, main, module, …
    • main 是vue的入口,在 import vue 时,通过这个 main 来查找入口, 后缀是.js
    • module 和 main 非常类似的,在webpack2以上把 module作为默认入口, 后缀是 .esm.js
  • vuejs 源码是基于 rollup 构建的,它的构建相关配置都在 scripts 目录下
  • npm 提供了一个叫 npm scripts 的东西
    • 之前早期构建, 可能会用到gulp或者grunt
    • 它们两个都是一个以任务为基准的
    • 也就是说可以定义一系列任务
    • npm scripts 就是完成了这部分的功能
    • 也就是说它定义了很多脚本, 每个脚本都是一个任务
    • 通过 npm run xxx 可以执行不同的任务
    • 构建相关的任务,就是这三个
      • build 构建web平台相关
      • build:ssr 构建服务端渲染相关
      • build:weex 构建weex平台相关
  • 我们的源码是托管在 src 目录下,通过构建生成的目标代码在 dist 目录下
    • 在vue的仓库下,它已经默认帮我们构建出来很多版本的vuejs
    • 那为什么我们能构建如此多版本的vuejs呢?

3 )rollup构建vuejs的过程

package.json

{
  "script": {
    "build": "node scripts/build.js",
    "build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
    "build:weex": "npm run build -- weex"
  }
}
  • 当我们去执行的这个 npm scripts 的时候,比如说,执行 npm run build
  • 它实际上就是执行了这样一个脚本 node scripts/build.js
  • 我们来看一下 scripts/build.js

scripts/build.js

const fs = require('fs')
const path = require('path')
const zlib = require('zlib')
const rollup = require('rollup')
const terser = require('terser')

if (!fs.existsSync('dist')) {
  fs.mkdirSync('dist')
}

let builds = require('./config').getAllBuilds()

// filter builds via command line arg
if (process.argv[2]) {
  const filters = process.argv[2].split(',')
  builds = builds.filter(b => {
    return filters.some(f => 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(builds)

function build (builds) {
  let built = 0
  const total = builds.length
  const next = () => {
    buildEntry(builds[built]).then(() => {
      built++
      if (built < total) {
        next()
      }
    }).catch(logError)
  }

  next()
}

function buildEntry (config) {
  const output = config.output
  const { file, banner } = output
  const isProd = /(min|prod)\.js$/.test(file)
  return rollup.rollup(config)
    .then(bundle => bundle.generate(output))
    .then(({ output: [{ code }] }) => {
      if (isProd) {
        const minified = (banner ? banner + '\n' : '') + terser.minify(code, {
          toplevel: true,
          output: {
            ascii_only: true
          },
          compress: {
            pure_funcs: ['makeMap']
          }
        }).code
        return write(file, minified, true)
      } else {
        return write(file, code)
      }
    })
}

function write (dest, code, zip) {
  return new Promise((resolve, reject) => {
    function report (extra) {
      console.log(blue(path.relative(process.cwd(), dest)) + ' ' + getSize(code) + (extra || ''))
      resolve()
    }

    fs.writeFile(dest, code, err => {
      if (err) return reject(err)
      if (zip) {
        zlib.gzip(code, (err, zipped) => {
          if (err) return reject(err)
          report(' (gzipped: ' + getSize(zipped) + ')')
        })
      } else {
        report()
      }
    })
  })
}

function getSize (code) {
  return (code.length / 1024).toFixed(2) + 'kb'
}

function logError (e) {
  console.log(e)
}

function blue (str) {
  return '\x1b[1m\x1b[34m' + str + '\x1b[39m\x1b[22m'
}
  • 前面声明读取的模块
  • let builds = require('./config').getAllBuilds() 是从配置文件中,读取配置
  • 之后,再通过命令行参数对构建配置做过滤,最终调用 build() 函数 进行真正的构建
  • 所以它整个的构建的流程是非常清晰的
  • 那我们首先来分析一下这个这就是怎么拿到的

打开 .config 文件

const path = require('path')
const buble = require('rollup-plugin-buble')
const alias = require('rollup-plugin-alias')
const cjs = require('rollup-plugin-commonjs')
const replace = require('rollup-plugin-replace')
const node = require('rollup-plugin-node-resolve')
const flow = require('rollup-plugin-flow-no-whitespace')
const version = process.env.VERSION || require('../package.json').version
const weexVersion = process.env.WEEX_VERSION || require('../packages/weex-vue-framework/package.json').version
const featureFlags = require('./feature-flags')

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

const weexFactoryPlugin = {
  intro () {
    return 'module.exports = function weexFactory (exports, document) {'
  },
  outro () {
    return '}'
  }
}

const aliases = require('./alias')
const resolve = p => {
  const base = p.split('/')[0]
  if (aliases[base]) {
    return path.resolve(aliases[base], p.slice(base.length + 1))
  } else {
    return path.resolve(__dirname, '../', p)
  }
}

const builds = {
  // Runtime only (CommonJS). Used by bundlers e.g. Webpack & Browserify
  '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
  },
  // 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
  },
  'web-full-cjs-prod': {
    entry: resolve('web/entry-runtime-with-compiler.js'),
    dest: resolve('dist/vue.common.prod.js'),
    format: 'cjs',
    env: 'production',
    alias: { he: './entity-decoder' },
    banner
  },
  // Runtime only ES modules build (for bundlers)
  'web-runtime-esm': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.esm.js'),
    format: 'es',
    banner
  },
  // Runtime+compiler ES modules build (for bundlers)
  'web-full-esm': {
    entry: resolve('web/entry-runtime-with-compiler.js'),
    dest: resolve('dist/vue.esm.js'),
    format: 'es',
    alias: { he: './entity-decoder' },
    banner
  },
  // Runtime+compiler ES modules build (for direct import in browser)
  'web-full-esm-browser-dev': {
    entry: resolve('web/entry-runtime-with-compiler.js'),
    dest: resolve('dist/vue.esm.browser.js'),
    format: 'es',
    transpile: false,
    env: 'development',
    alias: { he: './entity-decoder' },
    banner
  },
  // Runtime+compiler ES modules build (for direct import in browser)
  'web-full-esm-browser-prod': {
    entry: resolve('web/entry-runtime-with-compiler.js'),
    dest: resolve('dist/vue.esm.browser.min.js'),
    format: 'es',
    transpile: false,
    env: 'production',
    alias: { he: './entity-decoder' },
    banner
  },
  // runtime-only build (Browser)
  'web-runtime-dev': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.js'),
    format: 'umd',
    env: 'development',
    banner
  },
  // runtime-only production build (Browser)
  'web-runtime-prod': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.min.js'),
    format: 'umd',
    env: 'production',
    banner
  },
  // Runtime+compiler development build (Browser)
  'web-full-dev': {
    entry: resolve('web/entry-runtime-with-compiler.js'),
    dest: resolve('dist/vue.js'),
    format: 'umd',
    env: 'development',
    alias: { he: './entity-decoder' },
    banner
  },
  // Runtime+compiler production build  (Browser)
  'web-full-prod': {
    entry: resolve('web/entry-runtime-with-compiler.js'),
    dest: resolve('dist/vue.min.js'),
    format: 'umd',
    env: 'production',
    alias: { he: './entity-decoder' },
    banner
  },
  // Web compiler (CommonJS).
  'web-compiler': {
    entry: resolve('web/entry-compiler.js'),
    dest: resolve('packages/vue-template-compiler/build.js'),
    format: 'cjs',
    external: Object.keys(require('../packages/vue-template-compiler/package.json').dependencies)
  },
  // Web compiler (UMD for in-browser use).
  'web-compiler-browser': {
    entry: resolve('web/entry-compiler.js'),
    dest: resolve('packages/vue-template-compiler/browser.js'),
    format: 'umd',
    env: 'development',
    moduleName: 'VueTemplateCompiler',
    plugins: [node(), cjs()]
  },
  // Web server renderer (CommonJS).
  'web-server-renderer-dev': {
    entry: resolve('web/entry-server-renderer.js'),
    dest: resolve('packages/vue-server-renderer/build.dev.js'),
    format: 'cjs',
    env: 'development',
    external: Object.keys(require('../packages/vue-server-renderer/package.json').dependencies)
  },
  'web-server-renderer-prod': {
    entry: resolve('web/entry-server-renderer.js'),
    dest: resolve('packages/vue-server-renderer/build.prod.js'),
    format: 'cjs',
    env: 'production',
    external: Object.keys(require('../packages/vue-server-renderer/package.json').dependencies)
  },
  'web-server-renderer-basic': {
    entry: resolve('web/entry-server-basic-renderer.js'),
    dest: resolve('packages/vue-server-renderer/basic.js'),
    format: 'umd',
    env: 'development',
    moduleName: 'renderVueComponentToString',
    plugins: [node(), cjs()]
  },
  'web-server-renderer-webpack-server-plugin': {
    entry: resolve('server/webpack-plugin/server.js'),
    dest: resolve('packages/vue-server-renderer/server-plugin.js'),
    format: 'cjs',
    external: Object.keys(require('../packages/vue-server-renderer/package.json').dependencies)
  },
  'web-server-renderer-webpack-client-plugin': {
    entry: resolve('server/webpack-plugin/client.js'),
    dest: resolve('packages/vue-server-renderer/client-plugin.js'),
    format: 'cjs',
    external: Object.keys(require('../packages/vue-server-renderer/package.json').dependencies)
  },
  // Weex runtime factory
  'weex-factory': {
    weex: true,
    entry: resolve('weex/entry-runtime-factory.js'),
    dest: resolve('packages/weex-vue-framework/factory.js'),
    format: 'cjs',
    plugins: [weexFactoryPlugin]
  },
  // Weex runtime framework (CommonJS).
  'weex-framework': {
    weex: true,
    entry: resolve('weex/entry-framework.js'),
    dest: resolve('packages/weex-vue-framework/index.js'),
    format: 'cjs'
  },
  // Weex compiler (CommonJS). Used by Weex's Webpack loader.
  'weex-compiler': {
    weex: true,
    entry: resolve('weex/entry-compiler.js'),
    dest: resolve('packages/weex-template-compiler/build.js'),
    format: 'cjs',
    external: Object.keys(require('../packages/weex-template-compiler/package.json').dependencies)
  }
}

function genConfig (name) {
  const opts = builds[name]
  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)
      }
    }
  }

  // built-in vars
  const vars = {
    __WEEX__: !!opts.weex,
    __WEEX_VERSION__: weexVersion,
    __VERSION__: version
  }
  // feature flags
  Object.keys(featureFlags).forEach(key => {
    vars[`process.env.${key}`] = featureFlags[key]
  })
  // build-specific env
  if (opts.env) {
    vars['process.env.NODE_ENV'] = JSON.stringify(opts.env)
  }
  config.plugins.push(replace(vars))

  if (opts.transpile !== false) {
    config.plugins.push(buble())
  }

  Object.defineProperty(config, '_name', {
    enumerable: false,
    value: name
  })

  return config
}

if (process.env.TARGET) {
  module.exports = genConfig(process.env.TARGET)
} else {
  exports.getBuild = genConfig
  exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
}
  • 这个config文件在最后一行暴露了一个方法,叫 getAllBuilds,它是一个函数
    • 这个函数做了什么事情呢? Object.keys(builds).map(genConfig)
    • 拿到一个keys的数组,然后我们再通过map方法调用这个 genConfig 函数
  • 我们来看这个 builds 参数
    • 上面代码大篇幅定义了 builds 对象
    • 里面每个key对应的也都是一个对象
      • 通过注释可知,是不同版本的vuejs的编译配置
      • 每一个编译配置它都会有一个 entry 顾名思义就是入口
      • dest 顾名思义就是目标
      • 还有一个format(输出格式) 和 banner(头部注释)
  • 这个 entry 它是通过 resolve 这个函数,然后传一个字符串(文件地址)
    const aliases = require('./alias')
    const resolve = p => {
      const base = p.split('/')[0]
      if (aliases[base]) {
        return path.resolve(aliases[base], p.slice(base.length + 1))
      } else {
        return path.resolve(__dirname, '../', p)
      }
    }
    
    • resolve 函数,它就是接收一个参数。这个字符参数会通过split(‘/’) 拿到第一个值作为base
    • 之后判断 aliases 这个 aliases 也是 require 进来的,看下这个 alias 文件
      const path = require('path')
      const resolve = p => path.resolve(__dirname, '../', p)
      
      module.exports = {
        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'),
        sfc: resolve('src/sfc')
      }
      
    • 可见,alias 文件提供别名到真实地址文件的映射
    • 回到最上面的 resolve 方法内部,最终返回了从参数到真实地址的字符串
  • dest 这个key也走的 resolve, 只不过走到了 最终 else 的环节里
  • format 是构建出来的文件格式,cjs 对应的就是 xxx.common.js
    • cjs 最终生成的js文件是 module.exports = Vue
    • es 最终生成的文件是 export default Vue
    • umd 最终生成的文件是 符合 umd 规范的 vuejs 文件
    • …
  • 所以,很显然
    • 上面 web 对应的真实的路径是 path.resolve(__dirname, ‘…/src/platforms/web’),这个路径就找到了 Vue.js 源码的 web 目录
    • 然后 resolve 函数通过 path.resolve(aliases[base], p.slice(base.length + 1)) 找到了最终路径
    • 它就是 Vue.js 源码 web 目录下的 entry-runtime.js。因此,web-runtime-cjs 配置对应的入口文件就找到了
    • 它经过 Rollup 的构建打包后,最终会在 dist 目录下生成 vue.runtime.common.js
  • banner 是自己设计的头部注释
    • 里面可以 写八本,日期,作者,license 等信息
  • 再回到我们的config,最终通过 Object.keys(builds).map(genConfig)
    • 拿到这个所有keys 的一个数组,然后这个这个数组我们去调用这个 genConfig 函数
    • genConfig 就拿到每个key,然后它就会拿到这个对象,再通过 build[name]
    • name 是key对应的这个对象,构造出一个新的 config 对象
      • 里面有 input, external, plugins, output, …
    • 这个最终的 config 对象才是 rollup 打包所需要的配置结构
    • 这是个适配器来进行的转换工作
  • 返回到 let builds = require('./config').getAllBuilds()
    • 这里的 builds 是一个数组
  • 之后进行 if (process.argv[2]) {} 的判断
    • 提取到命令行输出的参数,如 – weex 等
    • 如果有参数,则会通过 filter 来过滤一些不需要的流程
  • 最终编译的时候,就调用 build(builds) 在里面进行一个个的编译
    • 里面定义一个 next() 函数,里面调用 buildEntry, 之后递归,里面有个 built 计数器
    • 而 buildEntry 传入最终的config, config作为最终rollup的参数进行构建
    • 编译完之后得到了 bundle, 通过了 bundle.generate 传入 output
    • 之后拿到 code, 判断环境,分别做处理,最终通过 write 方法,得到构建好的文件
    • 在生成的过程中,打下一些 log 信息
  • 这是整个的构建流程

4 ) Runtime Only VS Runtime + Compiler

  • 通常我们利用 vue-cli 去初始化我们的 Vue.js 项目的时候
  • 会询问我们用 Runtime Only 版本的还是 Runtime + Compiler 版本
  • 下面我们来对比这两个版本

4.1 ) Runtime Only

  • 我们在使用 Runtime Only 版本的 Vue.js 的时候,通常需要借助如 webpack 的 vue-loader 工具把 .vue 文件编译成 JavaScript
  • 在浏览器里,是不认识 .vue文件的,所以需要一个编译的过程,在编译阶段,会把 template 模板编译成 render 函数
  • 最终编译后的,就是一个 render 函数的版本,所以vue是不带编译的,也就是运行时不带编译
  • 所以它只包含运行时的 Vue.js 代码,因此代码体积也会更轻量

4.2 )Runtime + Compiler

  • 我们如果没有对代码做预编译,但又使用了 Vue 的 template 属性并传入一个字符串,则需要在客户端编译模板,如下所示:

    // 需要编译器的版本
    new Vue({
      template: '<div>{{ hi }}</div>'
    })
    
  • 这种一定要选择 Runtime + Compiler 版本

    // 这种情况不需要
    new Vue({
      render (h) {
        return h('div', this.hi)
      }
    })
    
  • 这种就不需要

  • 而 .vue文件 是在编译过程中,通过 vue-loader 处理的

  • 所以我们写的 .vue 文件在运行的时候已经编译成 js 函数了,并且模板部分已经编译成 render 函数了

  • 在 Vue.js 2.0 中,最终渲染都是通过 render 函数,如果写 template 属性,则需要编译成 render 函数

  • 那么这个编译过程会发生运行时,需要带有编译器的版本

  • 很显然,这个编译过程对性能会有一定损耗,所以通常开发阶段更推荐使用 Runtime-Only 的 Vue.js

    • 一种是运行时的性能优化,一种是编译出来的体积会更轻量

5 )总结

  • 我们可了解到 Vue.js 的构建打包过程,也知道了不同作用和功能的 Vue.js 它们对应的入口以及最终编译生成的 JS 文件
  • 在实际开发过程中我们会用 Runtime Only 版本开发比较多
  • 但为了分析 Vue 的编译过程,我们重点分析的源码是
SpringBoot+Vue旅游管理系统:源码解析与部署全流程指南 前后端分离架构已成为现代Web开发的主流模式,SpringBoot与Vue的组合凭借其轻量、高效、生态完善的特点,广泛应用于各类业务系统开发。在旅游管理系统中,SpringBoot负责提供RESTful API,处理业务逻辑与数据持久化,Vue则通过组件化方式构建用户界面,实现动态交互。这种架构不仅提升了开发效率,还便于后期维护与扩展。本文从实战角度出发,围绕一套完整的SpringBoot+Vue旅游管理系统,详细讲解源码目录结构、运行环境选型、MySQL数据库导入、基于JWT的登录鉴权、MyBatis-P 阅读详情

相关推荐

SSM+Vue电子商城系统:源码解析与部署实战指南

在Java后端开发领域,SSM框架(Spring、SpringMVC、MyBatis)与Vue前端框架的组合,依然是构建企业级Web应用的经典方案。SSM通过分层架构清晰管理对象、请求路由与数据持久化,Vue则以组件化方式提升界面开发效率,两者通过JSON接口实现前后端分离,既降低了系统耦合度,也贴近真实电商项目的工程实践。对于初学者或求职者而言,掌握这套技术栈不仅能深入理解Java Web底层原理,还能快速搭建出商品管理、购物车、订单流转等核心业务闭环。本文从环境版本匹配、三层架构拆解、Vue组件组织、部

weixin_32183107的博客 273

vue2源码解析(学习笔记)

vue源码调试解析

weixin_47454918的博客 3629

解决Matlab激活后License checkout failed问题的详细步骤与避坑指南

本文详细解析了Matlab激活后出现License checkout failed错误的常见原因及解决方案,重点介绍了如何正确找到并运行激活程序,避免用户名填写错误等常见问题。文章还提供了多次激活与疑难排解的实用建议,帮助用户顺利完成Matlab激活过程。

weixin_33670786的博客 582

Vue2源代码解读(含源码)

Vue2源代码解读(含源码)

weixin_43263566的博客 2867

帆软 finereport FCRA 考试 题库+答案,共收录561题,大部分有答案

帆软 finereport FCRA 考试 题库+答案,共收录561题,大部分有答案 入门基础 11.多选题 以下方式中属于FineReport中预览模式的有( ) 分页预览、填报预览、新填报预览、数据分析、移动端预览 16.判断题 FineReport报表工具必须购买激活码后才能使用。 错误,可以免费获取激活码。 29.单选题 FineReport是一款利用( )语言开发的报表工具。java 41.多选题 访问帮助文档的方式有哪些?设计器中社区菜单下-帮助文档;直接访问http://help.finere

qq_37485720的博客 2万+

Vivado FFT IP核避坑指南:从Matlab数据生成到FPGA验证的完整流程

本文详细解析了Vivado FFT IP核从Matlab数据生成到FPGA验证的完整流程,重点解决跨平台数据一致性、IP核配置陷阱和验证方法论等核心问题。通过实战案例和避坑指南,帮助工程师高效实现FFT运算的硬件验证,确保结果与Matlab的误差控制在0.3%以内。

weixin_42543046的博客 398

vue2.x源码解析(一)

本文以vue2.x框架作为分析,简单记录整个源码编译的过程。

weixin_45514326的博客 2753

Abaqus 导出单元刚度矩阵和全局刚度矩阵

Abaqus 导出单元刚度矩阵和全局刚度矩阵

科技芯风 1万+

Vue2源码解读

例如,Vue.js 会在内部定义一些工具方法,这些工具方法既可以在浏览器端的 Vue.js 中使用,也可以在服务端的 Vue.js 中使用。需要注意的是,在Vue 2.x中,如果你使用了构建时预编译(例如通过vue-loader),那么模板已经被编译成了渲染函数,Vue在运行时就不需要再次编译了。在Vue 3.x中,编译过程有所变化,因为Vue 3引入了编译时优化和更高效的编译策略,但基本概念仍然相同:模板被编译成渲染函数,然后Vue使用这些渲染函数来生成和更新DOM。时,实际上是在调用这个构造函数。

警警的博客 2475

Jetson AGX Orin边缘AI实战:用YOLOv8做目标检测,我的环境配置踩坑与优化记录

本文详细记录了在Jetson AGX Orin上部署YOLOv8目标检测模型的环境配置与优化过程。从JetPack版本确认、PyTorch安装陷阱到Torchvision编译技巧,再到YOLOv8部署和系统级优化,提供了完整的实战指南。特别针对边缘AI设备的特性,分享了CUDA加速、内存管理等性能调优经验,帮助开发者高效完成工业级AI应用部署。

weixin_30839881的博客 377

ctx->cvdl->cuvidGetDecoderCaps(&ctx->caps8) failed -> CUDA_ERROR_DEINITIALIZED: driver shutting down

ffplay -vcodec h264_cuvid sample_720p-2.h264 [quantum6@freeswitch freeswitch]$ ffplay -vcodec h264_cuvid sample_720p-2.h264 ffplay version 4.3.1 Copyright (c) 2003-2020 the FFmpeg developers built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-44) .

柳鲲鹏 2408

vue-cli2 与vue-cli3,vue2与vue3 初始化项目,解析区别

vue-cli2 与vue-cli3,vue2与vue3 初始化项目,解析区别

hap1994的博客 2579

阿里天池新闻推荐实战:多路召回策略解析与优化

本文深入解析阿里天池新闻推荐项目中的多路召回策略,包括ItemCF、UserCF、YouTubeDNN等五种召回模型的协同应用与优化技巧。通过实战案例展示如何提升推荐系统效果,特别针对冷启动问题提出创新解决方案,帮助开发者构建高效的新闻推荐系统。

weixin_26918763的博客 416

Vue3源码梳理:关于运行时和编译时

上述 v-if 和 m-com 自定义组件不是正常的html, 浏览器是不认识的,所以不会解析。.vue文件是单文件组件, 在template中写入的html是真实的html标记节点么?vue中的编译时,准确来说是编译器的意思,核心代码在 compiler-core模块下。运行时做不到的事情,通过html标签结构的方式来渲染解析成真实的dom节点。初次渲染,会生成一个ul标签,同时生成三个li标签,并把他们挂载到div中。这个过程主要是:让假标记,被渲染成真实的html标签,最终呈现给用户。

Wang的专栏 990

实现基于 Python 和 xterm.js 的 Web 交互终端demo

前端 (HTML):使用 xterm.js 作为前端终端模拟器库。创建了一个 WebSocket 连接到 ws://localhost:8765,这与后端服务器的地址和端口匹配。监听 WebSocket 消息,并将数据写入终端。同时监听用户输入并发送到服务器。后端 (Python):使用 websockets 库来创建 WebSocket 服务器,监听端口 8765。使用 paramiko 库来创建 SSH 客户端并连接到指定的远程服务器。

u010674101的专栏 876

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Vue 3 性能优化实战:从编译时标记到静态提升与运行时优化

在前端应用日益复杂的今天,虚拟 DOM diff 的性能成为影响页面流畅度的关键因素。Vue 3 通过编译阶段的 patchFlag 标记与静态提升(hoistStatic),将模板中动态与静态节点分离,使得运行时只需对比动态节点,大幅减少不必要的计算和重复创建。结合 Block Tree 与快速 diff 算法,在长列表、报表页、文章详情等静态占比高的场景中,渲染更新效率得到显著提升。理解编译器与运行时如何分工协作,掌握模板结构设计对优化效果的影响,才能让 Vue 3 的性能优势真正落地。

weixin_29628635的博客 124

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

vue 全局静态变量_Vue源码探秘(一)

引言 Vue作为当前前端开发中比较重要的框架,在企业级开发中应用十分广泛。目前也是我的主要技术栈之一。在接下来的系列文章中,我将带大家一起探秘Vue.js底层源码。本篇文章是Vue源码探秘的第一篇。在这一篇中,我主要是带大家做一些准备工作,介绍一下flow、源码目录和源码构建流程。认识flow flow是facebook 出品的 JavaScript 静态类型检查工具。Vue.js 的源...

weixin_42523846的博客 372

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

我的Vue2/Vue3知识框架汇总

基础一定要多看,很多看似复杂的bug,实际都是基础问题,不要把时间浪费在修复基础问题的bug上。本文以知识点总结为主,将技术点连成线,再结成网,不管面试官问啥,都能扯一扯啦~最近总感觉知道的越多之后,不知道的更多;还有许多需要学习的,总结这篇文章之后,也该需要制定个以后的学习计划了。然后这篇关于vue2/vue3的文章也算是一个阶段性的总结吧,有了对vue框架的理解,相信再上手框架的学习也会有帮助。

铁锤妹妹的博客 1956

Vue 3 核心原理与实战:从响应式到企业级应用

Vue 3 核心原理与实战指南 本文全面解析 Vue 3 的核心技术升级与最佳实践。重点探讨了: 响应式系统革命:采用 Proxy 替代 defineProperty,实现更高效的属性监听和惰性劫持 编译时优化:通过 Patch Flag 和静态提升技术大幅提升虚拟 DOM 性能 开发范式演进:Composition API 提供更好的逻辑复用与 TypeScript 支持 现代化工具链:推荐使用 Vite 构建工具、Pinia 状态管理和 Nuxt 3 全栈框架 文章通过代码示例和原理对比,帮助开发者从

1221

Vue2到Vue3全家桶升级实战指南

本文提供了从Vue2升级到Vue3全家桶的完整实战指南。文章详细阐述了升级的必要性,包括性能提升、打包体积优化及Composition API带来的开发体验革新。核心内容涵盖升级前的项目评估与规划、核心API变更(如生命周期、v-model、过滤器)的适配方法、Composition API的实战应用,以及Vue Router 4、Pinia状态管理和Vite构建工具等生态库的升级策略,并总结了迁移过程中的常见问题与避坑指南。

xk7n92h3p5m的博客 539

Vue项目图片资源全指南:从路径原理到构建优化与排错

在前端工程化实践中,静态资源路径处理是打包构建与运行时表现差异的常见问题。开发环境正常、生产环境404的根源往往在于编译期静态分析与运行期路径解析的割裂。理解webpack/Vite对图片模块的打包机制,掌握public与assets目录的适用场景,是保障Vue应用稳定部署的基础。针对动态图片拼接、require.context与import.meta.glob批量加载、base64内联阈值、懒加载等细节,制定合理的工程化约定,既能避免线上资源丢失,也能优化页面加载性能。本文从路径原理出发,系统梳理Vue项

weixin_27945229的博客 252

Vue2与Vue3 Diff算法深度对比:从双端Diff到最长递增子序列

虚拟DOM是前端框架高效渲染的基础,diff算法则是衡量性能的关键一环。Vue2采用双端diff,通过四个指针尽可能复用节点;Vue3引入快速diff,借助最长递增子序列将DOM移动次数降至最优。同时,Vue3编译阶段的patchFlag和Block Tree机制,让diff只关注动态节点,进一步减少无意义的比较开销。在长列表拖拽排序、复杂模板频繁更新等场景中,Vue3性能优势更为明显。理解两代diff的设计取舍,有助于开发者合理使用key、规避常见性能陷阱,实现更优的前端工程实践。

weixin_30166691的博客 215

Vue面试核心考点与2026前端趋势解析

响应式原理作为现代前端框架的核心机制,通过数据劫持实现视图自动更新。Vue2采用Object.defineProperty,而Vue3升级为Proxy代理,显著提升了性能并解决了数组监听等痛点问题。在工程实践中,理解虚拟DOM的diff算法和key的优化作用对性能调优至关重要,例如通过v-memo实现编译时优化可大幅提升渲染效率。随着组合式API的普及和TypeScript的强类型支持,Vue3在大型应用开发中展现出更强的工程化优势。当前微前端架构与模块联邦等技术的结合,正推动Vue在复杂系统集成中的创新应

weixin_34208185的博客 408

Bootstrap 5 从入门到精通:版本选择、安装定制与实战指南

前端开发中,CSS框架是构建响应式、一致性界面的核心工具,其原理在于通过预定义的样式类和组件系统,将设计规范转化为可复用的代码模块。这类框架的技术价值在于极大提升了开发效率,保证了多设备、多浏览器的兼容性,并降低了团队协作的样式维护成本。在实际应用场景中,无论是快速搭建管理后台、官网原型,还是开发需要广泛兼容性的企业级应用,一个成熟稳定的框架都是关键。本文聚焦于Bootstrap这一经典工具,深入探讨其v4与v5版本的选型策略,详解CDN、NPM及源码编译三种安装方式,并解析其移动优先、工具类驱动的设计哲学

weixin_33861800的博客 517

Vue3性能优化实战:从编译到运行的全方位提升

前端性能优化是现代Web开发的核心课题,尤其在Vue3框架中,通过编译时优化和运行时调优可以显著提升应用性能。编译阶段利用静态节点提升和Tree Shaking能有效减少打包体积,而运行时的响应式系统优化则通过shallowRef等API避免不必要的性能开销。这些技术手段在大型后台管理系统和电商平台等场景中尤为重要,能直接提升用户体验。本文以Vue3为例,详细解析如何通过组件拆分、虚拟滚动等具体方案实现性能飞跃,其中静态提升和shallowRef等热词技术在实际项目中可带来40%以上的性能提升。

weixin_33417488的博客 206

JavaScript class 不是语法糖:原型、继承与运行时契约深度解析

JavaScript 的 class 关键字常被误认为 ES6 引入的语法糖,实则是面向对象编程范式在原型机制之上的强制性抽象协议。其本质在于将开发者心智从‘函数即一切’转向‘构造器-原型-实例’三元运行时模型,背后由 V8 的 [[Construct]] 内部方法、严格模式约束、暂时性死区(TDZ)及不可枚举方法等底层契约共同支撑。这种设计既保障了继承链的可预测性(如 prototype.__proto__ 拓扑),也带来了工程挑战——从 instanceof 失效、HMR 不兼容到 Web Worker

weixin_33984032的博客 560
上一篇: Vue2源码梳理:关于vue2的源码目录设计与相关模块作用分析
下一篇: Vue2源码梳理:在 import Vue 时干了啥
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值