webpack devServer本地開發(fā)(7)

獲取全套webpack 4.x教程,請訪問瓦力博客

webpack-dev-server是一個用來快速搭建本地運行環(huán)境的工具。在實際開發(fā)中調(diào)試接口需要打http請求,我們用之前的方式本地直接打開html文件是不行的,本地直接打開html文件,在瀏覽器中顯示的協(xié)議是file協(xié)議不是http協(xié)議。

使用devServer的好處:

  • 自動打開瀏覽器頁面
  • 調(diào)試接口
  • 實時刷新
  • 熱更新
  • 使用代理
  • 局域網(wǎng)訪問

1.安裝插件

yarn add webpack-dev-server

2.devServer配置

package.json

{
  "scripts": {
    "dev": "npx webpack-dev-server --mode=development --colors",
    "dist": "npx webpack --mode=production"
  }
}

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');    //生成html文件
const CleanWebpackPlugin = require('clean-webpack-plugin');  //清除



module.exports = {
  mode:'development',
  entry:'./src/index.js',
  module:{
    rules:[
        {
            test:/\.css$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:1
                    }                   
                },
                'postcss-loader'
                
            ]
        },
        {
            test:/\.scss$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'sass-loader',
                'postcss-loader'
            ]
        },
        {
            test: /\.less$/,
            use: [
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'less-loader',
                'postcss-loader'
            ]
        },
        {
            test:/\.(png|svg|jpeg|jpg|gif)$/,
            use:[       
                {
                    loader:'file-loader',
                    options:{
                        name:'[name].[ext]',  //[path] 上下文環(huán)境路徑
                        publicPath:'./assets/image/',    //公共路徑
                        outputPath:'assets/image/',  //輸出路徑                         
                    }
                },
                {
                    loader: 'image-webpack-loader',
                    options: {
                        bypassOnDebug: true, // webpack@1.x
                        disable: true,       // webpack@2.x and newer
                    },
                },
            ]
        },
        {
            test: /\.html$/,
            use:[
                {
                    loader:'html-loader',
                    options:{
                        arrts:['img:src','img:data-src'],
                        minimize:false  //是否壓縮html
                    }
                }
            ]
        },
        {
            test: /(iconfont.svg)|\.(woff|woff2|eot|ttf|otf)$/,
            use:[
                {
                    loader:'file-loader',
                    options:{
                        name:'[name].[ext]',  //[path] 上下文環(huán)境路徑
                        publicPath:'./assets/iconfont/',    //公共路徑
                        outputPath:'assets/iconfont/',  //輸出路徑                          
                    }
                }               
            ]
        }

    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
        title: '瓦力博客',
        template: './src/index.html'   //以src/index.html為編譯模板
    }),
    new CleanWebpackPlugin()
  ],
+  devServer:{
+    contentBase: path.join(__dirname, 'dist'),
+    clientLogLevel: 'info',
+    open:true,  //啟動時默認打開瀏覽器
+    host:'localhost', //域名 0.0.0.0局域網(wǎng)可訪問
+    port:'9009',
+    inline:true, //實時更新
+    proxy:{
+       '/':{
+           target:'http://www.waliblog.com'
+       },
+       '/upload':{
+           target:'http://www.waliblog.com'
+       }
+    }
+  },  
  output:{
    path: path.resolve(__dirname,'dist')
  }
}

運行webpack

yarn run dev

3.使用代理

proxy:{
    '/':{
        target:'http://www.waliblog.com'
    },
    '/upload':{
        target:'http://www.baidu.com'
    }
}

小菜這里想提到一點就是proxy可以根據(jù)匹配路徑來設置不同的host。舉個例子,小菜要上傳一個文件到服務器,請求的url是http://www.yagm.com/upload,如果配置代理,請求的url就會變成http://www.baidu.com/upload。proxy會匹配到/uploade這個路徑,將host替換成target的值。

4.設置局域網(wǎng)訪問

不知道大家有沒有遇到過這種需求,當你開發(fā)完一個功能時,其他人想先在自己電腦上瀏覽一下,但是你還沒有更新部署。如果在局域網(wǎng)內(nèi),可以設置host這個屬性。將上面配置的host:'localhost'修改為host:'0.0.0.0'然后重啟webpack。在瀏覽器上訪問需要輸入IP地址加端口號。例如小菜的電腦在局域網(wǎng)的IP:192.168.3.21,那么其他人訪問頁面的url:'http://192.168.3.21:9009'。9009端口號是小菜在上面配置自己設置的,大家要替換成自己設置的端口號。

5.熱模塊替換

webpack.config.js

  const path = require('path');
+ const webpack = require('webpack');
  const HtmlWebpackPlugin = require('html-webpack-plugin');    //生成html文件
  const CleanWebpackPlugin = require('clean-webpack-plugin');  //清除



module.exports = {
  mode:'development',
  entry:'./src/index.js',
  module:{
    rules:[
        {
            test:/\.css$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:1
                    }                   
                },
                'postcss-loader'
                
            ]
        },
        {
            test:/\.scss$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'sass-loader',
                'postcss-loader'
            ]
        },
        {
            test: /\.less$/,
            use: [
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'less-loader',
                'postcss-loader'
            ]
        },
        {
            test:/\.(png|svg|jpeg|jpg|gif)$/,
            use:[       
                {
                    loader:'file-loader',
                    options:{
                        name:'[name].[ext]',  //[path] 上下文環(huán)境路徑
                        publicPath:'./assets/image/',    //公共路徑
                        outputPath:'assets/image/',  //輸出路徑                         
                    }
                },
                {
                    loader: 'image-webpack-loader',
                    options: {
                        bypassOnDebug: true, // webpack@1.x
                        disable: true,       // webpack@2.x and newer
                    },
                },
            ]
        },
        {
            test: /\.html$/,
            use:[
                {
                    loader:'html-loader',
                    options:{
                        arrts:['img:src','img:data-src'],
                        minimize:false  //是否壓縮html
                    }
                }
            ]
        },
        {
            test: /(iconfont.svg)|\.(woff|woff2|eot|ttf|otf)$/,
            use:[
                {
                    loader:'file-loader',
                    options:{
                        name:'[name].[ext]',  //[path] 上下文環(huán)境路徑
                        publicPath:'./assets/iconfont/',    //公共路徑
                        outputPath:'assets/iconfont/',  //輸出路徑                          
                    }
                }               
            ]
        }

    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
        title: '瓦力博客',
        template: './src/index.html'   //以src/index.html為編譯模板
    }),
    new CleanWebpackPlugin(),
+       new webpack.HotModuleReplacementPlugin()
  ],
  devServer:{
    contentBase: path.join(__dirname, 'dist'),
    clientLogLevel: 'info',
    open:true,  //啟動時默認打開瀏覽器
    host:'localhost', //域名 0.0.0.0局域網(wǎng)可訪問
    port:'9009',
    inline:true, //實時更新
+    hot:true,    //熱替換
+    hotOnly:true,
    proxy:{
        '/':{
            target:'http://www.waliblog.com'
        },
        '/upload':{
            target:'http://www.waliblog.com'
        }
    }
  },  
  output:{
    path: path.resolve(__dirname,'dist')
  }
}

src/assets/css/index.css

h1{
    color: red;
}

src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
    <h1>歡迎來到瓦力博客</h1>
</body>
</html>

src/index.js

import "./assets/css/index.css"

運行webpack

yarn run dev

webpack啟起來后,我們修改樣式將字體顏色變成藍色

h1{
    color: blue;
}

這個時候瀏覽器中歡迎來到瓦力博客字體也會變藍,這里值得注意的是瀏覽器并未刷新,只是將樣式替換而已。這個熱替換對樣式有用,但是對js腳本就沒有用了。接下來我們做個演示

文件結構

myProject
 |-dist  
 |-node_modules
 |-src
     |-assets
        |-css
            |-index.css
        |-less
            |-index.less     
        |-sass
            |-index.scss
        |-images
            |-wali_logo.png
        |-iconfont
            |-demo.css
            |-demo_index.html
            |-iconfont.css
            |-iconfont.eot
            |-iconfont.js
            |-iconfont.svg
            |-iconfont.ttf
            |-iconfont.woff
            |-iconfont.woff2            
     |-index.html
     |-index.js
+     |-print.js
 |-package.json
 |-webpack.config.js
 |-postcss.config.js

src/index.js

import printMe from './print.js';

function component() {
    var element = document.createElement('div');
    var btn = document.createElement('button');

    element.innerHTML = 'hello webpapck';

    btn.innerHTML = 'Click me and check the console!';
    btn.onclick = printMe;

    element.appendChild(btn);

    return element;
}

document.body.appendChild(component());

上面代碼什么作用呢?創(chuàng)建一個div標簽,創(chuàng)建一個按鈕,在div標簽里填充hello webpapck。按鈕上的文案改為Click me and check the console!,給按鈕綁定一個點擊事件,將按鈕放在div標簽里,將div元素返回出去。最后將div元素掛在body元素里。

src/print.js

export default function printMe() {
    console.log('hello !');
}

導出一個函數(shù),這個函數(shù)的功能是在控制臺輸出一句hello !

啟動webpack

yarn run dev

啟動起來,打開控制臺,在瀏覽器中點擊按鈕,控制臺會輸出hello !

ssl

修改src/print.js

export default function printMe() {
+    console.log('歡迎來到瓦力博客');
}

保存后,這個時候不要刷新瀏覽器,繼續(xù)點擊按鈕,此刻控制臺輸出的依然是hello !而不是我們想要的歡迎來到瓦力博客。

修改src/index.js

import printMe from './print.js';

function component() {
    var element = document.createElement('div');
    var btn = document.createElement('button');

    element.innerHTML = 'hello webpapck';

    btn.innerHTML = 'Click me and check the console!';
    btn.onclick = printMe;

    element.appendChild(btn);

    return element;
}

document.body.appendChild(component());

+if (module.hot) {
+  module.hot.accept('./print.js', function() {
+      var btn = document.querySelector('button');
+      btn.onclick = printMe;
+
+  })
+}

保存后刷新瀏覽器,然后點擊按鈕??吹娇刂婆_輸出歡迎來到瓦力博客這個時候我們回過頭將print.js的內(nèi)容重新修改為

export default function printMe() {
+    console.log('hello !');
}

保存后不要刷新瀏覽器,在點擊按鈕,這個時候控制就會輸出hello !。我們來看看在index.js中添加的代碼作用,當開啟了熱替換后,我們手動監(jiān)聽print.js文件如果發(fā)生更改,在回調(diào)中更新按鈕的點擊事件。小菜舉這個例子是想說明,當我們在devServer中開啟熱替換,只有樣式會被熱替換,js文件不會被熱替換,想要js也被熱替換需要手動編寫代碼。事實上,樣式文件也不會被熱替換,而是開發(fā)人員在代碼中幫我們做了這個功能,我們才不需要去寫。

演示完畢后我們刪除print.js文件

myProject
-   |-print.js
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 原文首發(fā)于:Webpack 3,從入門到放棄 Update (2017.8.27) : 關于 output.pub...
    昵稱都被用完了衰閱讀 2,003評論 4 19
  • 版權聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一、webpack介紹 1、由來 ...
    it筱竹閱讀 11,486評論 0 21
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 7,390評論 0 17
  • 在現(xiàn)在的前端開發(fā)中,前后端分離、模塊化開發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,690評論 1 32
  • 寫在開頭 先說說為什么要寫這篇文章, 最初的原因是組里的小朋友們看了webpack文檔后, 表情都是這樣的: (摘...
    Lefter閱讀 5,452評論 4 31

友情鏈接更多精彩內(nèi)容