搭建一個webpack微服務器

 

[前言]:由於最近在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:html

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的配置屬性 vue

1.devServer.contentBase
contentBase是咱們今天要講的第一個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.port
port配置屬性指定了開啓服務的端口號:
devServer: {
   port:7000
}
設置端口號爲7000:
運行:node_modules/.bin/webpack-dev-server
這個時候就不是默認的8080的端口了,而是咱們設置的7000
 
3.devServer.host
host設置的是服務器的主機號:
修改配置爲:
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:truenode

第一次編譯同上
第二次編譯什麼都不輸出
【吐槽】這樣看的話感受這個配置好像只有負面做用呢.....
 
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:true
2增長一個插件配置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);
相關文章
相關標籤/搜索