一、概述
開發項目中為了保證上線,開發項目是都需要使用localhost進行開發,以前的做法就是本地搭建Apache或者Tomcat服務器。有的前端開發人員 對服務器的搭建和配置並不熟悉,這個時候需要后台開發人員進行幫忙,有的時候后台開發人員還愛答不理的。為了解決這個愛答不理的問題,webpack-dev-server出現了,它的出現告訴后台開發人員,不用你們了。
webpack-dev-server的作用不只是搭建本地服務器,大家知道使用webpack可以 進行監聽和打包文件,但是如果文件比較多,webpack執行會非常的慢,webpack-dev-server就可以解決 慢的問題。另一方面,webpack-dev-server可以進行瀏覽器的實時刷新, 避免了修改代碼手動執行刷新功能。
webpack-dev-server其中部分功能就能克服上面的2個問題。webpack-dev-server主要是啟動了一個使用express的Http服務器。它的作用主要是用來伺服資源文件。此外這個Http服務器和client使用了websocket通訊協議,原始文件作出改動后,webpack-dev-server會實時的編譯。
注意:啟動webpack-dev-server后,在目標文件夾中是看不到編譯后的文件的,實時編譯后的文件都保存到了內存當中。因此很多同學使用webpack-dev-server進行開發的時候都看不到編譯后的文件。
二、webpack-dev-server 安裝
由於webpack-dev-server和webpack不是一個資源包,所以,需要單獨安裝webpack-dev-server資源包:
全局安裝
npm install webpack-dev-server -g
項目安裝
npm install webpack-dev-server --save-dev
這里建議進行項目安裝,這樣別人開發的時候只需要執行npm install 命令就能安裝了,沒有必須單獨進行 全局安裝了。
三、webpack-dev-server 服務器
首先我們看一下 都有哪些參數可選項:
--content-base //設定webpack-dev-server的director根目錄。如果不進行設定的話,默認是在當前目錄下。
--quiet: //控制台中不輸出打包的信息,開發中一般設置為false,進行 打印,這樣查看錯誤比較方面
--no-info: // 不顯示任何信息
--colors: //對信息進行顏色輸出
--no-colors: //對信息不進行顏色輸出
--compress: //開啟gzip壓縮
--host <hostname/ip>: //設置ip
--port <number>: //設置端口號,默認是:8080
--inline: //webpack-dev-server會在你的webpack.config.js的入口配置文件中再添加一個入口,
--hot: //開發熱替換
--open: //啟動命令,自動打開瀏覽器
--history-api-fallback: //查看歷史url
這里只是列舉一下常用了的,相關的參數可以查看:http://webpack.github.io/docs/webpack-dev-server.html#webpack-dev-server-cli
1、content-base
設定webpack-dev-server的根目錄。如果不進行設定的話,默認是在當前目錄下。
webpack-dev-server --content-base ./assets
這個時候還要注意的一點就是在webpack.config.js文件里面,如果配置了output的publicPath這個字段的值的話,在index.html文件里面也應該做出調整。因為webpack-dev-server的根目錄是相對publicPath這個路徑的。因此,如果你的webpack.config.js配置成這樣的:
module.exports = { entry: './src/js/index.js', output: { path: './dist/js', filename: 'bundle.js', publicPath: '/assets/' } }
那么,在index.html文件當中引入的路徑也發生相應的變化:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<script src="assets/bundle.js"></script>
</body>
</html>
如果在webpack.config.js里面沒有配置output的publicPath的話,那么index.html最后引入的文件js文件路徑應該是下面這樣的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
直接在命令行執行一下命令,就可以啟動服務器:
webpack-dev-server --content-base ./assets
四、webpack-dev-server 的熱替換
webpack-dev-server支持2種自動刷新的方式:
-
Iframe mode, webpack-dev-server默認的刷新模式
-
inline mode
1、Iframe mode
Iframe mode刷新模式是在網頁中嵌入了一個iframe,將我們自己的應用注入到這個iframe當中去,因此每次你修改的文件后,都是這個iframe進行了reload。
啟動Iframe mode刷新模式直接使用命令就可以啟動了:
webpack-dev-server --content-base ./dist
瀏覽器訪問的路徑是:
localhost:8080/webpack-dev-server/index.html。
2、Inline-mode
Inline-mode刷新模式是直接刷新頁面,不會在頁面增減任何的元素或者js插件,它是直接放在內存中,這種方式也是官方推薦的,並且速度相對來說比較快。實現Inline-mode刷新模式 有很多的方法,下面我們來列舉一下:
方法一:將代碼內聯到入口配置文件webpakc.config.js文件entry屬性里面,並且添加new webpack.HotModuleReplacementPlugin()熱點插件
var webpack = require('webpack'); var WebpackDevServer = require("webpack-dev-server"); module.exports = { //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字
entry: [ 'webpack-dev-server/client?http://localhost:8080/', './src/index.js' ], //輸出的文件名,合並以后的js會命名為bundle.js
output: { path: path.join(__dirname, "dist/"), publicPath: "http://localhost:8088/dist/", filename: "bundle.js" }, plugins: [ new webpack.HotModuleReplacementPlugin() ] };
這種方式比較容易,但是不夠靈活,需要添加相關的熱點插件。
方法二、直接在你index.html引入這部分代碼:
<script src="http://localhost:8080/webpack-dev-server.js"></script>
這種方法更不好,項目上線還需要手動刪除,堅決杜絕這些方法。
方法三、直接實現一個server.js,啟動服務器(需要啟動熱替換plugin)
var webpack = require('webpack'); var webpackDevMiddleware = require("webpack-dev-middleware"); var webpackDevServer = require('webpack-dev-server'); var config = require("./webpack.config.js"); config.entry.index.unshift("webpack-dev-server/client?http://localhost:9000"); // 將執替換js內聯進去
config.entry.index.unshift("webpack/hot/only-dev-server"); var compiler = webpack(config); var server = new webpackDevServer(compiler, { hot: true, historyApiFallback: false, // noInfo: true,
stats: { colors: true // 用顏色標識
}, proxy: { "*": "http://localhost:9000" // 用於轉發api數據,但webpack自己提供的並不太好用
}, }); server.listen(9000);
方法四、直接在webpack.config.js上配置。這個辦法最簡單,當然靈活性沒有自己實現一個服務器好。
var webpack = require('webpack'); var WebpackDevServer = require("webpack-dev-server"); var path = require('path'); var CURRENT_PATH = path.resolve(__dirname); // 獲取到當前目錄
var ROOT_PATH = path.join(__dirname, '../'); // 項目根目錄
var MODULES_PATH = path.join(ROOT_PATH, './node_modules'); // node包目錄
var BUILD_PATH = path.join(ROOT_PATH, './dist'); // 最后輸出放置公共資源的目錄
//用於提取多個入口文件的公共腳本部分,然后生成一個 common.js 來方便多頁面之間進行復用
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); module.exports = { //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字
entry: [ './src/index.js' ], //輸出的文件名,合並以后的js會命名為bundle.js
output: { path: path.join(__dirname, "dist/"), publicPath: "http://localhost:8088/dist/", filename: "bundle.js" }, devServer: { historyApiFallback: true, contentBase: "./", quiet: false, //控制台中不輸出打包的信息
noInfo: false, hot: true, inline: true, lazy: false, progress: true, //顯示打包的進度
watchOptions: { aggregateTimeout: 300 }, port: '8088' } };
五、配置webpackDemo項目本地 服務器
上面我們講解了webpack-dev-server 搭建本地服務以及瀏覽器實時刷新的相關方法和配置,我們選擇方法四 直接在webpack.config.js使用devServer配置服務器以及熱點替換。內容如下:
var webpack = require('webpack'); var WebpackDevServer = require("webpack-dev-server"); var path = require('path'); var CURRENT_PATH = path.resolve(__dirname); // 獲取到當前目錄
var ROOT_PATH = path.join(__dirname, '../'); // 項目根目錄
var MODULES_PATH = path.join(ROOT_PATH, './node_modules'); // node包目錄
var BUILD_PATH = path.join(ROOT_PATH, './dist'); // 最后輸出放置公共資源的目錄
//用於提取多個入口文件的公共腳本部分,然后生成一個 common.js 來方便多頁面之間進行復用
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js'); module.exports = { //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字
entry: [ './src/index.js' ], //輸出的文件名,合並以后的js會命名為bundle.js
output: { path: path.join(__dirname, "dist/"), publicPath: "http://localhost:8088/dist/", filename: "bundle.js" }, devServer: { historyApiFallback: true, contentBase: "./", quiet: false, //控制台中不輸出打包的信息
noInfo: false, hot: true, inline: true, lazy: false, progress: true, //顯示打包的進度
watchOptions: { aggregateTimeout: 300 }, port: '8088' } };
這個時候index.html內容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="dist/bundle.js"></script>
</head>
<body>
<h1>welcome to 68kejian.com</h1>
</body>
</html>
然后在命令行執行一下操作啟動 服務:
webpack-dev-server --hot --inline
在瀏覽器輸入:localhost:8088, 這里我們設置的端口號是:8088
這個時候隨意修改login.js的userName的值,看看頁面是不是刷新了。