国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

vue-cli系列之vue-cli-service整體架構淺析

2024-05-06 15:43:18
字體:
來源:轉載
供稿:網友

概述

vue啟動一個項目的時候,需要執行npm run serve,其中這個serve的內容就是vue-cli-service serve。可見,項目的啟動關鍵是這個vue-cli-service與它的參數serve。接下來我們一起看看service中主要寫了什么東東(主要內容以備注形式寫到代碼中。)。

關鍵代碼

vue-cli-service.js

const semver = require('semver')const { error } = require('@vue/cli-shared-utils')const requiredVersion = require('../package.json').engines.node// 檢測node版本是否符合vue-cli運行的需求。不符合則打印錯誤并退出。if (!semver.satisfies(process.version, requiredVersion)) { error(  `You are using Node ${process.version}, but vue-cli-service ` +  `requires Node ${requiredVersion}./nPlease upgrade your Node version.` ) process.exit(1)}// cli-service的核心類。const Service = require('../lib/Service')// 新建一個service的實例。并將項目路徑傳入。一般我們在項目根路徑下運行該cli命令。所以process.cwd()的結果一般是項目根路徑const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())// 參數處理。const rawArgv = process.argv.slice(2)const args = require('minimist')(rawArgv, { boolean: [  // build  'modern',  'report',  'report-json',  'watch',  // serve  'open',  'copy',  'https',  // inspect  'verbose' ]})const command = args._[0]// 將參數傳入service這個實例并啟動后續工作。如果我們運行的是npm run serve。則command = "serve"。service.run(command, args, rawArgv).catch(err => { error(err) process.exit(1)})

Service.js

上面實例化并調用了service的run方法,這里從構造函數到run一路瀏覽即可。

const fs = require('fs')const path = require('path')const debug = require('debug')const chalk = require('chalk')const readPkg = require('read-pkg')const merge = require('webpack-merge')const Config = require('webpack-chain')const PluginAPI = require('./PluginAPI')const loadEnv = require('./util/loadEnv')const defaultsDeep = require('lodash.defaultsdeep')const { warn, error, isPlugin, loadModule } = require('@vue/cli-shared-utils')const { defaults, validate } = require('./options')module.exports = class Service { constructor (context, { plugins, pkg, inlineOptions, useBuiltIn } = {}) {  process.VUE_CLI_SERVICE = this  this.initialized = false  // 一般是項目根目錄路徑。  this.context = context  this.inlineOptions = inlineOptions  // webpack相關收集。不是本文重點。所以未列出該方法實現  this.webpackChainFns = []  this.webpackRawConfigFns = []  this.devServerConfigFns = []  //存儲的命令。  this.commands = {}  // Folder containing the target package.json for plugins  this.pkgContext = context  // 鍵值對存儲的pakcage.json對象,不是本文重點。所以未列出該方法實現  this.pkg = this.resolvePkg(pkg)  // **這個方法下方需要重點閱讀。**  this.plugins = this.resolvePlugins(plugins, useBuiltIn)    // 結果為{build: production, serve: development, ... }。大意是收集插件中的默認配置信息  // 標注build命令主要用于生產環境。  this.modes = this.plugins.reduce((modes, { apply: { defaultModes }}) => {   return Object.assign(modes, defaultModes)  }, {}) } init (mode = process.env.VUE_CLI_MODE) {  if (this.initialized) {   return  }  this.initialized = true  this.mode = mode  // 加載.env文件中的配置  if (mode) {   this.loadEnv(mode)  }  // load base .env  this.loadEnv()  // 讀取用戶的配置信息.一般為vue.config.js  const userOptions = this.loadUserOptions()  // 讀取項目的配置信息并與用戶的配置合并(用戶的優先級高)  this.projectOptions = defaultsDeep(userOptions, defaults())  debug('vue:project-config')(this.projectOptions)  // 注冊插件。  this.plugins.forEach(({ id, apply }) => {   apply(new PluginAPI(id, this), this.projectOptions)  })  // wepback相關配置收集  if (this.projectOptions.chainWebpack) {   this.webpackChainFns.push(this.projectOptions.chainWebpack)  }  if (this.projectOptions.configureWebpack) {   this.webpackRawConfigFns.push(this.projectOptions.configureWebpack)  } } resolvePlugins (inlinePlugins, useBuiltIn) {  const idToPlugin = id => ({   id: id.replace(/^.///, 'built-in:'),   apply: require(id)  })  let plugins      // 主要是這里。map得到的每個插件都是一個{id, apply的形式}  // 其中require(id)將直接import每個插件的默認導出。  // 每個插件的導出api為  // module.exports = (PluginAPIInstance,projectOptions) => {  //  PluginAPIInstance.registerCommand('cmdName(例如npm run serve中的serve)', args => {  //    // 根據命令行收到的參數,執行該插件的業務邏輯  //  })  //  // 業務邏輯需要的其他函數  //}  // 注意著里是先在構造函數中resolve了插件。然后再run->init->方法中將命令,通過這里的的apply方法,  // 將插件對應的命令注冊到了service實例。  const builtInPlugins = [   './commands/serve',   './commands/build',   './commands/inspect',   './commands/help',   // config plugins are order sensitive   './config/base',   './config/css',   './config/dev',   './config/prod',   './config/app'  ].map(idToPlugin)    // inlinePlugins與非inline得處理。默認生成的項目直接運行時候,除了上述數組的插件['./commands/serve'...]外,還會有  // ['@vue/cli-plugin-babel','@vue/cli-plugin-eslint','@vue/cli-service']。  // 處理結果是兩者的合并,細節省略。  if (inlinePlugins) {    //...  } else {    //...默認走這條路線   plugins = builtInPlugins.concat(projectPlugins)  }  // Local plugins 處理package.json中引入插件的形式,具體代碼省略。  return plugins } async run (name, args = {}, rawArgv = []) {  // mode是dev還是prod?  const mode = args.mode || (name === 'build' && args.watch ? 'development' : this.modes[name])  // 收集環境變量、插件、用戶配置  this.init(mode)  args._ = args._ || []  let command = this.commands[name]  if (!command && name) {   error(`command "${name}" does not exist.`)   process.exit(1)  }  if (!command || args.help) {   command = this.commands.help  } else {   args._.shift() // remove command itself   rawArgv.shift()  }  // 執行命令。例如vue-cli-service serve 則,執行serve命令。  const { fn } = command  return fn(args, rawArgv) } // 收集vue.config.js中的用戶配置。并以對象形式返回。 loadUserOptions () {  // 此處代碼省略,可以簡單理解為  // require(vue.config.js)  return resolved }}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 望江县| 鹤庆县| 禹州市| 清徐县| 鄂温| 屯留县| 融水| 丰城市| 津市市| 五家渠市| 凤台县| 梁河县| 潍坊市| 渝中区| 独山县| 新宁县| 会同县| 福清市| 昌黎县| 华蓥市| 乌兰察布市| 高平市| 兴城市| 平南县| 宁德市| 施秉县| 德昌县| 高要市| 荆门市| 潜江市| 五指山市| 民丰县| 威远县| 民权县| 内丘县| 肥城市| 富源县| 鄯善县| 阜平县| 甘洛县| 灵山县|