当前位置: 首页 > article >正文

vue cli源码学习之cli-service

vue cli源码学习之cli-service

目录结构分析

cli-service/ :根目录,代表项目的主要服务模块,用于提供命令行服务插件功能

tests/ :测试文件夹,通常用于存放自动化测试代码。文件夹命名约定为 tests,可能包含单元测试或集成测试,用于验证项目功能的正确性。

bin/ :存放可执行文件或脚本,通常包含启动 CLI 服务的入口文件。例如,可以包含一个启动脚本(如 cli-service),用于用户直接在命令行中调用。

generator/ :用于生成代码的模块,通常包含脚手架代码或代码生成器的逻辑。generator 目录下可能会包含模板和代码生成逻辑,用于生成项目中的文件或初始化项目配置。

lib/:库文件夹,包含项目的核心逻辑代码,主要是供外部调用的核心函数和类等。通常在项目中引用这些功能模块实现特定功能。

migrator/:用于 管理迁移脚本 的目录。该文件夹通常包含数据迁移或版本迁移的逻辑,如数据库结构的迁移等。适用于项目的升级或数据结构的演变。

types/类型声明文件夹。通常用于 TypeScript 项目,定义接口和类型,以确保类型安全和代码的可维护性。类型声明可以为其他模块提供类型支持。

.npmignore:文件用于指定哪些文件和文件夹在发布到 npm 时应被忽略。通过 .npmignore 文件可以控制不需要的文件或目录(如测试文件夹、配置文件等)不会被包含在 npm 包中。

package.json:项目的配置文件,定义了项目的基本信息(如名称、版本、依赖项、脚本等),也是 npm 项目必须包含的文件。通过 package.json 可以管理项目的依赖、命令和元数据。

README.md:项目的自述文件,通常用于向用户介绍项目的功能、安装方法、使用指南等。README.md 文件在 GitHub 和 npm 上也会展示出来,帮助用户了解和使用项目。

webpack.config.js:Webpack 的配置文件,用于配置项目的打包过程。Webpack 是一个前端打包工具,配置文件定义了如何处理、打包项目中的资源(如 JavaScript、CSS、图像等)。

bin/ 目录下的启动脚本

vue-cli-service 的命令行脚本,主要功能是启动 Vue CLI 服务。以下是代码的主要作用和流程:
1.检查 Node.js 版本:
使用 semver 模块检查当前运行的 Node.js 版本是否满足 package.json 中定义的版本要求。
如果不满足要求,输出错误信息并终止进程。

2. 创建服务实例
导入 Service 类并创建一个服务实例。服务的上下文是当前工作目录或环境变量VUE_CLI_CONTEXT 指定的目录。

3.解析命令行参数:
使用 minimist 模块解析命令行参数。
定义了一些布尔类型的选项,如 modern、report、open 等。
这些选项是命令行参数,用于配置和控制 vue-cli-service 的行为。以下是每个选项的作用:

构建相关选项:
modern:启用现代模式构建,生成现代 JavaScript 代码以利用新浏览器的特性。
report:生成构建报告,通常用于分析打包后的文件大小和依赖关系。
report-json:生成 JSON 格式的构建报告。
inline-vue:将 Vue 的运行时内联到构建的包中。
watch:在开发模式下监听文件变化,自动重新构建。

服务相关选项:
open:在启动开发服务器后自动打开浏览器
copy:将本地 URL 复制到剪贴板。
https:使用 HTTPS 协议启动开发服务器。

检查相关选项
verbose:启用详细模式,输出更详细的日志信息,通常用于调试。
这些选项可以通过命令行传递给 vue-cli-service,以便在开发和构建过程中自定义其行为。

4. 获取并运行命令:
从解析的参数中获取要执行的命令。
调用服务实例的 run 方法执行命令,并传递解析的参数
如果执行过程中出现错误,捕获错误并输出,然后终止进程。
Vue CLI 的一个入口脚本,用于根据用户输入的命令和参数启动相应的服务或构建任务

generator/路径下的index.js文件

Vue CLI 服务生成器的模块,主要用于根据用户的选项配置项目的模板和依赖。以下是代码的主要功能:
1.模板渲染:
使用 api.render 方法渲染项目模板,并根据是否安装了 Babel 或 TypeScript 插件来决定是否编译代码。

2. 依赖管理:
根据用户选择的 Vue 版本(Vue 2 或 Vue 3),设置相应的项目依赖。
如果是 Vue 2,还会添加 vue-template-compiler 作为开发依赖。

3.脚本和浏览器支持:
扩展 package.json,添加 serve 和 build 脚本,用于启动开发服务器和构建生产环境代码。
配置 browserslist,以支持特定市场份额的浏览器,并根据 Vue 版本决定是否支持 IE 11。

4.CSS 预处理器支持:
根据用户选择的 CSS 预处理器(如 Sass、Less、Stylus),添加相应的开发依赖。

5.Vue 3 兼容性:
如果用户选择了路由或 Vuex,但没有安装相应的插件,则引入默认的路由或 Vuex 配置。

6.额外工具配置:
如果用户提供了额外的配置选项,则将这些配置扩展到 package.json。

7. TypeScript 支持:
如果项目使用 TypeScript,则删除 jsconfig.json 文件,因为 TypeScript 项目通常使用 tsconfig.json。
这段代码的目的是根据用户的选择自动配置 Vue 项目,以便开发者可以快速启动项目开发。

module.exports = (api, options) => {
  // 渲染模板,判断是否使用 Babel 或 TypeScript
  api.render('./template', {
    doesCompile: api.hasPlugin('babel') || api.hasPlugin('typescript'),
    useBabel: api.hasPlugin('babel')
  })

  // 根据 Vue 版本设置依赖
  if (options.vueVersion === '3') {
    api.extendPackage({
      dependencies: {
        'vue': '^3.2.13' // Vue 3 版本
      }
    })
  } else {
    api.extendPackage({
      dependencies: {
        'vue': '^2.6.14' // Vue 2 版本
      },
      devDependencies: {
        'vue-template-compiler': '^2.6.14' // Vue 2 模板编译器
      }
    })
  }

  // 扩展 package.json 的脚本和浏览器列表
  api.extendPackage({
    scripts: {
      'serve': 'vue-cli-service serve', // 启动开发服务器
      'build': 'vue-cli-service build'  // 构建生产环境代码
    },
    browserslist: [
      '> 1%', // 支持市场份额大于 1% 的浏览器
      'last 2 versions', // 支持最新的两个版本
      'not dead', // 不支持已停止更新的浏览器
      ...(options.vueVersion === '3' ? ['not ie 11'] : []) // Vue 3 不支持 IE 11
    ]
  })

  // 根据选择的 CSS 预处理器添加相应的开发依赖
  if (options.cssPreprocessor) {
    const deps = {
      sass: {
        sass: '^1.32.7',
        'sass-loader': '^12.0.0'
      },
      'dart-sass': {
        sass: '^1.32.7',
        'sass-loader': '^12.0.0'
      },
      less: {
        'less': '^4.0.0',
        'less-loader': '^8.0.0'
      },
      stylus: {
        'stylus': '^0.55.0',
        'stylus-loader': '^6.1.0'
      }
    }

    api.extendPackage({
      devDependencies: deps[options.cssPreprocessor]
    })
  }

  // Vue 3 兼容性:如果选择了路由但没有安装插件,则引入路由配置
  if (options.router && !api.hasPlugin('router')) {
    require('./router')(api, options, options)
  }

  // Vue 3 兼容性:如果选择了 Vuex 但没有安装插件,则引入 Vuex 配置
  if (options.vuex && !api.hasPlugin('vuex')) {
    require('./vuex')(api, options, options)
  }

  // 额外的工具配置
  if (options.configs) {
    api.extendPackage(options.configs)
  }

  // 如果使用 TypeScript,删除 jsconfig.json 文件
  if (api.hasPlugin('typescript')) {
    api.render((files) => delete files['jsconfig.json'])
  }
}

cli-service\generator\template\src\App.vue 文件

这段代码是一个 Vue.js 应用程序的模板文件,通常用于生成一个新的 Vue.js 项目。以下是代码的主要作用和结构:

  1. 模板部分:
    根据 rootOptions.vueVersion 判断使用 Vue 3 还是 Vue 2。
    如果是 Vue 3,直接在根元素下显示 Vue 的 logo 和一个 HelloWorld 组件或欢迎标题。
    如果是 Vue 2,使用一个 div 包裹内容,显示 Vue 的 logo 和一个 HelloWorld 组件或欢迎标题。
    rootOptions.bare 用于判断是否显示 HelloWorld 组件或简单的欢迎标题。

  2. 脚本部分:
    导入 HelloWorld 组件。
    定义一个 Vue 组件,名称为 App,并注册 HelloWorld 组件。

  3. 样式部分:
    根据 rootOptions.cssPreprocessor 判断使用哪种 CSS 预处理器。
    如果不是 stylus,则根据选择的预处理器语言设置样式语言。
    定义了 #app 的样式,包括字体、文本对齐、颜色等。
    这段代码通过条件语句和模板语法,动态生成适合不同项目配置的 Vue.js 应用程序模板。

<template>
<%_ if (rootOptions.vueVersion === '3') { _%>
  <img alt="Vue logo" src="./assets/logo.png">
  <%_ if (!rootOptions.bare) { _%>
  <HelloWorld msg="Welcome to Your Vue.js App"/>
  <%_ } else { _%>
  <h1>Welcome to Your Vue.js App</h1>
  <%_ } _%>
<%_ } else { _%>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <%_ if (!rootOptions.bare) { _%>
    <HelloWorld msg="Welcome to Your Vue.js App"/>
    <%_ } else { _%>
    <h1>Welcome to Your Vue.js App</h1>
    <%_ } _%>
  </div>
<%_ } _%>
</template>
<%_ if (!rootOptions.bare) { _%>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<%_ if (rootOptions.cssPreprocessor !== 'stylus') { _%>
<style<%-
  rootOptions.cssPreprocessor
    ? ` lang="${
        rootOptions.cssPreprocessor.includes('sass')
          ? 'scss'
          : rootOptions.cssPreprocessor
      }"`
    : ``
%>>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
<%_ } else { _%>
<style lang="stylus">
#app
  font-family Avenir, Helvetica, Arial, sans-serif
  -webkit-font-smoothing antialiased
  -moz-osx-font-smoothing grayscale
  text-align center
  color #2c3e50
  margin-top 60px
</style>
<%_ } _%>
<%_ } _%>


http://www.kler.cn/a/382963.html

相关文章:

  • 【Python运维】自动化备份与恢复系统的实现:Python脚本实战
  • JAVA学习笔记_MySQL进阶
  • Unity中UGUI的Button动态绑定引用问题
  • json字符串或者json文件转换成相应的bean,报错“Unrecognized field xxx , not marked as ignorable”
  • 重温设计模式--迭代器模式
  • 横向项目三模态融合笔记
  • C语言算法编译成汇编语言增加保密性
  • Unity SRP学习笔记(二)
  • 语音识别中的RPM技术:原理、应用与发展趋势
  • java list使用基本操作
  • ReactPress系列—NestJS 服务端开发流程简介
  • 2024年世界职业院校技能大赛大数据应用与服务赛项(中职组)圆满闭幕
  • 复合查询【MySQL】
  • http 从请求到响应的过程中发生了什么
  • AI技术:转变未来生活与工作的革命性力量
  • 软件测试基础十二(python变量进阶)
  • 多模态大模型架构演变:主流模式的进化路径
  • Django+DRF+Celery+Redis通用Requirements记录
  • [Vue]防止路由重复跳转
  • scala学习记录,Set,Map
  • 前端零基础学习Day-Five
  • 易语言模拟真人动态生成鼠标滑动路径
  • 如何产生新想法并创新?
  • 讲讲分布式与集群的区别?
  • qt QListView详解
  • [前端] 为网站侧边栏添加搜索引擎模块