翻譯 | webpack2的入門手冊

背景

一直對webpack的打包流程很感興趣,但是無奈官網(wǎng)文檔實(shí)在太多,搜出來的大部分文章要么偏理論要么純粹講過程不講原理,最近終于找到一篇入門文章,文章對于初學(xué)者講的很清晰全庸,但是由于是英文的,而且我沒有找到這篇文章對應(yīng)的中文翻譯版融痛,所以本文主要是對那篇文章進(jìn)行翻譯壶笼,介紹一下webpack2的入門知識。
注:本人翻譯水平有限雁刷,如果有錯(cuò)誤拌消,歡迎指正。
原文地址:A Beginner’s Guide to Webpack 2 and Module Bundling
原文作者:Mark Brown
譯文作者:Allen Gong

webpack2入門手冊(譯文)

Webpack是一個(gè)模塊打包機(jī)

Webpack已然成為當(dāng)前web開發(fā)最重要的工具之一安券。首先它是一個(gè)Javascript的打包工具墩崩,但同時(shí)他也能打包包括HTML,CSS侯勉,甚至是圖片等形式的資源鹦筹。它能更好的控制你正在編寫的App的HTTP請求,并且允許你去使用更多的資源(如Jade,Sass以及ES6)。Webpack同時(shí)允許你更容易的從npm獲取安裝包吓著。

這篇文章主要面向那些對于webpack完全陌生的同學(xué)拴清,內(nèi)容將包括初始安裝和配置,模塊携龟,模塊加載器崇堰,插件亿虽,代碼拆分以及模塊熱替換(HMR,hot module replacement)虚青。如果你覺得入門視頻比較有用的話它呀,我推薦Glen Maddern的Webpack初體驗(yàn)作為開始學(xué)習(xí)的起點(diǎn),會(huì)讓你理解為什么webpack如此特殊棒厘。

為了更加后續(xù)的閱讀纵穿,請確保先安裝了Node.js,安裝可以參考Node.js安裝教程奢人。你也在Github上下載到對應(yīng)的Demo谓媒。

安裝

讓我們用npm和webpack新建一個(gè)項(xiàng)目吧:

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack@beta --save-dev
mkdir src
touch index.html src/app.js webpack.config.js

編輯以下文件:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Hello webpack</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="dist/bundle.js"></script>
  </body>
</html>
// src/app.js
const root = document.querySelector('#root')
root.innerHTML = `<p>Hello webpack.</p>`
// webpack.config.js
const webpack = require('webpack')
const path = require('path')

const config = {
  context: path.resolve(__dirname, 'src'),
  entry: './app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [{
      test: /\.js$/,
      include: path.resolve(__dirname, 'src'),
      use: [{
        loader: 'babel-loader',
        options: {
          presets: [
            ['es2015', { modules: false }]
          ]
        }
      }]
    }]
  }
}

module.exports = config

以上的設(shè)置只是通用配置,它會(huì)指導(dǎo)你的webpack將我們的入口文件src/app.js編譯輸入為/dist/bundle.js何乎,并且所有的.js文件都將通過Babel從ES2015轉(zhuǎn)換為ES5句惯。

為了讓這個(gè)項(xiàng)目能運(yùn)行起來,我們需要安裝三個(gè)安裝包支救,babel-core抢野,webpack的加載器babel-loader以及預(yù)處理模塊babel-preset-es2015,這些模塊都是為了支持Javascript的編寫搂妻。{ modules: false }可以確保使用Tree Shaking去去除掉不必要的模塊蒙保,同時(shí)會(huì)降低文件大小辕棚。

npm install babel-core babel-loader babel-preset-es2015 --save-dev

最后使用下面代碼更新package.json:

"scripts": {
  "start": "webpack --watch",
  "build": "webpack -p"
},

運(yùn)行npm start將會(huì)以觀察模式啟動(dòng)webpack欲主,在這種模式下,會(huì)持續(xù)監(jiān)聽我們src文件夾下的.js文件逝嚎”馄埃控制臺的輸出結(jié)果顯示了生成的打包后的文件,我們應(yīng)該持續(xù)關(guān)注生成的文件的大小和數(shù)量补君。

現(xiàn)在你可以在瀏覽器中訪問index.html引几,將會(huì)看到“Hello webpack.”

open index.html

打開dist/bundle.js看看webpack到底做了什么事,在文件的頂部是bootstrapping模塊的代碼挽铁,在它下面是我們自己的模塊伟桅。你可能目前還沒有什么感覺webpack好處,但是你現(xiàn)在可以編寫ES6代碼并且webpack將會(huì)把各個(gè)模塊打成生產(chǎn)所需要的包叽掘,這樣所有瀏覽器都能訪問楣铁。

使用Ctrl + C停止webpack的服務(wù),運(yùn)行npm run build更扁,編譯成生成環(huán)境所需要的包盖腕。

注意:包的大小從2.61 kB降到了585 bytes
重新看看dist/bundle.js赫冬,你會(huì)發(fā)現(xiàn)代碼變得一團(tuán)糟,UglifyJS對打包后的代碼進(jìn)行了壓縮溃列,運(yùn)行起來是沒有差別的劲厌,但同時(shí)字符數(shù)是相當(dāng)少的。

模塊

對于外部模塊听隐,webpack有多種方式去引入补鼻,其中比較重要的兩種是:

  • ES2015的import方法
  • CommonJS的require()方法

我們可以通過安裝lodash來測試上述方式,并且導(dǎo)入到app.js中遵绰。

npm install lodash --save
// src/app.js
import {groupBy} from 'lodash/collection'

const people = [{
  manager: 'Jen',
  name: 'Bob'
}, {
  manager: 'Jen',
  name: 'Sue'
}, {
  manager: 'Bob',
  name: 'Shirley'
}, {
  manager: 'Bob',
  name: 'Terrence'
}]
const managerGroups = groupBy(people, 'manager')

const root = document.querySelector('#root')
root.innerHTML = `<pre>${JSON.stringify(managerGroups, null, 2)}</pre>`

運(yùn)行npm start重啟webpack并刷新index.html辽幌,你會(huì)在頁面上看到一個(gè)按照manager分好組人名的數(shù)組。
接下來讓我們把這個(gè)數(shù)組部分單獨(dú)放在people.js這個(gè)模塊里椿访。

// src/people.js
const people = [{
  manager: 'Jen',
  name: 'Bob'
}, {
  manager: 'Jen',
  name: 'Sue'
}, {
  manager: 'Bob',
  name: 'Shirley'
}, {
  manager: 'Bob',
  name: 'Terrence'
}]

export default people

我們可以以相對路徑的方式將模塊導(dǎo)入到app.js

// src/app.js
import {groupBy} from 'lodash/collection'
import people from './people'

const managerGroups = groupBy(people, 'manager')

const root = document.querySelector('#root')
root.innerHTML = `<pre>${JSON.stringify(managerGroups, null, 2)}</pre>`

注意:導(dǎo)入像'lodash/collection這種不使用相對路徑的乌企,是那些通過npm安裝的,從/node_modules中引入成玫,你自定義的模塊則需要像'./people'相對路徑的方式引入加酵,通過這種方式可以對兩種模塊進(jìn)行區(qū)分。

加載器

我們已經(jīng)介紹了babel-loader哭当,它是眾多loader中的一種猪腕,能夠告訴webpack當(dāng)遇到不同的文件時(shí)如何處理。比較好的方式是將loader進(jìn)行串聯(lián)钦勘,加載到一個(gè)加載器中陋葡,我們通過從Javascript中引入Sass包來看看loader是如何進(jìn)行工作的。

Sass

這個(gè)轉(zhuǎn)換器包括了三個(gè)單獨(dú)的加載器和node-sass庫:

npm install css-loader style-loader sass-loader node-sass --save-dev

在配置文件中為.scss引入新的規(guī)則:

// webpack.config.js
rules: [{
  test: /\.scss$/,
  use: [
    'style-loader',
    'css-loader',
    'sass-loader'
  ]
}, {
  // ...
}]

注意:不管什么時(shí)候你改變了webpack.config.js中的加載規(guī)則彻采,你都需要通過Ctrl + C然后npm start的方式重啟webpack腐缤。

loader以倒序的方式運(yùn)行:

  • sass-loader轉(zhuǎn)換Sass成CSS
  • css-loader將CSS解析Javascript并解決依賴包問題
  • style-loader將CSS導(dǎo)出成<tag>便簽放在document下

你可以將上述過程想象成函數(shù)的調(diào)用關(guān)系,一個(gè)函數(shù)運(yùn)行的結(jié)果作為另一個(gè)函數(shù)的輸入:

styleLoader(cssLoader(sassLoader('source')))

接下來讓我們增加一個(gè)Sass源文件:

/* src/style.scss */
$bluegrey: #2B3A42;

pre {
  padding: 20px;
  background: $bluegrey;
  color: #dedede;
  text-shadow: 0 1px 1px rgba(#000, .5);
}

現(xiàn)在你可以在你的app.js中直接引入Sass文件:

// src/app.js
import './style.scss'

// ...

刷新index.html你會(huì)看到樣式發(fā)生了變化肛响。

Javascript中的CSS

我們剛剛把Sass作為一個(gè)模塊引入到我們的入口文件中岭粤。

打開dist/bundle.js,搜索pre {特笋。事實(shí)上剃浇,Sass已經(jīng)被編譯成一段CSS的字符串,并以模塊的形式存在猎物。當(dāng)我們在我們的Javascript文件中導(dǎo)入這個(gè)模塊時(shí)虎囚,style-loader就會(huì)將其編譯輸出成內(nèi)嵌的<style>標(biāo)簽。

我知道你在想什么蔫磨?為什么要這么做淘讥?

關(guān)于這個(gè)問題,我在這個(gè)話題中不想說太多质帅,但下面幾個(gè)原因值得思考一下:

  • 如果你想在項(xiàng)目中引入一個(gè)Javascript組件并正常運(yùn)行适揉,可能需要依賴很多其他資源(如HTML, CSS, Images, SVG)留攒,如果我們將所有資源打包到一起,將會(huì)非常易于引入和使用嫉嘀。
  • 去除寫死的代碼:當(dāng)一個(gè)JS組件不再被代碼引入到項(xiàng)目中炼邀,對應(yīng)的CSS也不會(huì)被引入進(jìn)來。而最終打包后的結(jié)果也只會(huì)包含那些被引用的部分剪侮。
  • CSS模塊:由于全局CSS命名空間的存在拭宁,使得改變CSS后是否有副作用不得而知。CSS模塊默認(rèn)情況下將CSS設(shè)成本地瓣俯,并顯示你在Javascript中可以引用的唯一類名杰标。
  • 通過捆綁/分割代碼的巧妙方式減少HTTP請求的數(shù)量。

圖片

最后一個(gè)關(guān)于loader的例子是關(guān)于處理圖片的url-loader彩匕。
在標(biāo)準(zhǔn)HTML文檔中腔剂,圖片通過<img>標(biāo)簽或者background-image屬性獲得。但是通過webpack驼仪,一些小圖片可以以字符串的形式存儲(chǔ)在Javascript中掸犬。通過這種方式,你可以在預(yù)加載的時(shí)候就獲取到圖片绪爸,從而不需要單獨(dú)的請求去請求圖片湾碎。

npm install file-loader url-loader --save-dev

在配置文件中增加一條圖片的規(guī)則:

// webpack.config.js
rules: [{
  test: /\.(png|jpg)$/,
  use: [{
    loader: 'url-loader',
    options: { limit: 10000 } // Convert images < 10k to base64 strings
  }]
}, {
  // ...
}]

通過Ctrl + Cnpm start重啟服務(wù)。
通過下面的命令下載一個(gè)測試圖片:

curl https://raw.githubusercontent.com/sitepoint-editors/webpack-demo/master/src/code.png --output src/code.png

現(xiàn)在可以在app.js中加載圖片資源:

// src/app.js
import codeURL from './code.png'
const img = document.createElement('img')
img.src = codeURL
img.style.backgroundColor = "#2B3A42"
img.style.padding = "20px"
img.width = 32
document.body.appendChild(img)

// ...

這樣頁面中多了一個(gè)img奠货,它的src屬性包含了圖片自身的data URI介褥。

<img src="data:image/png;base64,iVBO..." style="background: #2B3A42; padding: 20px" width="32">

同時(shí),因?yàn)?code>css-loader的緣故递惋,通過url()屬性引入的圖片柔滔,也通過url-loader轉(zhuǎn)換成行內(nèi)元素。

/* src/style.scss */
pre {
  background: $bluegrey url('code.png') no-repeat center center / 32px 32px;
}

編譯后變成:

pre {
    background: #2b3a42 url("data:image/png;base64,iVBO...") no-repeat scroll center center / 32px 32px;
}

模塊到靜態(tài)資源

現(xiàn)在你可以webpack是如何幫助你對將你項(xiàng)目中一系列的依賴資源進(jìn)行打包處理的丹墨,下面這張圖是webpack官網(wǎng)主頁上的廊遍。

雖然Javascript是入口文件嬉愧,但是webpack還是傾向于你的其他類型的資源像HTML, CSS, and SVG能有自己的依賴贩挣,把它們作為構(gòu)建包的一部分。

插件

我們已經(jīng)看過了webpack其中一個(gè)構(gòu)建插件的例子没酣,使用UglifyJsPluginnpm run build腳本可以調(diào)用webpack -p王财,它的作用是與webpack搭配壓縮生成后的包。
當(dāng)loader在單個(gè)文件上操作相應(yīng)變換時(shí)裕便,插件可以在各個(gè)大型代碼塊上交叉運(yùn)行绒净。

公共代碼

commons-chunk-plugin是另一個(gè)核心插件,搭配webpack用來創(chuàng)建在多個(gè)入口文件中使用的擁有公共代碼的單文件模塊偿衰。到目前為止挂疆,我們使用的都是單一入口和單一出口文件改览。但是很多real-world scenarios中更好的方法是使用多文件入口和多文件出口。
如果你在你的應(yīng)用中有兩個(gè)完全獨(dú)立的領(lǐng)域但是卻擁有共同的模塊缤言,舉個(gè)例子宝当,app.js是面向用戶的,admin.js是面向管理員的胆萧,你就可以為他們單獨(dú)創(chuàng)建不同的入口文件庆揩,就像下面這樣:

// webpack.config.js
const webpack = require('webpack')
const path = require('path')

const extractCommons = new webpack.optimize.CommonsChunkPlugin({
  name: 'commons',
  filename: 'commons.js'
})

const config = {
  context: path.resolve(__dirname, 'src'),
  entry: {
    app: './app.js',
    admin: './admin.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js'
  },
  module: {
    // ...
  },
  plugins: [
    extractCommons
  ]
}

module.exports = config

注意對于結(jié)果文件,現(xiàn)在包含了名字跌穗,這樣我們區(qū)分出兩個(gè)不同的結(jié)果文件對應(yīng)不同的入口文件:app.bundle.jsadmin.bundle.js订晌。

commonschunk插件生成了第三個(gè)文件commons.js,他包含了我們?nèi)肟谖募墓材K蚌吸。

// src/app.js
import './style.scss'
import {groupBy} from 'lodash/collection'
import people from './people'

const managerGroups = groupBy(people, 'manager')

const root = document.querySelector('#root')
root.innerHTML = `<pre>${JSON.stringify(managerGroups, null, 2)}</pre>`
// src/admin.js
import people from './people'

const root = document.querySelector('#root')
root.innerHTML = `<p>There are ${people.length} people.</p>`

這些入口文件將會(huì)產(chǎn)生下列文件:

  • app.bundle.js:包括樣式和lodash/collection模塊
  • admin.bundle.js:不包含任何額外模塊
  • commons.js:包含了我們公共的people模塊

我們可以在兩個(gè)入口文件中都引入公共模塊:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Hello webpack</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="dist/commons.js"></script>
    <script src="dist/app.bundle.js"></script>
  </body>
</html>
<!-- admin.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Hello webpack</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="dist/commons.js"></script>
    <script src="dist/admin.bundle.js"></script>
  </body>
</html>

試試在瀏覽器中重新加載index.htmladmin.html锈拨,看看自動(dòng)生成的公共模塊部分。

抽取CSS

另一個(gè)受歡迎的插件是extract-text-webpack-plugin羹唠,它的用途是抽取模塊到對應(yīng)的結(jié)果文件中推励。
下面我們在配置文件中修改.scss的規(guī)則編譯成對應(yīng)的Sass文件,加載CSS肉迫,接著把他們抽取到各自的CSS包中验辞,這樣就可以把它們從Javascript包中移除。

npm install extract-text-webpack-plugin@2.0.0-beta.4 --save-dev
// webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const extractCSS = new ExtractTextPlugin('[name].bundle.css')

const config = {
  // ...
  module: {
    rules: [{
      test: /\.scss$/,
      loader: extractCSS.extract(['css-loader','sass-loader'])
    }, {
      // ...
    }]
  },
  plugins: [
    extractCSS,
    // ...
  ]
}

重啟webpack你會(huì)看到一個(gè)新的打包后的文件app.bundle.css喊衫,你可以照例直接引用它跌造。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Hello webpack</title>
    <link rel="stylesheet" href="dist/app.bundle.css">
  </head>
  <body>
    <div id="root"></div>
    <script src="dist/commons.js"></script>
    <script src="dist/app.bundle.js"></script>
  </body>
</html>

刷新頁面,確認(rèn)CSS已經(jīng)被編譯過了族购,并從app.bundle.js移到了app.bundle.css壳贪,成功了!

代碼拆分

我們已經(jīng)看了幾種代碼拆分的方法:

  • 手動(dòng)創(chuàng)建單獨(dú)的入口文件
  • 自動(dòng)將公共代碼拆分到公共模塊中
  • 使用extract-text-webpack-plugin從編譯后的代碼中抽取出來

拆分包還有其他方法:System.importrequire.ensure寝杖。通過在這些函數(shù)中包含代碼段违施,你可以創(chuàng)建一個(gè)在運(yùn)行時(shí)按需加載的模塊。這個(gè)從根本上提高了性能瑟幕,因?yàn)樵趩?dòng)過程中不需要把所有東西都發(fā)送到客戶端磕蒲。System.import將模塊名作為參數(shù),并返回一個(gè)Promise對象只盹。require.ensure獲取依賴關(guān)系的列表辣往,回調(diào)函數(shù)以及可選的模塊名。
如果應(yīng)用程序的某一部分具有很大的依賴關(guān)系殖卑,則應(yīng)用程序的其余部分就不需要了站削,最好的方式就是拆分到各個(gè)模塊中去。我們通過新建一個(gè)需要依賴d3的模塊dashboard.js來證明這點(diǎn)孵稽。

npm install d3 --save
// src/dashboard.js
import * as d3 from 'd3'

console.log('Loaded!', d3)

export const draw = () => {
  console.log('Draw!')
}

app.js的頂部引入dashboard.js

// ...

const routes = {
  dashboard: () => {
    System.import('./dashboard').then((dashboard) => {
      dashboard.draw()
    }).catch((err) => {
      console.log("Chunk loading failed")
    })
  }
}

// demo async loading with a timeout
setTimeout(routes.dashboard, 1000)

因?yàn)槲覀兗虞d了異步模塊许起,我們需要在配置文件中增加output.publicPath屬性十偶,因此webpack知道去哪里獲取。

// webpack.config.js

const config = {
  // ...
  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/dist/',
    filename: '[name].bundle.js'
  },
  // ...
}

運(yùn)行npm build操作园细,你會(huì)看到一個(gè)新的神秘的打包文件0.bundle.js扯键。

注意webpack為了保持誠實(shí),通過凸現(xiàn)[big]的包來讓你保持關(guān)注珊肃。
這個(gè)0.bundle.js將會(huì)通過JSONP的請求按需加載荣刑,所以從文件目錄中獲取將不在有效,我們需要啟動(dòng)一個(gè)服務(wù)來獲取文件伦乔。

python -m SimpleHTTPServer 8001

打開瀏覽器厉亏,輸入http://localhost:8001/
加載一秒鐘后,你會(huì)獲得一個(gè)GET請求烈和,我們動(dòng)態(tài)生成了/dist/0.bundle.js文件爱只,在控制臺上打印除了"Loaded!",成功招刹!

webpack開發(fā)服務(wù)器

當(dāng)文件改變時(shí)恬试,實(shí)時(shí)地重新加載能提高開發(fā)者的開發(fā)效率。只要安裝它疯暑,并且以webpack-dev-server的形式啟動(dòng)训柴,就可以體驗(yàn)啦。

npm install webpack-dev-server@2.2.0-rc.0 --save-dev

修改package.json中的start腳本:

"start": "webpack-dev-server --inline",

重新運(yùn)行npm start妇拯,在瀏覽器中打開http://localhost:8080
試著去改變src目錄中任何文件幻馁,如改變people.js中的任意一個(gè)名字,或者style.scss中的任意樣式越锈,去看看它如何實(shí)時(shí)改變仗嗦。

熱模塊替換(熱更新)

如果你對實(shí)時(shí)重新加載印象深刻,那么hot module replacement(HMR)一定會(huì)讓你吃驚不已甘凭。

現(xiàn)在是2017年了稀拐,你在工作中已經(jīng)可以在單頁面應(yīng)用中使用全局狀態(tài)了。在開發(fā)過程中丹弱,你可能會(huì)對組件進(jìn)行許多小的修改德撬,并且希望能在瀏覽器中看到修改后生成的結(jié)果,這樣可以實(shí)時(shí)去更改蹈矮。但是通過刷新頁面或者實(shí)時(shí)熱更新并不能改變?nèi)值臓顟B(tài)砰逻,你就必須重頭開始鸣驱。但是HMR永遠(yuǎn)地改變了這一問題泛鸟。

最后對package.json中的start腳本做修改:

"start": "webpack-dev-server --inline --hot",

app.js中告訴webpack去接受這個(gè)模塊以及對應(yīng)依賴的熱更新。

if (module.hot) {
  module.hot.accept()
}

// ...

注意:webpack-dev-server --hot設(shè)置了module.hottrue踊东,但只是在開發(fā)過程中北滥。當(dāng)以生產(chǎn)模式打包時(shí)刚操,module.hot被設(shè)成了false,這樣這些包就被從結(jié)果中抽離了再芋。

webpack.config.js中增加一個(gè)NamedModulesPlugin插件菊霜,去改善控制臺的記錄功能。

plugins: [
  new webpack.NamedModulesPlugin(),
  // ...
]

最后我們在頁面中增加一個(gè)<input>元素济赎,我們可以在里面增加一些文字鉴逞,用來確保我們更改自己模塊時(shí)頁面不會(huì)刷新。

<body>
  <input />
  <div id="root"></div>
  ...

運(yùn)行npm start重啟服務(wù)司训,觀察熱更新如何工作吧构捡。

為了實(shí)驗(yàn),在input框中輸入“HMR Rules”壳猜,接著改變一個(gè)people.js中的名字勾徽,你會(huì)發(fā)現(xiàn)頁面在不刷新也能做出修改,而忽略input的狀態(tài)统扳。

這只是一個(gè)簡單的例子喘帚,但是希望你能看到其廣泛的用途。在諸如React的開發(fā)模式中咒钟,你可能有很多"啞巴"組件是與他們的狀態(tài)分離開的吹由,通過熱更新,這些組件將不會(huì)失去狀態(tài)朱嘴,也能實(shí)時(shí)更新溉知,因此你將獲得及時(shí)的反饋。

熱更新CSS

修改style.scss文件中<pre>元素的背景顏色腕够,你發(fā)現(xiàn)他并沒有被HMR替換级乍。

pre {
  background: red;
}

事實(shí)證明當(dāng)你使用style-loader時(shí),CSS的熱更新將會(huì)免費(fèi)為你提供而不需要你做任何特殊處理帚湘。我們只需要斷開CSS模塊與最終抽取的包之間的鏈接玫荣,這個(gè)包是無法被替換的。

如果我們將Sass規(guī)則恢復(fù)到原始狀態(tài)捅厂,并從插件列表中刪除extractCSS,那么您也可以看到Sass的熱重新加載焙贷。

{
  test: /\.scss$/,
  loader: ['style-loader', 'css-loader','sass-loader']
}

HTTP/2

使用像webpack這樣的模塊打包工具的主要好處之一是,您可以通過控制資源的構(gòu)建方式以及在客戶端上的獲取方式辙芍,從而幫助你提高性能。多年以來故硅,它被認(rèn)為是最佳實(shí)踐,通過連接文件減少客戶端請求〕孕疲現(xiàn)在還是有效,但是HTTP2在單一請求中發(fā)送多文件徘层,因此連接文件的方式不不再是"銀彈"。你的應(yīng)用程序?qū)嶋H上可以從多個(gè)小文件單獨(dú)緩存趣效,但客戶端可以獲取單個(gè)更改的模塊,而不必再次獲取大部分相同內(nèi)容的整個(gè)包英支。

Webpack的創(chuàng)始人Tobias Koppers的撰寫了一篇內(nèi)容豐富的帖子,解釋了為什么打包仍然很重要干花,即使在HTTP/2時(shí)代妄帘。

想了解更多請參考webpack & HTTP/2

寫在結(jié)尾的話

我真心希望你已經(jīng)發(fā)現(xiàn)這個(gè)介紹webpack 2的文章對你有幫助,并能夠開始很好使用它池凄。圍繞webpack的配置抡驼,加載程序和插件可能需要一些時(shí)間,但是了解這個(gè)工具的工作原理后會(huì)對你有很大幫助肿仑。

文檔仍在進(jìn)行更新中致盟,但如果您想將現(xiàn)有的Webpack1項(xiàng)目移到Webpack2,則可以參考Migrating from v1 to v2尤慰。

webpack是否是你打包的選擇馏锡,從評論中你就可以知曉。

本文由Scott Molinari伟端,Joan YinJoyce Echessa進(jìn)行了同行評審杯道。 感謝SitePoint的同行評議人員,使SitePoint內(nèi)容成為最棒的內(nèi)容责蝠!

本文翻譯自A Beginner’s Guide to Webpack 2 and Module Bundling
翻譯者:Allen Gong

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末党巾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子霜医,更是在濱河造成了極大的恐慌齿拂,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肴敛,死亡現(xiàn)場離奇詭異署海,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門叹侄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巩搏,“玉大人昨登,你說我怎么就攤上這事趾代。” “怎么了丰辣?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵撒强,是天一觀的道長笙什。 經(jīng)常有香客問我,道長芽隆,這世上最難降的妖魔是什么统屈? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任愁憔,我火速辦了婚禮,結(jié)果婚禮上半抱,老公的妹妹穿的比我還像新娘窿侈。我一直安慰自己秋茫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布乘瓤。 她就那樣靜靜地躺著衙傀,像睡著了一般统抬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钙畔,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天擎析,我揣著相機(jī)與錄音揍魂,去河邊找鬼棚瘟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛庄蹋,可吹牛的內(nèi)容都是我干的迷雪。 我是一名探鬼主播振乏,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼慧邮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耻矮?” 一聲冷哼從身側(cè)響起裆装,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤哨免,失蹤者是張志新(化名)和其女友劉穎昙沦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體采桃,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年工扎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肢娘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔬浙。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贞远,死狀恐怖蓝仲,靈堂內(nèi)的尸體忽然破棺而出官疲,到底是詐尸還是另有隱情,我是刑警寧澤垢夹,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布果元,位于F島的核電站而晒,受9級特大地震影響阅畴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜监署,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一钠乏、第九天 我趴在偏房一處隱蔽的房頂上張望昵仅。 院中可真熱鬧累魔,春花似錦垦写、人聲如沸梯投。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蒸甜,卻和暖如春余佛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恨憎。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工憔恳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痢甘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓者铜,卻偏偏與公主長得像作烟,于是被迫代替她去往敵國和親拿撩。 傳聞我的和親對象是個(gè)殘疾皇子如蚜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 最近在學(xué)習(xí) Webpack,網(wǎng)上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學(xué)習(xí) Webpack 的...
    My_Oh_My閱讀 8,173評論 40 247
  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺,特此分享以備自己日后查看型宙,也希望更多的人看到...
    小小字符閱讀 8,147評論 7 35
  • 在現(xiàn)在的前端開發(fā)中妆兑,前后端分離毛仪、模塊化開發(fā)、版本控制腺逛、文件合并與壓縮刨晴、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,433評論 1 32
  • GitChat技術(shù)雜談 前言 本文較長狈癞,為了節(jié)省你的閱讀時(shí)間茂契,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,681評論 7 110
  • 黃磊:婚姻就是該摸摸透硝,該抱抱 “該摸摸疯搅,該抱抱,沒事就得么么噠罪治。” “一定是要能吃到鍋里觉义,睡到一個(gè)床上∑缧玻” ......
    乖乖愛閑逛閱讀 754評論 0 0