本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(static module bundler)。在 webpack 處理應用程序時,它會在內部建立一個依賴圖(dependency graph),用於映射到項目須要的每一個模塊,而後將全部這些依賴生成到一個或多個bundle。css
注:webpack不是一個JS編譯器,而是模塊打包工具(並不只僅是JS模塊的打包工具,還支持CSS、圖片等文件);html
webpack支持的JS規範主要有ES Moudule、CommonJS、CMD、AMD等。
複製代碼
以上規範舉幾個例子:前端
提升webpack打包速度的兩個方法:vue
(1)保持node.js的版本比較新
(2)保持webpack版本比較新
複製代碼
這是由於新版本的webpack會利用node的新特性來提升它的打包速度。node
正常webpack的安裝方式有兩種:全局安裝和本地項目安裝react
(1)使用如下命令行進行webpack全局安裝webpack
npm install webpack webpack-cli -g
複製代碼
(2)使用如下命令行進行本地項目安裝git
npm install webpack webpack-cli -D
複製代碼
以上命令至關於:github
npm install webpack webpack-cli --save-dev
複製代碼
當要選擇webpack版本時,使用npm install webpack@版本 -D進行安裝,這樣即可以在不一樣項目切換使用webpack版本。web
注意:當咱們有其餘項目須要使用到webpack3或者比較老的版本的話,若是直接使用當前的webpack命令執行打包的話會出錯,這是由於當前webpack使用的是全局安裝下的webpack命令,解決方法是卸載原先在全局安裝webpack和webpack-cli,在本地項目進行方式(2)安裝。
檢查:怎麼檢查安裝是否成功呢?
當咱們使用webpack -v時會輸出以下提示說當前全局沒有webpack,能夠安裝webpack-cli腳手架來使用
One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:
- webpack-cli (https://github.com/webpack/webpack-cli)
The original webpack full-featured CLI.
We will use "npm" to install the CLI via "npm install -D".
Do you want to install 'webpack-cli' (yes/no):
複製代碼
此處要想使用當前項目的webpack命令,則須要加上npx,以下:
npx webpack -v
npx webpack-cli -v
複製代碼
webpack底層已經幫咱們封裝好不少默認配置,當咱們沒有本身手動去配置時,則會使用默認配置,可是在一個比較複雜的項目下,咱們通常但願使用根據咱們需求配置好的文件來更改webpack的默認配置,簡單步驟以下:
(1)建立webpack的默認配置文件webpack.config.js
(2)修改webpack的默認配置,代碼以下:
const path = require('path');
module.exports = {
// 配置webpack打包的入口文件
entry: './index.js',
// 配置webpack打包的輸出文件
output: {
// 配置打包完成後的文件名
filename: 'bundle.js',
// 配置打包完成後的文件存放目錄(絕對路徑)
path: path.resolve(__dirname, 'bundle')
}
}
複製代碼
(3)執行命令,進行打包
npx webpack
複製代碼
(4)當咱們有需求不想使用webpack的默認配置文件名webpack.config.js時,好比咱們能夠修改成webpackConfig.js,這時若是你執行打包命令則會報錯,由於webpack不識別你當前的配置文件,而使用原先的默認配置文件,因此咱們須要使用如下命令讓webpack以你當前配置文件爲當前配置。
npx webpack --config webpackConfig.js
複製代碼
(5)每次打包都要執行npx命令感受跟咱們之前學的不太像,能夠在npm scripts中加入對應的打包命令來代替:
"scripts": {
"bundle": "webpack"
}
複製代碼
接着執行以下打包命令:
npm run bunlde
複製代碼
注意:你必定有個疑問,咱們執行打包命令爲npx webpack,因此不是應該在scripts中配置成,"bundle":"npx webpack",否則會使用的全局webpack命令致使找不到?
這個是由於npm scripts的配置,由於在scripts中配置爲webpack,執行打包命令後它會先在當前項目的node_modules下查找是否有webpack,沒有的話再往上一級到全局node_modules去找。
(1)在global全局下:
webpack index.js
複製代碼
(2)在當前項目文件夾:
npx webpack index.js
複製代碼
(3)使用webpack的配置文件+npm scripts中加入打包命令:
npm run bundle
複製代碼
(1)讓咱們可以在命令行中,直接使用webpack命令
(2)在本地項目文件夾下,若是全局沒有安裝webpack,使用webpack會去全局查找webpack則報你沒安裝,而 只要你在本地項目中有裝webpack,使用npx webpack能夠找到本地webpack命令。
當咱們在打包時引入的不只僅是js文件,好比能夠是一個圖片文件:
var avator = require('./avator.jpg');
複製代碼
若是咱們還執行打包命令則會提示打包報錯,由於webpack自己在默認配置下只會打包js文件,因此當咱們要想打包圖片文件則要引入對應的loader並配置,使得webpack支持圖片打包。
webpack打包圖片須要藉助file-loader配置:
(1)首先在本地項目安裝file-loader:
npm install file-loader -D
複製代碼
(2)在webpack.config.js配置使用file-loader規則:
module: {
rules: [{
// 正則匹配以.jpg結尾的文件
test: /\.jpg$/,
// 將匹配到的文件使用file-loader進行打包
use: {
loader: 'file-loader'
}
}]
}
複製代碼
(3)配置完成以後,使用打包命令打包:
npm run bundle
複製代碼
總之,webpack不能識別打包除JavaScript 以外的靜態資源,須要藉助各類loader來預處理文件,使之可以打包除 JavaScript 以外的任何靜態資源 。
在開始以前先看一下咱們目前文件的目錄結構,以下圖:
上一小節中咱們可使用webpack將圖片打包到dist目錄下了,可是若是咱們想在index.html文件下加載打包的index.js文件,index.js文件中的代碼以下:import avator from './avator.jpg';
var root = document.getElementById("root");
var img = new Image();
img.src = avator;
root.append(img);
複製代碼
這裏index.js中建立了一個img標籤,並打包好的avator圖片賦值到img的src上,掛載到root上顯示。
接着在index.html文件中的代碼以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圖片打包番外篇</title>
</head>
<body>
<p>圖片打包番外篇</p>
<div id='root'></div>
<script src='./../dist/bundle.js'></script>
</body>
</html>
複製代碼
上述代碼看着沒問題,接下來執行打包命令,沒有報錯,一切看似都很ok的,可是當咱們在瀏覽器打開index.html時看到倒是這樣的畫面,以下圖:
圖片竟然找不到,這是啥緣由啊?
img.src = avator; //6db51315be71c2bc73d1bc8663cc1ebc.jpg
複製代碼
這是由於上面代碼img的src屬性上賦的值爲打包後圖片的名稱加擴展名,這樣子的話index.html在哪一個目錄下引入打包後的bundle.js,就如上面index.html在src目錄下引入了bunlde.js,當執行bundle.js就去src下找打包後的圖片,結果找不到。反之!若是index.html在dist目錄下的時候,恰巧打包後的圖片也在該目錄下,因此加載出來!
解決方法以下:
方式一:
將index.html移到dist打包目錄下,修改index.html中引用bundle.js的路徑爲'./bundle.js',這樣再打包一次,運行index.html圖片就顯示出來了。方式二:
在不改變index.html位置下,直接在index.js文件中修改代碼以下:
import avator from './avator.jpg';
var root = document.getElementById("root");
var img = new Image();
img.src = "./../dist/"+avator;
console.log("./../dist/"+avator)
root.append(img);
複製代碼
這樣的話,打包成功後,圖片會被打包到dist目錄下,在img的src屬性下直接賦值dist目錄下打包好的圖片路徑就能夠找到圖片了,而後顯示在瀏覽器上。
上面咱們用到了file-loader,可是並無比較詳細的介紹這個loader,接下來就來看看file-loader的一些經常使用配置
(1)安裝file-loader,安裝時起初沒注意直接安裝了最新版3.0.1,可是新版本並無將它所需的依賴也安裝進來,因此後面降級到2.0.0版本
npm install file-loader@2.0.0 -D
複製代碼
(2)常見的選項和placeholders結合使用
use: {
loader: 'file-loader',
options: {
// placeholders 佔位符
name: '[name]_[hash].[ext]',
outputPath: 'images/'
}
}
複製代碼
選項:
name:配置自定義文件名
outputPath:配置資源的輸出目錄
emitFile:只返回 public URL 但不會生成文件 ,默認值爲true生成,false不生成
複製代碼
placeholders:佔位符
[name]:資源的基本名稱
[hash]: 配置文件名的加密規則(默認MD5加密)
[ext]:資源的擴展名
[path]:資源相對於context的路徑
複製代碼
url-loader跟file-loader很像,基本差很少,基本配置以下:
(1)安裝
npm install url-loader -D
複製代碼
(2)快速使用
use: {
loader: 'url-loader',
options: {
// placeholders 佔位符
name: '[name]_[hash].[ext]',
outputPath: 'images/',
// 20KB
limit: 20480
}
}
複製代碼
選項:
limit:單位爲Byte,當超過這個大小限制的話就會生成文件,不然直接以base64格式嵌入url中
fallback:當文件超過limit限制時,使用對應的loader處理(默認是file-loader)
複製代碼
使用url-loader適用於圖片文件比較小(幾KB的那種),這樣的話能夠直接嵌入到url中,直接在瀏覽器js腳本運行時就加載,不用發送請求,可是若是圖片文件過大的話,腳本加載過長,首屏顯示就好久。
使用file-loader適用於圖片文件比較大一點的,能夠解決文件引用路徑的問題 ,打包後生成對應的圖片文件,在打開html在瀏覽器運行時發送一個請求,若是圖片較多,會發不少http請求,會下降頁面性能 。
webpack支持打包的靜態資源不只是圖片等文件,還能夠是CSS、Less、Scss等樣式文件,這時候就須要藉助style-loader、css-loader、sass-loader來支持webpack打包,簡單的例子以下:
(1)在src目錄下建立index.scss,編寫以下的sass樣式:
body {
.avator {
width: 150px;
height: 150px;
transform: translate(100, 100);
}
}
複製代碼
(2)在src目錄下的index.js導入scss的樣式並將class添加到對應圖片的dom上,代碼以下:
import avator from './avator.jpg';
import './index.scss'
var root = document.getElementById("root");
var img = new Image();
img.src = avator;
// 往img上添加avatorclass
img.classList.add('avator');
root.append(img);
複製代碼
(3)在webpack.config.js文件中添加以下配置:
{
test: /\.scss$/,
use: [
// 從下到上執行
'style-loader',
'css-loader',
'sass-loader',
'postcss-loader'
]
}
複製代碼
注意:這裏的loader是從下到上執行的,若是寫成一行的話是從右到左執行
(4)在sass文件的樣式中咱們用到了transform,這個樣式屬性要支持各類瀏覽器的話要添加對應的瀏覽器廠商前綴,好比-webkit-等,這時咱們能夠藉助webpack的postcss-loader來給咱們自動添加廠商前綴,可是postcss-loader還須要建立本身的配置文件postcss.config.js而且加入autoprefixer插件,代碼以下:
安裝style-loader、css-loader、sass-loader、postcss-loader、node-sass、autoprefixer:
npm install -D style-loader css-loader sass-loader postcss-loader node-sass autoprefixer
複製代碼
在根目錄下建立postcss.config.js文件並加入以下代碼:
module.exports = {
plugins: [
// 導入插件
require('autoprefixer')
]
}
複製代碼
(5)刪除dist下的images文件夾和bundle.js,執行打包命令完成打包,打開html文件在瀏覽器運行選中對應的圖片元素能夠看到上面掛載了avator的class,而且在transform邊上還添加了廠商前綴。
咱們可能在scss樣式文件中又導入另一個scss樣式文件,這樣子的話若是按原先的執行順序來執行,只能將第一個scss文件進行處理轉譯,另一個沒轉譯,即postcss-loader和sass-loader只執行一次,解決方法就是讓這兩個loader再執行一次。
相關文件代碼修改以下:
(1)在src目錄下建立一個avator.scss文件,編寫代碼以下:
body {
.avator {
width: 220px;
height: 150px;
}
}
複製代碼
(2)在index.scss中導入avator.scss:
@import './avator.scss';
body {
.avator {
transform: translate(100px, 100px);
}
}
複製代碼
(3)webpack.config.js中須要修改爲以下代碼配置:
{
test: /\.scss$/,
use: [
// 從下到上執行
'style-loader',
{
loader: 'css-loader',
options: {
// 讓匹配到的scss樣式文件都去走如下兩個loader
// 用於配置「css-loader 做用於 @import 的資源以前」有多少個 loader
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
}
複製代碼
(1)首先咱們在前面的基礎上封裝一個createAvator.js,做用是建立頭像,createAvator.js代碼以下:
import avator from './avator.jpg';
export default function () {
var root = document.getElementById("root");
var img = new Image();
img.src = avator;
img.classList.add('avator');
root.append(img);
}
複製代碼
(2)在index.js中引入createAvator並調用:
import avator from './avator.jpg';
import createAvator from './createAvator';
import './index.scss';
// 調用建立頭像
createAvator();
var root = document.getElementById("root");
var img = new Image();
img.src = avator;
img.classList.add('avator');
root.append(img);
複製代碼
這時執行打包命令,運行index.html能夠看到建立的兩個圖片頭像都引用到了index.scss中的樣式,index.scss中的樣式就成了全局的樣式了,如何解決這個問題,讓css樣式模塊化?
(3)要讓scss樣式支持css module,則須要在webpack.config.js中的css-loader中配置參數module爲true:
{
test: /\.scss$/,
use: [
// 從下到上執行
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
// 設置css-loader支持css 的modules
modules: true
}
},
'sass-loader',
'postcss-loader'
]
}
複製代碼
(4)修改index.js中引入index.scss的方式,使用模塊化的方式引入,代碼以下:
import avator from './avator.jpg';
import createAvator from './createAvator';
import style from './index.scss';
createAvator();
var root = document.getElementById("root");
var img = new Image();
img.src = avator;
img.classList.add(style.avator);
root.append(img);
複製代碼
(5)打包運行index.html能夠看到兩張圖片頭像顯示不一樣的樣式,使用createAvator建立的頭像沒有使用index.scss的樣式,若是要想讓它也使用index.scss的樣式則須要在createAvator.js中模塊化導入index.scss並使用,代碼以下:
import avator from './avator.jpg';
// 模塊化引入index.scss,調用的時候才引用樣式
import style from './index.scss';
export default function () {
var root = document.getElementById("root");
var img = new Image();
img.src = avator;
// 使img引用style中的avator樣式
img.classList.add(style.avator);
root.append(img);
}
複製代碼
在實際項目應用中咱們可能須要用到字體的樣式文件,一樣webpack也支持打包咱們項目所需的字體樣式文件,具體步驟以下:
(1)首先到iconfont阿里圖標矢量庫中添加幾個圖標到項目中,再下載對應的字體樣式文件到本地
(2)在src目錄下建立font文件夾,從下載下來的字體樣式文件取以eot、svg、ttf、woff結尾的文件到font文件夾
(3)在index.scss中粘貼iconfot.css中的內容,修改引入路徑,代碼以下:
@font-face {
font-family: "iconfont";
src: url('./font/iconfont.eot?t=1543245201565'); /* IE9*/
src: url('./font/iconfont.eot?t=1543245201565#iefix') format('embedded-opentype'), /* IE6-IE8 */
// 此處去掉了base64的一段代碼
url('./font/iconfont.ttf?t=1543245201565') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('./font/iconfont.svg?t=1543245201565#iconfont') format('svg'); /* iOS 4.1- */
}
複製代碼
(4)在index.js中導入index.scss並建立對應的字體div,代碼以下:
var root = document.getElementById('root');
import './index.scss';
// 這裏的class必須是iconfont 圖標的class名
root.innerHTML = '<div class="iconfont icon-changjingguanli"></div>';
複製代碼
(5)在webpack.config.js中添加處理eot、svg、ttf結尾的文件打包的配置,代碼以下:
{
test: /\.(eot|svg|ttf)$/,
use: {
loader: 'file-loader'
}
}
複製代碼
(6)打包運行index.html能夠看到字體顯示出來了
在咱們原先打包時,每次都要刪掉dist目錄下的除index.html,不能直接刪除整個dist,那咱們能不能在每次打包以前直接將dist目錄都直接刪除,打包完成後自動生成符合咱們配置的index.html文件呢?
這就須要藉助webpack的html-webpack-plugin了,基本使用步驟以下:
(1)安裝html-webpack-plugin
npm install html-webpack-plugin -D
複製代碼
(2)在webpack.config.js文件中引入html-webpack-plugin:
const HtmlWebPackPlugin = require('html-webpack-plugin');
複製代碼
(3)在webpack.config.js中添加配置:
plugins: [
// 建立插件實例,添加各項配置
new HtmlWebPackPlugin({
// 根據index.html模板建立dist下的index.html
template: 'src/index.html'
})
]
複製代碼
注意:在咱們直接刪除dist整個目錄文件夾時,webpack打包完成後悔自動添加index.html並把打包好的bundle.js引入到script標籤之中。
plugin的本質就像vue或者react的生命週期函數同樣,能夠在webpack運行到某個時刻的時候,自動幫你作一些事。
咱們在上面一些操做中,每次都在打包前把dist下的文件手動刪除,有沒有好的工具能夠幫咱們解決打包前自動刪除dist文件夾及其底下全部文件?
答案確定是有的,須要藉助webpack第三方plugin即clean-webpack-plugin,具體使用步驟以下:
(1)安裝clean-webpack-plugin:
npm install clean-webpack-plugin -D
複製代碼
(2)在webpack.config.js文件中引入clean-webpack-plugin:
const CleanWebpackPlugin = require('clean-webpack-plugin');
複製代碼
(3)在webpack.config.js文件中配置plugins:
plugins: [
// 建立插件實例,添加各項配置
new HtmlWebPackPlugin({
template: 'src/index.html'
}),
// 建立實例並傳入要刪除的文件夾
new CleanWebpackPlugin(['dist'])
]
複製代碼
對於SourceMap的幾個理解
對於SourceMap是什麼,咱們能夠先作一個小實驗來引出SourceMap,大概步驟以下:
(1)在src目錄下將index.js代碼所有去掉,添加一行代碼:
consles.log("hello world"); // 這裏故意將console打錯
複製代碼
(2)在webpack.config.js中mode設置爲development 會自動打開sourceMap,所以咱們進行手動關閉:
// 手動將sourceMap關閉
devtool: 'none',
複製代碼
(3)執行打包命令,運行index.html打開控制檯會報打包後的main.js的第96行代碼出錯,咱們點擊main.js就會進入到打包後的main.js中排錯,可是在實際中就算修改了main.js中代碼,再次打包仍是錯的,這是由於咱們只在打包好的代碼修改,並無在源文件修改,所以咱們但願控制檯報錯的時候給咱們提示的是源文件的報錯信息,這時就要藉助SourcMap的功能:
// 打開sourceMap功能
devtool: 'source-map',
複製代碼
(4)再次執行打包,控制檯能夠看到報錯信息是在源文件的index.js中第一行console拼錯了。
sourceMap就是創建起打包以後報錯的代碼與源文件代碼之間的映射關係,主要在devtool裏面進行配置,配置參數很是多,通常只用到比較常見的幾個:
複製代碼
如上,devtool中的參數能夠進行疊加使用,通常這樣規定:
在development模式中,devtool使用cheap-module-eval-source-map
在production模式中,devtool使用cheap-module-source-map
在咱們使用webpack打包的時候,每次修改源代碼文件以後都要再執行一次打包命令,這很是不方便,webpack能不能監聽到源代碼發生修改以後自動幫咱們再次打包?
強大的webpack給咱們提供了不少種方式,這裏簡要介紹兩種:
(1)直接在package.json文件中的scripts中配置,執行npm run watch便可:
"scripts": {
"watch": "webpack --watch"
},
複製代碼
(2)藉助webpackDevServer
安裝webpack-dev-server
npm install webpack-dev-server -D
複製代碼
在webpack.config.js文件中配置devServer:
devServer: {
// 告訴服務器從哪一個目錄中提供內容
contentBase: './dist',
// 打包結束後自動啓動瀏覽器進入localhost:8080下的頁面
open: true
}
複製代碼
在package.json文件中的scripts中配置,執行npm run start啓動服務:
"scripts": {
"bundle": "webpack",
"watch": "webpack --watch",
"start": "webpack-dev-server"
}
複製代碼
注意:在webpackDevServer時還能夠配置代理轉發,好比:
module.exports = {
//...
devServer: {
proxy: {
'/api': 'http://localhost:3000'
}
}
};
複製代碼
以上代理的意思是當請求到/api/xxx時會代理到請求http://localhost:3000/api/xxx,這樣子使咱們前端在數據mock時不須要使用Charles等代理工具。
在網上偶然看到webpack藉助webpack-dev-middleware和express也能夠集成相似webpackDevServer的小型Server,具體步驟以下:
(1) 安裝服務所需的包和依賴:
npm install express webpack-dev-middleware -D
複製代碼
(2)在webpack.config.js文件中配置生成新文件所指向的路徑即publicPath:
// 配置webpack打包的輸出文件
output: {
publicPath: '/',
// 配置打包完成後的文件名
filename: '[name].js',
// 配置打包完成後的文件存放目錄(絕對路徑)
path: path.resolve(__dirname, 'dist')
}
複製代碼
(3)在package.json文件中的scripts中配置:
"scripts": {
"bundle": "webpack",
"watch": "webpack --watch",
"start": "webpack-dev-server",
"server": "node server.js"
}
複製代碼
(4)在項目跟webpack.config.js同級目錄下建立server.js,編寫代碼以下:
const express = require("express");
const webpack = require("webpack");
const webpackDevMiddleWare = require("webpack-dev-middleware");
// 引入webpack的配置文件
const config = require("./webpack.config");
// 導入配置文件建立webpack的編譯器
const complier = webpack(config);
// 建立基於express的node web服務器
const app = express();
// express服務集成webpack-dev-middleware中間件
app.use(webpackDevMiddleWare(complier, {
// 配置生成新文件所指向的路徑,須要使用相對路徑
publicPath: config.output.publicPath
}));
// 啓動sever時監聽3000端口
app.listen(3000, ()=> {
console.log("server is running");
})
複製代碼
(5)執行npm run server運行服務,並在瀏覽器輸入localhost:3000進入頁面
在開發過程當中,特別是前端開發一些html和css樣式的調整,咱們並不想刷新整個瀏覽器的頁面,只是想webpack幫咱們覆蓋掉咱們修改的那部分html和css代碼,相似於局部刷新,熱模塊更新HotModuleReplacementPlugin可以很好地幫咱們解決這個問題,具體實現步驟以下:
(1)在webpack.config.js文件中配置處理導入css文件的打包處理方式:
{
test: /\.css$/,
use: [
// 從下到上執行
'style-loader',
'css-loader',
'postcss-loader'
]
}
複製代碼
(2)webpack.config.js文件中配置熱更新:
// 熱更新plugin是在webpack底下,全部要先引入webpack
const webpack = require('webpack');
// 在devServer中啓用熱更新
devServer: {
// 告訴服務器從哪一個目錄中提供內容
contentBase: './dist',
// 打包結束後自動啓動瀏覽器進入localhost:8080下的頁面
open: true,
port: 8080,
// 啓用熱模塊更新
hot: true,
// 在html出現問題時不讓webpack幫咱們自動刷新,而是直接給咱們報錯
hotOnly: true
}
// 在plugins下建立plugin實例
new webpack.HotModuleReplacementPlugin()
複製代碼
(3)在src目錄下新建style.css文件,代碼以下:
div:nth-of-type(odd) {
background: blue;
}
複製代碼
(4)src下新建index.js,代碼以下:
import './style.css';
var btn = document.createElement('button');
btn.innerHTML = '新增';
document.body.appendChild(btn);
btn.onclick = function() {
var div = document.createElement('div');
div.innerHTML = 'item';
document.body.appendChild(div);
}
複製代碼
(5)執行npm run start啓動服務,瀏覽器中點擊新增按鈕,發現奇數行的div爲藍色,咱們修改style.css的background顏色爲green
div:nth-of-type(odd) {
background: green;
}
複製代碼
保存時回到瀏覽器發現建立的item個數還在,item的顏色也變成了綠色,實現css模塊熱更新。
注意:有時候咱們在js中要想實現js模塊熱更新,webpack也有對應的解決方式,以下例子:
(1)在src下新建counter .js、number.js和number1.js:
// counter .js
function counter() {
var div = document.createElement('div');
div.setAttribute('id', 'counter');
div.innerHTML = 1;
div.onclick = function() {
div.innerHTML = parseInt(div.innerHTML, 10) + 1
}
document.body.appendChild(div);
}
export default counter;
// number.js
function number() {
var div = document.createElement('div');
div.setAttribute('id', 'number');
div.innerHTML = 4000;
document.body.appendChild(div);
}
export default number;
// number1.js
function number1() {
var div = document.createElement('div');
div.setAttribute('id', 'number1');
div.innerHTML = 1000;
document.body.appendChild(div);
}
export default number1;
複製代碼
(2)清除index.js的代碼添加以下代碼:
import counter from './counter';
import number from './number';
import number1 from './number1';
counter();
number();
number1();
if(module.hot) {
module.hot.accept('./number', () => {
// 先將id選擇器爲number移除
document.body.removeChild(document.getElementById('number'));
// 建立div並設置id爲number
number();
})
module.hot.accept('./number1', () => {
document.body.removeChild(document.getElementById('number1'));
number1();
})
}
複製代碼
(3)webpack.config.js中的熱更新已配置好,直接運行服務,瀏覽器打開先點擊幾下counter的計數器後修改number.js和number1.js中的div.innerHTML值,能夠發現頁面上number和number1的值都會變化可是counter值仍是保持在原先的計數值,並不會恢復成0。
如今ES6的一些語法已經逐漸代替了老版本的語法,可是一些瀏覽器還不能兼容ES6的一些新語法,使用Babel能夠將ES6語法轉換成ES5語法再讓瀏覽器執行。
在webpack中使用Babel處理ES6的步驟以下:
(1)首先在index.js中編寫須要轉譯的ES6代碼:
const arr = [
new Promise(() => {}),
new Promise(() => {})
];
arr.map(item => {
console.log(item);
});
複製代碼
(2)安裝babel-loader、 @babel/core、@babel/preset-env、@babel/polyfill:
npm install babel-loader @babel/core @babel/preset-env @babel/polyfill -D
複製代碼
(3)配置webpack.config.js文件:
// 在module下配置
{
test: /\.js$/,
// 排除node_modules目錄下的js文件
exclude: /node_modules/,
loader: "babel-loader",
options: {
"presets": [["@babel/preset-env", {
// 配置babel/polyfill根據業務代碼所用到的變量、函數才填充進去,這樣打包的文件就比較小
useBuiltIns: 'usage'
}]]
}
}
複製代碼
注意:這裏的babel-loader只是創建起webpack與babel轉譯器的橋樑,咱們還須要告訴webpack編譯的規則和環境,所以如上要配置presets
(4)若是此時直接執行npx webpack打包的話,發現打包後文件的末尾index.js代碼仍是有一些變量、函數沒有被轉譯,所以還須要在index.js導入@babel/polyfill彌補低版本瀏覽器一些變量、函數 :
// index.js
// @babel/polyfill能夠彌補低版本瀏覽器一些變量、函數
import "@babel/polyfill";
複製代碼