標籤:應用程式 doc 背景 exp 開發環境 src 新手 處理 本地
前面的話
在webpack出現之前,市面上已經存在的模組管理和打包工具並不適合大型的項目,尤其單頁面 Web 應用程式。最緊迫的原因是如何在一個大規模的程式碼程式庫中,維護各種模組資源的分割和存放,維護它們之間的依賴關係,並且無縫的將它們整合到一起產生適合瀏覽器端請求載入的靜態資源。webpack是當下最熱門的前端資源模組化管理和打包工具。它可以將許多鬆散的模組按照依賴和規則打包成符合生產環境部署的前端資源。還可以將按需載入的模組進行代碼分隔,等到實際需要的時候再非同步載入
webpack的內容豐富且雜亂,對於新手並不友好。本文以一個執行個體的形式,對webpack的重要概念進行介紹,並著重說明如何使用webpack
概述
webpack是一個模組打包器。
【特點】
webpack有以下特點
代碼拆分
webpack 有兩種組織模組依賴的方式,同步和非同步。非同步依賴作為分割點,形成一個新的塊。在最佳化了依賴樹後,每一個非同步區塊都作為一個檔案被打包。
Loader
Webpack 本身只能處理原生的 JavaScript 模組,但是 loader 轉換器可以將各種類型的資源轉換成 JavaScript 模組。這樣,任何資源都可以成為 Webpack 可以處理的模組。
智能解析
Webpack 有一個智能解析器,幾乎可以處理任何第三方庫,無論它們的模組形式是 CommonJS、 AMD 還是普通的 JS 檔案。甚至在載入依賴的時候,允許使用動態運算式 require("./templates/" + name + ".jade")。
外掛程式系統
Webpack 還有一個功能豐富的外掛程式系統。大多數內容功能都是基於這個外掛程式系統啟動並執行,還可以開發和使用開源的 Webpack 外掛程式,來滿足各式各樣的需求。
快速運行
Webpack 使用非同步 I/O 和多級緩衝提高運行效率,這使得 Webpack 能夠以令人難以置信的速度快速增量編譯
【安裝】
用 npm 安裝 Webpack
$ npm install webpack
一個常見的問題是:安裝webpack後,無法使用webpack命令
這是因為只進行了本地安裝,沒有全域安裝,輸入如下代碼進行全域安裝後即可運行
$ npm install webpack -g
使用
首先建立一個靜態頁面index.html和一個JS入口檔案entry.js
<!-- index.html --><html><head> <meta charset="utf-8"></head><body> <script src="bundle.js"></script></body></html>
// entry.jsdocument.write(‘It works.‘)
然後編譯 entry.js 並打包到 bundle.js:
$ webpack entry.js bundle.js
打包過程會顯示日誌:
Hash: f47511e706e3de8f2417Version: webpack 2.6.1Time: 47ms Asset Size Chunks Chunk Namesbundle.js 2.66 kB 0 [emitted] main [0] ./entry.js 27 bytes {0} [built]
用瀏覽器開啟 index.html 將會看到 It works.
接下來添加一個模組 module.js 並修改入口 entry.js:
// module.jsmodule.exports = ‘It works from module.js.‘
// entry.jsdocument.write(‘It works.‘)document.write(require(‘./module.js‘)) // 添加模組
重新打包 webpack entry.js bundle.js 後重新整理頁面看到變化 It works.It works from module.js.
Hash: 09733456f2c5b24a4845Version: webpack 2.6.1Time: 61ms Asset Size Chunks Chunk Namesbundle.js 2.83 kB 0 [emitted] main [0] ./module.js 43 bytes {0} [built] [1] ./entry.js 75 bytes {0} [built]
Webpack會分析入口檔案,解析包含依賴關係的各個檔案。這些檔案(模組)都打包到 bundle.js 。Webpack 會給每個模組分配一個唯一的 id 並通過這個 id 索引和訪問模組。在頁面啟動時,會先執行 entry.js 中的代碼,其它模組會在運行 require 的時候再執行
Loader
Webpack 本身只能處理 JavaScript 模組,如果要處理其他類型的檔案,就需要使用 loader 進行轉換。
Loader 可以理解為是模組和資源的轉換器,它本身是一個函數,接受源檔案作為參數,返迴轉換的結果。詳細資料移步至此
接上面的例子,我們要在頁面中引入一個CSS檔案style.css,要使用require("!style-loader!css-loader!./style.css")代碼,代碼讀取順序從右向左,表示首頁將 style.css 也看成是一個模組,先載入style.css,然後用 css-loader 來讀取它,再用 style-loader 把它插入到頁面中
/* style.css */body { background: yellow; }
修改 entry.js:
require("style-loader!css-loader!./style.css") document.write(‘It works.‘)document.write(require(‘./module.js‘))
安裝 loader:
npm install css-loader style-loader
重新編譯打包,重新整理頁面,就可以看到黃色的頁面背景了
如果每次 require CSS 檔案的時候都要寫 loader 首碼,是一件很繁瑣的事情。我們可以根據模組類型(副檔名)來自動綁定需要的 loader。
將 entry.js 中的 require("!style-loader!css-loader!./style.css") 修改為 require("./style.css") ,然後執行
$ webpack entry.js bundle.js --module-bind ‘css=style-loader!css-loader‘
顯然,這兩種使用 loader 的方式,效果是一樣的
配置
Webpack 在執行的時候,除了在命令列傳入參數,還可以通過指定的設定檔來執行。預設情況下,會搜尋目前的目錄的 webpack.config.js 檔案,這個檔案是一個 node.js 模組,返回一個 json 格式的配置資訊對象,或者通過 --config選項來指定設定檔。
繼續我們的案例,在根目錄建立 package.json 來添加 webpack 需要的依賴:
{ "name": "project", "version": "1.0.0", "devDependencies": { "css-loader": "^0.28.4", "style-loader": "^0.18.2", "webpack": "^2.6.1" }}
別忘了運行 npm install。然後建立一個設定檔 webpack.config.js,在下面的配置中,對一個單獨的module對象定義了rules屬性,裡麵包含兩個必須屬性:test和use。相當於告訴webpack compiler,碰到「在require()/import語句中被解析為‘.css‘的路徑」時,在把它們添加並打包之前,要先使用css-loader後使用style-loader去轉換
var webpack = require(‘webpack‘);module.exports = { entry: ‘./entry.js‘, //入口檔案 output: { path: __dirname,//出口路徑 filename: ‘bundle.js‘//出口名稱 }, module: { rules: [ {test: /\.css$/,use: [ ‘style-loader‘, ‘css-loader‘ ]} ] }}
同時簡化 entry.js 中的 style.css 載入方式:
require(‘./style.css‘);
最後運行 webpack,可以看到 webpack 通過設定檔執行的結果和上一節通過命令列 webpack entry.js bundle.js --module-bind ‘css=style!css‘ 執行的結果是一樣的
如果設定檔並不叫做預設的webpack.config.js,而是其他的名稱,如test.js,則需要設定如下命令進行打包
webpack --config test.js
外掛程式
外掛程式可以完成更多 loader 不能完成的功能。外掛程式的使用一般是在 webpack 的配置資訊 plugins 選項中指定。Webpack 本身內建了一些常用的外掛程式,還可以通過 npm 安裝第三方外掛程式。詳細資料移步至此
想要使用一個外掛程式,只需要require()它,然後把它添加到plugins數組中。內建外掛程式則不需要require,直接使用即可
接下來,我們利用一個最簡單的 BannerPlugin 內建外掛程式來實踐外掛程式的配置和運行,這個外掛程式的作用是給輸出的檔案頭部添加註釋資訊。
修改 webpack.config.js,添加 plugins:
var webpack = require(‘webpack‘);module.exports = { entry: ‘./entry.js‘, //入口檔案 output: { path: __dirname,//出口路徑 filename: ‘bundle.js‘//出口名稱 }, module: { rules: [ {test: /\.css$/,use: [ ‘style-loader‘, ‘css-loader‘ ]} ] }, plugins: [ new webpack.BannerPlugin(‘This file is created by xiaohuochai‘) ]}
然後運行 webpack,開啟 bundle.js,可以看到檔案頭部出現了我們指定的注釋資訊:
/*! This file is created by xiaohuochai *//******/ (function(modules) { // webpackBootstrap/******/ // The module cache/******/ var installedModules = {};// 後面代碼省略
開發環境
當項目逐漸層大,webpack 的編譯時間會變長,可以通過參數讓編譯的輸出內容帶有進度和顏色
$ webpack --progress --colors
如果不想每次修改模組後都重新編譯,那麼可以啟動監聽模式。開啟監聽模式後,沒有變化的模組會在編譯後緩衝到記憶體中,而不會每次都被重新編譯,所以監聽模式的整體速度是很快的
$ webpack --progress --colors --watch
比如,執行以上命令後,修改‘style.css‘的body的背景顏色為紅色,不用重新編譯,重新整理頁面後,頁面即發生改變
當然,使用 webpack-dev-server 開發服務是一個更好的選擇。它將在 localhost:8080 啟動一個 express 靜態資源 網頁伺服器,並且會以監聽模式自動運行 webpack,在瀏覽器開啟 http://localhost:8080/ 或 http://localhost:8080/webpack-dev-server/ 可以瀏覽項目中的頁面和編譯後的資源輸出,並且通過一個 socket.io 服務即時監聽它們的變化並自動重新整理頁面
# 安裝$ npm install webpack-dev-server -g# 運行$ webpack-dev-server --progress --colors
比如,執行以上命令後,修改‘style.css‘的body的背景顏色為藍色,不用重新編譯,也不用重新整理頁面,頁面即發生改變
webpack入門