這篇文章主要介紹了vue-cli-server怎么使用的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇vue-cli-server怎么使用文章都會有所收獲,下面我們一起來看看吧。
一、入口
我們可以在package.json中看到npm run dev
其實就是vue-cli-service serve
,我們在安裝vue-cli
的時候可以一并將我們的vue-cli-service
一同安裝,然后執行npm install vue-cli-service --save-dev
這樣就可以在./node_modules/.bin
目錄下查看到vue-cli-service
,相關代碼如下:
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\@vue\cli-service\bin\vue-cli-service.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\@vue\cli-service\bin\vue-cli-service.js" %*
)
入口路徑:./node_modules/@vue/cli-service/bin/vue-cli-service.js
。
我們還可以去看下我們的vue-cli-service.js
核心代碼,如下所示:
const Service = require('../lib/Service')
// 實例化Service
// VUE_CLI_CONTEXT為undefined,所以傳入的值為process.cwd()及項目所在目錄
const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
const rawArgv = process.argv.slice(2)
// minimist解析工具來對命令行參數進行解析
const args = require('minimist')(rawArgv, {
boolean: [
// build
'modern',
'report',
'report-json',
'watch',
// serve
'open',
'copy',
'https',
// inspect
'verbose'
]
})
// {
// _: [ 'serve' ],
// modern: false,
// report: false,
// 'report-json': false,
// watch: false,
// open: false,
// copy: false,
// https: false,
// verbose: false ,
// }
const command = args._[0]
// 執行service方法傳入:'serve'、agrs、['serve','--open',...]
service.run(command, args, rawArgv).catch(err => {
error(err)
process.exit(1)
})
二、初始化配置
代碼如下:
module.exports = class Service {
constructor (context, { plugins, pkg, inlineOptions, useBuiltIn } = {}) {
process.VUE_CLI_SERVICE = this
this.initialized = false
this.context = context
this.inlineOptions = inlineOptions
this.webpackChainFns = []
this.webpackRawConfigFns = []
this.devServerConfigFns = []
this.commands = {}
this.pkgContext = context
// 獲取package.json中的依賴
this.pkg = this.resolvePkg(pkg)
// 如果有內聯插件,不使用package.json中找到的插件
// 最終得到的plugins為內置插件+@vue/cli-plugin-*
// {id: 'xxx',apply: require('xxx')}
this.plugins = this.resolvePlugins(plugins, useBuiltIn)
// 解析每個命令使用的默認模式
//{ serve: 'development',
// build: 'production',
// inspect: 'development' }
this.modes = this.plugins.reduce((modes, { apply: { defaultModes }}) => {
return Object.assign(modes, defaultModes)
}, {})
}
// ......
}
我們通過獲取package.json中的依賴,通過read-pkg這個包來讀取我們的package.json文件,并且通過json格式返回賦值給我們的this.pkg;之后初始化相關的插件。代碼如下:
resolvePlugins (inlinePlugins, useBuiltIn) {
const idToPlugin = id => ({
id: id.replace(/^.\//, 'built-in:'),
apply: require(id)
})
let plugins
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)
if (inlinePlugins) {
// ...
} else {
// 開發環境依賴+生產環境的依賴中,獲取cli-plugin-*插件
const projectPlugins = Object.keys(this.pkg.devDependencies || {})
.concat(Object.keys(this.pkg.dependencies || {}))
.filter(isPlugin) // 驗證是否為vue-cli插件 cli-plugin-*
.map(idToPlugin)
plugins = builtInPlugins.concat(projectPlugins)
}
// ...
}
1、通過初始化模式,從而解析每個命令,代碼如下:
// 解析每個命令使用的默認模式
//{ serve: 'development',
// build: 'production',
// inspect: 'development' }
this.modes = this.plugins.reduce((modes, { apply: { defaultModes }}) => {
return Object.assign(modes, defaultModes)
}, {})
之后在內聯插件默認到處defaultModes
這個文件如下所示:
// serve.js
module.exports.defaultModes = {
serve: 'development'
}
三、解析命令參數
我們在這邊通過minimist
解析工具來對命令行參數進行解析,如下所示:
const args = require('minimist')(rawArgv, {
boolean: [
// build
// serve
'open',
'copy',
'https',
]
})
// 'serve'、agrs、['serve','--open',...]
四、加載插件
我們可以通過運行service.run方法,加載環境變量,加載用戶配置,應用插件,代碼如下:
async run (name, args = {}, rawArgv = []) {
const mode = args.mode || (name === 'build' && args.watch ? 'development' : this.modes[name])
// 加載環境變量,加載用戶配置,應用插件
this.init(mode)
args._ = args._ || []
// 注冊完的命令集里獲取對應的命令
let command = this.commands[name]
// ....
const { fn } = command
return fn(args, rawArgv)
}
1、加載環境變量,我們從項目中的根目錄下的.env.(mode)
文件讀取環境變量,并寫入到process.env
(聲明環境變量必須是VUE_APP_*,不然會被過濾掉)代碼如下:
init (mode = process.env.VUE_CLI_MODE) {
// 加載development.env環境變量
if (mode) {
this.loadEnv(mode)
}
this.loadEnv()
// ...
}
// 加載環境變量方法(部分)
loadEnv (mode) {
// 項目路徑/.env.development
const basePath = path.resolve(this.context, `.env${mode ? `.${mode}` : ``}`)
// 項目路徑/.env.development.local
const localPath = `${basePath}.local`
const load = path => {
const env = dotenv.config({ path, debug: process.env.DEBUG })
// 這里會先調用 dotenv(位于 node_modules/dotenv )的 config 函數,最終會返回這樣的格式 { parsed: { YOUR_ENV_KEY: '你設定的環境變量值' } },并且寫入到process.env里面
dotenvExpand(env)
logger(path, env)
}
load(localPath)
load(basePath)
if (mode) {
const defaultNodeEnv = (mode === 'production' || mode === 'test')
? mode
: 'development'
if (shouldForceDefaultEnv || process.env.NODE_ENV == null) {
process.env.NODE_ENV = defaultNodeEnv
}
}
}
2、加載用戶配置
我們這個步驟通過讀取vue.config.js文件內部的配置就可以了,代碼如下:
init (mode = process.env.VUE_CLI_MODE) {
// 加載用戶配置
const userOptions = this.loadUserOptions()
this.projectOptions = defaultsDeep(userOptions, defaults())
}
3、應用插件
//const idToPlugin = id => ({
// id: id.replace(/^.\//, 'built-in:'),
// apply: require(id)
//})
init (mode = process.env.VUE_CLI_MODE) {
// 應用插件
this.plugins.forEach(({ id, apply }) => {
apply(new PluginAPI(id, this), this.projectOptions)
})
// 從項目配置文件中應用webpack配置
if (this.projectOptions.chainWebpack) {
this.webpackChainFns.push(this.projectOptions.chainWebpack)
}
if (this.projectOptions.configureWebpack) {
this.webpackRawConfigFns.push(this.projectOptions.configureWebpack)
}
}
}
通過前面初始化插件的時候(resolvePlugins方法)有一個apply屬性,調用這個方法就可以導入對應的插件,這里就是調用了serve.js的方法。
4、注冊命令
我們在在service注冊serve命令,代碼如下:
// serve.js
api.registerCommand('serve', {
description: 'start development server',
usage: 'vue-cli-service serve [options] [entry]',
options: {}
}, async function serve (args) {
// ...
});
五、配置啟動服務
最后我們通過執行的serve.js 內注冊serve時傳遞的方法。然后等webpack
獲取到配置之后,在通過實例化Compiler
傳遞給webpackDevServer
,通過webpackDevServer
實現自動編譯和更新,代碼如下:
// serve.js serve函數
async function serve (args) {
//創建webpack編譯器
const compiler = webpack(webpackConfig)
// compiler.run()即可完成一次編譯打包
// 創建本地服務
const server = new WebpackDevServer(compiler, Object.assign({
clientLogLevel: 'none',
historyApiFallback: {
disableDotRule: true,
rewrites: [
{ from: /./, to: path.posix.join(options.baseUrl, 'index.html') }
]
},
contentBase: api.resolve('public'),
watchContentBase: !isProduction,
hot: !isProduction,
quiet: true,
compress: isProduction,
publicPath: options.baseUrl,
overlay: isProduction // TODO disable this
? false
: { warnings: false, errors: true }
}, projectDevServerOptions, {
https: useHttps,
proxy: proxySettings,
}))
return new Promise((resolve, reject) => {
compiler.hooks.done.tap('vue-cli-service serve', stats => {
// ...
})
// ...
server.listen(port, host, err => {
if (err) {
reject(err)
}
})
})
}
我們在這里獲取了webpack
配置:api.resolveWebpackConfig()
,之后在通過獲取 devServer
配置 注入 webpack-dev-server
和 hot-reload(HRM)
的中間件入口從而創建 webpack-dev-server
實例
,而且在啟動webpack-dev-server后,在目標文件夾中是看不到編譯后的文件的,實時編譯后的文件都保存到了內存當中。
關于“vue-cli-server怎么使用”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“vue-cli-server怎么使用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。