vue-element-admin
是一款优秀的前端框架,使用了最新的前端技术,内置了(Vue-i18)
国际化解决方案,动态路由(Vue Route)
、状态管理(Vuex)
等等方案使得整个框架结构非常清晰。不仅如此,该框架还有Typescript
的实现版本(vue-typescript-admin-template),具有强制类型约束、接口规范统一等等功能,对今后项目的拓展与模块化、与后端的对接等等方面将起到必不可少的作用。
虽然vue-element-admin
官方也编写了相关的用户指南,不过只是单纯地介绍了如何修改当前项目结构来满足业务需求,并未对项目的代码实现层面做太多的赘述,所以这篇文章就是来从源码的角度,来一步步深入vue-element-admin
框架,了解整个项目的构成,来实现更深度地定制。
vue-element-admin
是一个具有完备功能的示例框架,如果只需要基础框架结构,请使用vue-admin-template
代码入口
根据官方提供的命令在执行npm install
模块安装之后,使用npm run dev
来启动项目。我们来看下这个dev
脚本对应的命令在哪:
// package.json
{
...,
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
...
},
...
}
可以看到dev
脚本启动就是vue-cli-service serve
这个控制台命令,我们进一步跟踪看看:
# vue-cli-service
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../@vue/cli-service/bin/vue-cli-service.js" "$@"
ret=$?
else
node "$basedir/../@vue/cli-service/bin/vue-cli-service.js" "$@"
ret=$?
fi
exit $ret
从这里就可以看出vue-cli-service serve
其实就是执行了node vue-cli-service.js serve
这个命令。
// vue-cli-service.js
const semver = require('semver')
const {
error } = require('@vue/cli-shared-utils')
const requiredVersion = require('../package.json').engines.node
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)
}
const Service = require('../lib/Service')
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.run(command, args, rawArgv).catch(err => {
error(err)
process.exit(1)
})
到这里就到命令的最后一步了,调用Service
对象的run
方法执行对应的指令。在深入这个run
方法之前,我们来看一下Service
这个对象在初始化的时候做了些什么: