本文系統講解vue-cli腳手架build目錄中的dev-server.js配置文件
1.這個配置文件是命令npm run dev 和 npm run start 的入口配置文件,主要用于開發環境
2.由于這是一個系統的配置文件,將涉及很多的模塊和插件,所以這部分內容我將分多個文章講解,請關注我博客的其他文章
3.關于注釋 •當涉及到較復雜的解釋我將通過標識的方式(如(1))將解釋寫到單獨的注釋模塊,請自行查看
4.上代碼
// 導入check-versions.js文件,并且執行導入的函數,用來確定當前環境node和npm版本是否符合要求// 關于check-versions請查看我博客check-versions的相關文章require('./check-versions')()// 導入config目錄下的index.js配置文件,此配置文件中定義了生產和開發環境中所要用到的一些參數// 關于index.js的文件解釋請看我博客的index.js的相關文章var config = require('../config')// 下面表示如果如果沒有定義全局變量NODE_ENV,則將NODE_ENV設置為"development"if (!process.env.NODE_ENV) { process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)}// opn插件是用來打開特定終端的,此文件用來在默認瀏覽器中打開鏈接 opn(url)var opn = require('opn')// nodejs路徑模塊var path = require('path')// nodejs開發框架express,用來簡化操作,有興趣可以自行去了解var express = require('express')// 引入webpack模塊,用來使用webpack內置插件var webpack = require('webpack')// 引入http-proxy-middleware插件,此插件是用來代理請求的只能用于開發環境,目的主要是解決跨域請求后臺apivar proxyMiddleware = require('http-proxy-middleware')// 下面的意思是指,如果不是testing環境就引入webpack.dev.conf.js配置文件// 關于webpack.dev.conf.js配置文件請關注我的相關文章,建議現在就去看,否則后面看著吃力var webpackConfig = process.env.NODE_ENV === 'testing' ? require('./webpack.prod.conf') : require('./webpack.dev.conf')// default port where dev server listens for incoming traffic// 下面是webpack-dev-server 監聽的端口號,因為沒有設置process.env.PORT,所以下面監聽的就是config.dev.port即8080var port = process.env.PORT || config.dev.port // automatically open browser, if not set will be false// 下面是true,至于為啥,本來就是true還要加!!兩個感嘆號,估計是vue作者裝了個逼吧var autoOpenBrowser = !!config.dev.autoOpenBrowser // Define HTTP proxies to your custom API backend // https://github.com/chimurai/http-proxy-middleware// 下面是解決開發環境跨域問題的插件,我在config目錄index.js文章中有介紹,自行查看var proxyTable = config.dev.proxyTable// 下面是創建node.js的express開發框架的實例,別問我為什么這樣,自己看node.js去吧var app = express()// 把配置參數傳遞到webpack方法中,返回一個編譯對象,這個編譯對象上面有很多屬性,自己去看吧,主要是用到里面的狀態函數 如compilation,compile,after-emit這類的var compiler = webpack(webpackConfig)// 下面是webpack-dev-middleware和webpack-hot-middleware兩兄弟,這兩個是黃金組合// 而vue作者用這兩個插件也是用的最基本的形式,詳情看(1) (2)var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, quiet: true // 使用friendly-errors-webpack-plugin插件這個必須設置為true,具體看我的wepback-dev-config.js})var hotMiddleware = require('webpack-hot-middleware')(compiler, { log: () => {} // 使用friendly-errors-webpack-plugin插件這個必須設置為true,具體看我的wepback-dev-config.js }) // force page reload when html-webpack-plugin template changescompiler.plugin('compilation', function(compilation) { // webpack任何一個插件都plugin這個方法,里面可以傳遞鉤子函數,用來在插件各個階段做特殊處理,鉤子函數種類很多 compilation.plugin('html-webpack-plugin-after-emit', function(data, cb) { // 當插件html-webpack-plugin產出完成之后,強制刷新瀏覽器 hotMiddleware.publish({ action: 'reload' }) cb() })})// proxy api requestsObject.keys(proxyTable).forEach(function(context) { // 下面是代理表的處理方法,看看就行了,幾乎用不上,除非你是全棧,不用webpack-dev-server,使用后臺語言做服務器 var options = proxyTable[context] if (typeof options === 'string') { options = { target: options } } app.use(proxyMiddleware(options.filter || context, options))})// handle fallback for HTML5 history API// 這個插件是用來解決單頁面應用,點擊刷新按鈕和通過其他search值定位頁面的404錯誤// 詳情請看(3)app.use(require('connect-history-api-fallback')())// serve webpack bundle output// app.use是在響應請求之前執行的,用來指定靜態路徑,掛載靜態資源app.use(devMiddleware)// enable hot-reload and state-preserving// compilation error displayapp.use(hotMiddleware)// serve pure static assets// 下面的staticPath是 static ,path.posix.join其他配置文件中我已經介紹了,這里不再贅述var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)// 掛載靜態資源,下面的方法是用虛擬目錄來訪問資源,staticPath就是虛擬目錄路徑,其實不管設不設置都是staticapp.use(staticPath, express.static('./static'))// 下面結果就是 'http://localhost:8080'var uri = 'http://localhost:' + port// 下面是es6的promise規范,用來處理嵌套請求的var _resolvevar readyPromise = new Promise(resolve => { _resolve = resolve // resolve是一個回調函數專門用來傳遞成功請求的數據})// 下面是加載動畫console.log('> Starting dev server...')// waitUntilValid是webpack-dev-middleware實例的方法,在編譯成功之后調用devMiddleware.waitUntilValid(() => { console.log('> Listening at ' + uri + '/n') // when env is testing, don't need open it // 測試環境不打開瀏覽器 if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { opn(uri) } _resolve() // 這里沒有傳遞數據,這只是在模擬})// node.js監聽端口var server = app.listen(port)// 這個導出對象是用來對外提供操作服務器和接受數據的接口,vue作者可謂考慮頗深啊module.exports = { ready: readyPromise, // promise實例,可以通過readyPromise.then收到數據 close: () => { server.close() // 關閉服務器 }}
新聞熱點
疑難解答
圖片精選