webpack 教程 那些事兒03-webpack兩大精華插件,熱加載


本節主要講述 webpack的兩大經典開發調試插件,熱插拔內存緩存機制

 

文章目錄

  1. 1. html-webpack-plugin插件的使用
  2. 2. webpack-dev-middleware 插件登場
  3. 3. webpack-hot-middleware 為了左手
  4. 4. 實現html模版更改自動刷新
  5. 5. 本案例測試源碼下載

html-webpack-plugin插件的使用

如果沒記錯,上篇的時候構建完成的js文件是我們在頁面用 script 標簽手動引入的, 聰明的您應該馬上看出問題來了,難道每次更改輸出path,都要手動更新引入鏈接嗎?如果加上 hash防止緩存,那么一串,豈不頭疼欲死。有需求就有解決方案,此款插件就是用來 將依賴自動寫入html文件的。

1
sudo cnpm i html-webpack-plugin -- save-dev

 

修改配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 終於動用了配置文件里的 plugins 功能選項,已經快遺忘在角落了
plugins: [
new HtmlWebpackPlugin({
filename: '../index.html',
//渲染輸出html文件名,路徑相對於 output.path 的值
 
template: path.resolve(__dirname, './app/views/index.html'),
//渲染源模版文件
 
inject: true
//這個東西非常重要,true: 自動寫入依賴文件; false: 不寫入依賴,構建多頁面非常有用
})
]
 
# 自動寫入依賴,所以刪除app/views/index.html 的script標簽鏈接
<body>
<mountain></mountain>
</body>
# 執行命令: webpack
webpack

 

查看output目錄,發現多了一個 index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
background: #f90;
}
h2{
text-align: center;
font-size: 30px;
padding: 10px 0;
}
</style>
</head>
<body>
<mountain></mountain>
<script type="text/javascript" src="static/app.js"></script></body>
</html>
# 上面的script就是自動寫入的依賴,src路徑就是 配置文件中 output.publicPath
# 終於用到了這個調試功能

 

用chrome 打開鏈接http://localhost:3000/output/index.html 可以看到一樣的屎黃色結果

可能聰明的您又發現了一個問題,我們每次改動一句代碼,哪怕更改一個字體大小,幾像素留白,就要編譯打包一次才能看到結果,有沒有好煩呢?

webpack-dev-middleware 插件登場

1
sudo cnpm i webpack- dev-middleware --save-dev

此插件主要結合 express的 中間件使用,修改dev-server.js,方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var express = require("express");
var app = express();
var port = process.env.PORT || 3000;
 
/**
* 引入webpack 及其 配置config
*/
var webpack = require("webpack");
var webpackConfig = require("./webpack.config.js");
//調用配置,生成 compiler instance
var compiler = webpack(webpackConfig);
 
//這里是重點,使用 webpack-dev-middleware 插件
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true,
chunks: false
}
})
// 注冊中間件
app. use(devMiddleware);
 
// 使用靜態資源
app. use(express.static(__dirname+'/'));
 
app.listen(port, function (err){
if (err) {
throw err;
}
console.log( 'Listening at http://localhost:' + port + '\n')
})

 

為了方便調試 和 理解什么叫 內存緩存,不寫入硬盤,我們修改一點webpack配置

  • 修改 output.publicPath: “/“,修改為根目錄
  • plugins中的filename: “index.html” ,置換到根目錄
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    output: {
    path: path.resolve(__dirname, "./output/static"), //輸出路徑
    publicPath: '/', //調試或者 CDN 之類的域名,稍候會用到
    filename: "[name].js" //配置生成的文件名
    }
     
    plugins: [
    new HtmlWebpackPlugin({
    filename: 'index.html',
    template: path.resolve(__dirname, './app/views/index.html'),
    inject: true
    })
    ]

然后,重啟服務 node dev-server.js

打來瀏覽器輸入: http://localhost:3000/index.html
哇塞,又看到了記憶中 屎黃色 的界面,有木有很開心,打開控制台,會看到這句代碼

1
<script type="text/javascript" src="/app.js"></script>

 

驚奇的事情發生了,我們的根目錄根本沒有index.html 和 app.js,這些東西哪里來的呢?
這就是我們的 偉大的中間件 webpack-dev-middleware 的功勞。

然后去mountains.vue文件中修改背景色或者其他,然后刷新瀏覽器就能看到效果了
有木有很贊,速度還超快哦,如圖改動了背景色,只需 55ms,就是快
timetime

接下來就是解放我們的雙手,自動實時刷新頁面.

webpack-hot-middleware 為了左手

1
2
# 老套路 install
sudo cnpm i webpack-hot-middleware --save-dev

使用步驟,參照api,很簡單

  • 增加插件plugins

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 注意先行引入 webpack
    # var webpack = require("webpack");
    plugins: [
    // Webpack 1.0
    new webpack.optimize.OccurenceOrderPlugin(),
    // Webpack 2.0 fixed this mispelling
    // new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
    new HtmlWebpackPlugin({
    filename: 'index.html',
    template: path.resolve(__dirname, './app/views/index.html'),
    inject: true
    })
    ]
  • Add ‘webpack-hot-middleware/client’ into the entry array(添加xx到入口數組)

    1
    2
    3
    4
    entry: {
    app: ['webpack-hot-middleware/client',path.resolve(__dirname, "./app/main.js")]
    }
    更好的方法是不動基本配置,稍候會在 dev-server.js中 書寫
  • Add webpack-hot-middleware attached to the same compiler instance

    1
    2
    # dev-server.js中 app.use(devMiddleware); 之后增加
    app .use(require("webpack-hot-middleware")(compiler));

重新啟動服務 node der-server.js
然后修改一個 body 背景,切回瀏覽器,哇塞,自動刷新了
懷着激動的心情改了一下main.js,開心的切回瀏覽器哇靠靠,一切都沒變化,錯覺?果然手動刷新, 看到了你想看到的。
你沒錯,是我錯了,更改上面第二部的 entry參數配置如下:

1
2
3
4
# 增加 參數reload= true
entry: {
app: [ 'webpack-hot-middleware/client?noInfo=true&reload=true',path.resolve(__dirname, "./app/main.js")]
}

 

果然重啟服務,一切ok.
閑的蛋疼又去,更改了.vue文件里面的 data 數據,然后。。。。問題又來了,無熱加載,控制台卻能看到vue文件變化消息
查了查資料:發現這可能是vue的熱加載機制和策略問題,目前我不知道怎么解決。

接下來還有一件事,那就是html模版改動的自動刷新,現在是沒有這個功能的,不信你試試!

實現html模版更改自動刷新

  • 更改entry注入參數方式,從dev-server.js寫入,example:
1
2
3
4
# webpack.config.js 恢復初始設置
entry: {
app: path.resolve(__dirname, "./app/main.js")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# dev-server.js
# 增加文件,刷新client單獨文件配置,配合html reload
var express = require("express");
var app = express();
var port = process.env.PORT || 3000;
 
/**
* 引入webpack 及其 配置config
*/
var webpack = require("webpack");
var webpackConfig = require("./webpack.config.js");
 
// var devClient = 'webpack-hot-middleware/client?noInfo=true&reload=true';
var devClient = './dev-client';
Object.keys(webpackConfig.entry). forEach(function (name, i) {
var extras = [devClient]
webpackConfig.entry[name] = extras.concat(webpackConfig.entry[name])
})
//調用配置
var compiler = webpack(webpackConfig);
 
//這里是重點,使用 webpack-dev-middleware 插件
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: '/',
stats: {
colors: true,
chunks: false
}
})
 
var hotMiddleware = require('webpack-hot-middleware')(compiler)
// 監聽html文件改變事件
compiler.plugin( 'compilation', function (compilation) {
compilation.plugin( 'html-webpack-plugin-after-emit', function (data, cb) {
// 發布事件 reload,這個事件會在dev-client.js中接受到,然后刷新
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
 
 
// 注冊中間件
app. use(devMiddleware);
app. use(hotMiddleware);
 
// 使用靜態資源
app. use(express.static(__dirname+'/'));
 
app.listen(port, function (err){
if (err) {
throw err;
}
console.log( 'Listening at http://localhost:' + port + '\n')
})

dev-client.js 接受reload事件

1
2
3
4
5
6
7
8
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
// 訂閱事件,當 event.action === 'reload' 時執行頁面刷新
// 還記得 dev-server.js中 派發的reload事件吧
hotClient.subscribe( function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})

 

重啟服務,修改試試?不出意外,應該萬事大吉了。
ok,至此,測試程序已經結束了。下篇講解項目中的webpack配置.

本案例測試源碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM