標籤:compress script 主機 壓縮 image lin 消失 back 負載
[前言]:因為最近在vue2.0的時候用到了webpack的externals,才發現我之前都只是用webpack做一些搭建完項目後的“收尾工作”——即打包,而沒有把它納入到項目開發的“主體過程”中來,真是“物不盡其用”。於是就有了我今天的這篇學習文章:
利用webpack-dev-server搭建一個webpack的伺服器
參考資料:
webpack-dev-server的github地址:
https://github.com/webpack/webpack-dev-server
webpack1官方文檔http://webpack.github.io/docs/webpack-dev-server.html(推薦看2的文檔)
webpack2官方文檔https://webpack.js.org/configuration/dev-server/#devserver(推薦讀這個)
提綱:1.複習webpack的知識2.詳解webpack-dev-server的配置屬性3.webpack-dev-server的自動重新整理和模組熱替換機制4.webpack下設定管理員的三種方式
複習一下webpack的知識 我將目錄結構簡化之後長這樣: 我的webpack.config.js:
var webpack = require(‘webpack‘)var path =require(‘path‘)module.exports = {entry:{ app:path.join(__dirname,‘src‘,‘index.js‘)},output:{ filename:‘bundle.js‘, path:path.join(__dirname,‘dist‘) }}
我的src/index.js:
require(‘./a.js‘)require(‘./b.js‘)console.log(‘我是index.js‘)
我的src/a.js:
console.log(‘我是a.js‘)
我的src/b.js:
console.log(‘我是b.js‘)
我的dist/index.html:
/*其他部分省略*/<body> <script src="./bundle.js"></script></body>
當我們在終端運行“webpack”命令後,目錄變為:
一張圖複習一下webpack的機制:
OK,下面,讓我們開始搭建一個伺服器吧:
怎麼用最簡單的方式搭建一個伺服器?
1.你需要一個安裝一個模組在終端中進入項目目錄下,敲下npm install webpack-dev-server --save-dev斷行符號
2.在終端運行一段命令:node_modules/.bin/webpack-dev-server(網上有的說直接輸webpack-dev-server那是錯的) 成功!輸出的是這一段資訊:
然後進入預設的localhost:8080頁面:伺服器的根目錄就是我們工程的目錄 到這裡,我們要做的第一步就成功啦! 進入dist後,我們發現報了這樣一段錯誤:what?沒有找到bundle.js? 所以我們要在webpack.config.js裡寫一下配置:
module.exports = {/*這裡省略entry和output,參照上面寫的內容*/ devServer: { contentBase: path.join(__dirname, "dist") }}儲存,後開啟頁面看控制台,報錯已經消失了!正確列印了被打包的檔案內容:
詳解webpack-dev-server的配置屬性
1.devServer.contentBasecontentBase是我們今天要講的第一個webpack-dev-server的配置屬性,那麼,contentBase做了什麼事情呢?——它指定了伺服器資源的根目錄,如果不寫入contentBase的值,那麼contentBase預設是項目的目錄。在上面例子中產生錯誤和後來解決錯誤的原因:產生錯誤:因為bundle.js被
"放在了"我們的項目根目錄裡,在dist/html裡<script src="./bundle.js"></script>此時顯然不能根據路徑找到bundle.js解決錯誤:通過配置contentBase: path.join(__dirname, "dist")將bundle.js
"放在了"dist目錄下,此時bundle.js和dist/index.html位於同一目錄下,通過 src="./bundle.js"自然就找到bundle.js了
webpack打包和webpack-dev-server開啟服務的區別——webpack輸出真實的檔案,而webpack-dev-server輸出的檔案只存在於記憶體中,不輸出真實的檔案!(注意下面兩張圖的區別) webpack:當我們在終端運行"webpack"後:
webpack-dev-server:當我們在終端運行"node_modules/.bin/webpack-dev-server後:這也就是我在上面的闡述中將bundle.js"放在了"加上雙引號的原因
2.devServer.portport配置屬性指定了開啟服務的連接埠號碼:
devServer: { port:7000}設定連接埠號碼為7000:運行:node_modules/.bin/webpack-dev-server這個時候就不是預設的8080的連接埠了,而是我們設定的7000
3.devServer.hosthost設定的是伺服器的主機號:修改配置為:
devServer: { contentBase: path.join(__dirname, "dist"), port:7000, host:‘0.0.0.0‘}
此時localhost:7000和0.0.0.0:7000都能訪問成功
4.devServer.historyApiFallback在文檔裡面說的很清楚,
這個配置屬性是用來應對返回404頁面時定向到特定頁面用的(the index.html page will likely have to be served in place of any 404 responses)在dist目錄下新增一個HTML頁面:
/*剩下的都是很常規的HTML內容,故省略*/<p>這裡是404介面</p>
我們把webpack.config.js修改如下:
module.exports = {/*這裡省略entry和output,參照上面寫的內容*/devServer: {contentBase: path.join(__dirname, "dist"),historyApiFallback:{ rewrites:[ {from:/./,to:‘/404.html‘} ] } }} 開啟頁面,輸入一個不存在的路由地址:
5.devServer.overlay這個配置屬性用來在編譯出錯的時候,在瀏覽器頁面上顯示錯誤,預設是false,可設定為true首先我們人為製造一個編譯錯誤:在我們尚未配置babel loader的項目裡使用ES6寫法:在src/index.js裡寫入“const a”在shell裡提示編譯錯誤: 但在瀏覽器裡沒有提示:所以我們把webpack.config.js修改為:
module.exports = { /*這裡省略entry和output,參照上面寫的內容*/ devServer: { contentBase: path.join(__dirname, "dist"), overlay: true }} 再重新運行node_modules/.bin/webpack-dev-server,瀏覽器上把錯誤顯示出來了
6.devServer.stats(字串) 這個配置屬性用來控制編譯的時候shell上的輸出內容,我們沒有設定devServer.stats時候編譯輸出是這樣子的:(其中看起來有許多看似不重要的檔案也被列印出來了)
stats: "errors-only"表示只列印錯誤:我們把配置改成:
devServer: { contentBase: path.join(__dirname, "dist"), stats: "errors-only"} 因為只有錯誤才被列印,所以,大多數資訊都略過了除此之外還有"minimal","normal","verbose",這裡不多加贅述
7.devServer.quiet當這個配置屬性和devServer.stats屬於同一類型的配置屬性當它被設定為true的時候,控制台只輸出第一次編譯的資訊,
當你儲存後再次編譯的時候不會輸出任何內容,包括錯誤和警告來做個對比吧:
quiet:false(預設):第一次編譯:第二次編譯(當你儲存的時候)
quiet:true
第一次編譯同上第二次編譯什麼都不輸出
【吐槽】這樣看的話感覺這個配置好像只有負面作用呢.....
8.devServer.compress這是一個布爾型的值,當它被設定為true的時候對所有的伺服器資源採用gzip壓縮採用gzip壓縮的優點和缺點:優點:對JS,CSS資源的壓縮率很高,可以極大得提高檔案傳輸的速率,從而提升web效能缺點:服務端要對檔案進行壓縮,而用戶端要進行解壓,增加了兩邊的負載
9.devServer.hot和devServer.inline在這之前,首先要說一下的是webpack-dev-server的自動重新整理和模組熱替換機制
webpack-dev-server的自動重新整理和模組熱替換機制 這兩個機制是緊緊聯絡在一起的
從外部角度看——自動重新整理當我們對業務代碼做了一些修改然後儲存後(command+s),頁面會自動重新整理,我們所做的修改會直接同步處理到頁面上,而不需要我們重新整理頁面,或重新開啟服務(The webpack-dev-server supports multiple modes to automatically refresh the page)
從內部角度看——模組熱替換在熱替換(HMR)機制裡,不是重載整個頁面,HMR程式會只載入被更新的那一部分模組,然後將其注入到運行中的APP中(In Hot Module Replacement, the bundle is notified that a change happened. Rather than a full page reload, a Hot Module Replacement runtime could then load the updated modules and inject them into a running app.)
webpack-dev-server有兩種模式可以實現自動重新整理和模組熱替換機制1. Iframe mode
(預設,無需配置)頁面被嵌入在一個iframe裡面,並且在模組變化的時候重載頁面2.inline mode(需配置)添加到bundle.js中當重新整理頁面的時候,一個小型的用戶端被添加到webpack.config.js的入口檔案中例如在我們的例子中,在使用inline mode的熱替換後,相當於入口檔案從
entry:{ app:path.join(__dirname,‘src‘,‘index.js‘)}變成了:
entry:{ app:[path.join(__dirname,‘src‘,‘index.js‘), ‘webpack-dev-server/client?http://localhost:8080/‘ ]}從一個入口變成了兩個入口,並實現重新整理
那怎麼才能inline mode模式的重新整理呢? 你需要做這些:1在配置中寫入devServer.hot:true和devServer.inline:true2增加一個外掛程式配置webpack.HotModuleReplacementPlugin() 例如:
var webpack = require(‘webpack‘)module.exports = { /*省略entry ,output等內容*/ plugins:[ new webpack.HotModuleReplacementPlugin() ], devServer: { inline:true, hot:true }} 開啟頁面:如果有上面兩行輸出則表明你已經配置成功 現在還有一個問題,那就是每次直接輸入node_modules/.bin/webpack-dev-server來啟動伺服器對我們來說簡直就是莫大的痛苦,那麼怎麼對這一過程進行簡化呢?答案:把這個運行指令碼寫到package.json裡就行了! 這裡我把我的package.json寫成:
{ "name": "webpackTest2", "dependencies": {}, "devDependencies": {}, "scripts": { "start": "node_modules/.bin/webpack-dev-server" }} 在終端運行npm start:運行成功!
佈建服務的三種方式: 1在webpack.config.js輸出對象中的devServer屬性中寫配置(也就是我們上述所有例子的做法) 2寫在package.json中,寫在node 命令對應的指令碼中,例如我們可以寫成:"scripts": {"start": "node_modules/.bin/webpack-dev-server --port 8000 --inline true "}(但這顯然並不是一個值得推薦的方式) 3使用純node的API實現,下面是一個官方給的例子
var config = require("./webpack.config.js");config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");var compiler = webpack(config);var server = new WebpackDevServer(compiler, { /*我們寫入配置的地方*/});server.listen(8080);
搭建一個webpack微伺服器