webpack-dev-server使用方法,看完還不會的來找我~

記錄下webpack-dev-server的用法.javascript

首先,咱們來看看基本的webpack.config.js的寫法css

module.exports = {
        entry: './src/js/index.js',
        output: {
            path: './dist/js',
            filename: 'bundle.js'
        }
    }

配置文件提供一個入口和一個出口,webpack根據這個來進行js的打包和編譯工做。雖然webpack提供了webpack --watch的命令來動態監聽文件的改變並實時打包,輸出新bundle.js文件,這樣文件多了以後打包速度會很慢,此外這樣的打包的方式不能作到hot replace,即每次webpack編譯以後,你還須要手動刷新瀏覽器。html

webpack-dev-server其中部分功能就能克服上面的2個問題。webpack-dev-server主要是啓動了一個使用expressHttp服務器。它的做用主要是用來伺服資源文件。此外這個Http服務器client使用了websocket通信協議,原始文件做出改動後,webpack-dev-server會實時的編譯,可是最後的編譯的文件並無輸出到目標文件夾,即上面配置的:前端

output: {
        path: './dist/js',
        filename: 'bundle.js'
    }

注意:你啓動webpack-dev-server後,你在目標文件夾中是看不到編譯後的文件的,實時編譯後的文件都保存到了內存當中。所以不少同窗使用webpack-dev-server進行開發的時候都看不到編譯後的文件java

下面來結合webpack的文檔和webpack-dev-server裏部分源碼來講明下如何使用:node

啓動

啓動webpack-dev-server有2種方式:react

  1. 經過cmd linewebpack

  2. 經過Node.js APIgit

配置

我主要講解下cmd line的形式,Node.js API形式你們去看下官方文檔。可經過npm script進行啓動。個人目錄結構是:github

app
    |__dist
    |   |__styles
    |   |__js
    |       |__bundle.js
    |   |__index.html
    |__src
    |   |__styles
    |   |__js
    |       |__index.js
    |__node_modules
    |__package.json
    |__webpack.config.js

content-base

設定webpack-dev-server伺服的directory。若是不進行設定的話,默認是在當前目錄下。

webpack-dev-server --content-base ./dist

這個時候還要注意的一點就是在webpack.config.js文件裏面,若是配置了outputpublicPath這個字段的值的話,在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裏面沒有配置outputpublicPath的話,那麼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>

Automatic Refresh

webpack-dev-server支持2種自動刷新的方式:

  • Iframe mode

  • inline mode

這2種模式配置的方式和訪問的路徑稍微有點區別,最主要的區別仍是Iframe mode是在網頁中嵌入了一個iframe,將咱們本身的應用注入到這個iframe當中去,所以每次你修改的文件後,都是這個iframe進行了reload

經過查看webpack-dev-server的源碼,lib路徑下的Server.js文件,第38-48行,分別新建幾個流,這幾個流保存了client文件夾下的相關文件:

// Prepare live html page
    var livePage = this.livePage = new StreamCache();
    fs.createReadStream(path.join(__dirname, "..", "client", "live.html")).pipe(livePage);

    // Prepare the live js file
    var liveJs = new StreamCache();
    fs.createReadStream(path.join(__dirname, "..", "client", "live.bundle.js")).pipe(liveJs);

    // Prepare the inlined js file
    var inlinedJs = new StreamCache();
    fs.createReadStream(path.join(__dirname, "..", "client", "index.bundle.js")).pipe(inlinedJs);
// Init express server
    var app = this.app = new express();

    // middleware for serving webpack bundle
    this.middleware = webpackDevMiddleware(compiler, options);

    app.get("/__webpack_dev_server__/live.bundle.js", function(req, res) {
        res.setHeader("Content-Type", "application/javascript");
        liveJs.pipe(res);
    });

    app.get("/webpack-dev-server.js", function(req, res) {
        res.setHeader("Content-Type", "application/javascript");
        inlinedJs.pipe(res);
    });

    app.get("/webpack-dev-server/*", function(req, res) {
        res.setHeader("Content-Type", "text/html");
        this.livePage.pipe(res);
    }.bind(this));

當使用Iframe mode時,請求/webpack-dev-server/index.html路徑時,會返回client/index.html文件,這個文件的內容就是:

<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/><script type="text/javascript" charset="utf-8" src="/__webpack_dev_server__/live.bundle.js"></script></head><body></body></html>

這個頁面會請求live.bundle.js,其中裏面會新建一個Iframe,你的應用就被注入到了這個Iframe當中。同時live.bundle.js中含有socket.ioclient代碼,這樣它就能和webpack-dev-server創建的http server進行websocket通信了。並根據返回的信息完成相應的動做。

Inline-mode,是webpack-dev-server會在你的webpack.config.js的入口配置文件中再添加一個入口,

module.exports = {
        entry: {
            app: [
                'webpack-dev-server/client?http://localhost:8080/',
                './src/js/index.js'
            ]
        },
        output: {
            path: './dist/js',
            filename: 'bundle.js'
        }
    }

這樣就完成了將inlinedJS打包進bundle.js裏的功能,同時inlinedJS裏面也包含了socket.ioclient代碼,能夠和webpack-dev-server進行websocket通信。

固然你也能夠直接在你index.html引入這部分代碼:

<script src="http://localhost:8080/webpack-dev-server.js"></script>

不過Iframe modeInline mode最後達到的效果都是同樣的,都是監聽文件的變化,而後再將編譯後的文件推送到前端,完成頁面的reload的。

Iframe mode

Iframe modecmd line不須要添加其餘的內容,瀏覽器訪問的路徑是:

localhost:8080/webpack-dev-server/index.html。

這個時候這個頁面的header部分會出現整個reload消息的狀態。當時改變源文件的時候,便可以完成自動編譯打包,頁面自動刷新的功能。

圖片描述

Inline mode

使用inline mode的時候,cmd line須要寫成:

webpack-dev-server --inline --content-base ./dist

這個時候訪問的路徑是:

localhost:8080/index.html

也能完成自動編譯打包,頁面自動刷新的功能。可是沒有的header部分的reload消息的顯示,不過在控制檯中會顯示reload的狀態。

圖片描述

Hot Module Replacement

開啓Hot Module Replacement功能,在cmd line裏面添加--hot

webpack-dev-server --hot --inline --content-base ./dist

其餘配置選項

--quiet 控制檯中不輸出打包的信息
--compress 開啓gzip壓縮
--progress 顯示打包的進度

還有一切其餘的配置信息能夠查閱官方文檔:

webpack-dev-server-cli

這是個人package.json的文件:

{
  "name": "reptile",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack-dev-server --devtool eval-source-map --progress --colors --hot --inline --content-base ./dist",
    "build": "webpack --progress --colors"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.13.2",
    "babel-loader": "^6.2.5",
    "babel-preset-es2015": "^6.13.2",
    "babel-preset-react": "^6.11.1",
    "css-loader": "^0.23.1",
    "react": "^15.3.1",
    "react-dom": "^15.3.1",
    "style-loader": "^0.13.1",
    "webpack": "^1.13.2",
    "webpack-dev-server": "^1.14.1"
  }
}

首先命令行:輸入 npm install 全部依賴。而後輸入npm run dev。在瀏覽器中打開localhost:8080/index.html,而後就能夠愉快的開發咯。

本地搭建API Server

若是你在本地還啓動了一個api server,port爲3000,這個server主要和你的前端應用進行數據交互。這個時候很顯然會出現跨域的問題,那麼這個時候,你前端應用的入口文件應當是用你本身啓動的api server提供的。

var express = require('express');
    var app = express();
    
    app.get('/', function(req, res) {
        res.send('xxx/xxx/index.html'); //這個地方填寫dist/index.html的路徑
    })

此外webpack.config.js:

module.exports = {
        entry: './src/js/index.js',
        output: {
            path: './dist/js',
            filename: 'bundle.js',
            publicPath: 'localhost:8080/dist'
        },
        devServer: {
            '/get': {
                targer: 'localhost:3000',
                secure: false
            }
        }
    }

publicPath字段的內容配置爲絕對路徑。同時index.html文件中對js引用的路徑也改成絕對路徑

<script src="localhost:8080/dist/bundle.js"></script>

若是對web-dev-server還有其餘問題的話,請留言告知。

另外2篇關於webpack的文章:

webpack1.x分包及異步加載套路
webpack2分包及異步加載套路

相關文章
相關標籤/搜索