使用webpack-dev-server提高webpack開發效率

這是webpack系列文章的 【第四期】,希望你在閱讀前已經看過前幾期的文章

如何使用webpack實現模塊化打包

webpack的核心機制之loader的祕密

徹底剖析webpack的plugin插件機制

前言

在前面幾期介紹了webpack的基本概念,用法,流程,loader機制與plugin機制,其實看起來好像已經掌握webpack。但是我們只以這些認知去在實際中開發使用還是遠遠不夠的。

在實際開發中還有一點很重要,那就是效率。通過前面幾期的學習,每次打包都需要經歷以下幾個流程:修改代碼→打包→運行→瀏覽器查看,每當我們進行一次修改都會經歷這一些列操作,這佔用了我們大量的時間,也導致了開發效率降低。

那設想一下一個理想的開發環境什麼樣的呢

  • 可以使用http服務來進行文件預覽,而不是手動的去打開文件
  • 可以訪問靜態資源文件
  • 每次次改完後可以自動打包,並自動刷新瀏覽器
  • 可以使用AJAX之類的API
  • 可以提供 Source Map 支持,可以讓我們在出現錯誤時快速定位到源代碼中的位置,便於調試
    那接下來我們就一項一項的來實現

自動編譯打包

我們之前打包使用的命令是

npx webpack

在webpack cli 中提供了另外一種watch工作模式,在這種模式下,會監聽源文件中的內容,一旦發生任何改動,webpack就會自動重新運行打包任務。我們只需要在啓動webpack時,在後面添加一個–watch參數即可,這樣webpack就會以監視啓動運行。

npx webpack --watch

當啓動監視模式後,webpack在打包完成後不會自動退出,而是繼續監視下一次修改然後重新打包,除非我們手動退出(ctrl + c)。

然後我們可以再打開一個命令行終端,把我們的項目以http的方式運行

npx serve dist


在瀏覽器中輸入localhost:5000即可預覽打包後的項目

到現在我們可以實現修改代碼後自動打包,通過http的形式去預覽,但是每次修改還是需要手動的去刷新瀏覽器。我們希望的是他可以像我們開發VUE項目一樣,具有熱更新的功能。

這裏我們需要藉助一個叫做 BrowserSync 的工具,現在全局進行安裝

npm install browser-sync -g

使用 BrowserSync 工具替換 serve 工具來啓動 http 服務,這裏我們需要監聽的是dist目錄下的變化,一旦dist下的內容發生改變,就需要自動刷新瀏覽器。

browser-sync dist --watch


現在每當我們修改文件保存後,就會自動執行打包,相應的dist文件的內容就會發生改變,BrowserSync 監聽dist改變後自動刷新瀏覽器。

通過上面的 watch模式+BrowserSync 已經可以實現我們的需求,但是這種方法存在很多的弊端:

  • 操作繁瑣,我們每次都需要打開兩個終端來分別實現修改自動打包與自動刷新的操作。
  • 執行效率低,這種方法涉及到大量的磁盤讀寫操作,webpack現將打包後的文件寫入磁盤BrowserSync 再進行讀取,每次都需要這樣反覆流程,必然會降低效率。
    所以我們需要繼續改善

Webpack Dev Server

Webpack Dev Server 是webpack官方推出的一款開發工具,他提供了一個開發服務器,將自動編譯和自動刷新等一系列的功能都集成到了一起。

npm install webpack-dev-server --save


Webpack Dev Server 同樣也是一個獨立的 npm 模塊,它提供了一個叫做webpack-dev-server的CLI程序,我們可以通過npx去直接運行它。

npx webpack-dev-server

它的工作流程是,它的內部會啓動一個HTTP Server,爲打包的結構提供靜態文件服務,並自動使用webpack打包我們的應用,然後監聽源代碼的變化,一旦文件發生變化,它會立即重新打包。

這看起來和之前的流程差不過呀,其實有很大的不同,webpack-dev-server 爲了提高工作速率,它並沒有將打包結果寫入到磁盤中,而是暫時存放在內存中,內部的 HTTP Server 也是從內存中讀取這些文件的。這樣一來,就會減少很多不必要的磁盤讀寫操作,大大提高了整體的構建效率。

我們還可以爲 webpack-dev-server 命令傳入一個 --open 的參數,用於自動喚起瀏覽器打開我們的應用。

npx webpack-dev-server --open

如果只是這樣還完全不能 展示出它的能力,webpack爲我們提供了可配置的選項

module.exports =  {
    devServer:{
        port: 9000,
        contentBase: 'public',
        proxy:{
            '/api':{
                target: 'https://.....'
            },
            pathRewrite:{   //重寫掉開頭的api
                '^/api': ''
            },
            changeOrigin: true   //修改主機名
        }
    }
}

更多的配置可參考官方配置說明:https://webpack.js.org/configuration/dev-server/

這裏我只提出一些常用的配置:

  • port

    指定要偵聽請求的端口號

  • proxy

    由於 webpack-dev-server 是一個本地開發服務器,如果我們要請求其他的地址上的API時,會出現跨域的問題,他的用法與我們在VUE項目中使用proxy是一樣的。

  • contentBase

    訪問靜態資源,通過前面介紹的plugin機制可以知道,我們可以使用copy-webpack-plugins實現對靜態資源的複製打包,也就是說在dist文件中也會包含靜態資源文件。既然這樣我們不是也可以直接訪問嗎,爲什麼要通過contentBase來訪問爲打包前的靜態資源。

還是效率問題,對於copy-webpack-plugins這個插件,我們在開發階段是不會使用的,只有當我們開發完成後進行最終打包的時候纔會引入,在開發階段,如果每次更改都要把靜態資源copy一遍,這顯然會浪費很多時間。contentBase它可以接受一個數組,用來訪問多個不同目錄下的靜態資源,就像下面這樣。


對於 Source Map 的支持將在下期進行講解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章