Webpack飞行手册
前言
在學習 Webpack 之前,我們需要了解一個概念:模塊。
何為模塊?
如果你曾學過 Java , C# 之類的語言,一定會知道 Java 中的 import 或 C# 中的 using 吧?
比如:我想在 C# 中進行數據庫操作,我只需要在代碼頭部加上 下面這兩段代碼即可。
using System.Data; using System.Data.SqlClient;
這兩段代碼可以看成 兩個與數據庫操作相關的模塊。 當我們需求是數據庫,或者是讀取 IO 等其他操作,我們便加載其他不同的模塊。
很明顯,這實現了編程中的一個非常重要的功能 按需加載。
在前端中 模塊又該如何定義呢? 按照我個人的理解:
- 在 HTML 中 模塊 便是一個組件
- 在 CSS 中 模塊 便是一個局部樣式
header{display:block; } header h1{font-size: 60px; }
- 在 Javascript 中 模塊 便是一個封裝著方法或數據的腳本文件
let People = { name: "Simon" } ; module.exports = People;
而我們又該怎樣實現 在前端中加載模塊呢?
下面是兩個很常見的例子:
在 Less 中
@import "header"; @import "layout"; @import "footer";
在 Javascript
// CommonJS const $ = require("jQuery");//es6 let People = { name: "Simon" } ; module.exports = People;import "./layer.less"; import tpl from "./layer.ejs";如果你直接運行以上代碼,瀏覽器并不會解析,這個時候,就要依靠 Webpack 了!
Webpack是什么
Webpack 是一款目前非常流行的前端模塊打包工具,可以將項目中所加載的模塊進行打包,以及將 一些瀏覽器不支持的語言進行轉換。
Webpack 的打包原理是 先找到入口文件,遞歸探索出所有依賴的模塊,最后 利用 Loader 進行不同文件類型的處理,打包成一個 Javascript 文件。
其中,Webpack 的兩個最核心原理分別是:
當然 Webpack 的作用不止加載模塊這么簡單,前端的常用需求通常都可以實現:利用 Loader 轉換 es6 、 Less 、 Typescript ,還可利用插件 開發多頁面應用,等等諸多強大功能。
正文
下面,我將講解 Webpack 的具體使用和配置。
安裝
我一般在項目中使用 Webpack,都是先執行下面這四條命令進行 Webpack 的安裝
npm install -g webpack
在全局安裝 Webpack,第一次使用時 執行
npm install --save-dev webpack
將 Webpack 安裝到你的項目
npm init
npm初始化,會詢問你的項目信息,可以回車跳過
npm install --save-dev webpack-dev-server
在當前項目,安裝 Webpack 服務器
安裝完成后,便是建立配置文件了。
基本配置
在項目根目錄下新建名為 webpack.config.js 的文件,
基本上 一個配置文件的大體結構就是下面這樣:
modules.export={entry:{/* 入口文件 */},output:{/* 出口文件 */},module:{/* Loader */rules:[{},{},{}]},plugins:[ /* 插件 */ ],devtool: ...devServer: {...}resolve:{...} }
我們下面就先分析 modules.export 各個屬性
入口
entry 代表是入口文件,Webpack 工作的開始。
Webpack 會遞歸的探索出 入口文件中所依賴的模塊,并按照順序 利用 Loader 進行處理。
官網給出了其 3 種數據類型:
? ? ?2.數組
? ? ?數組中的每一項都會被打包,形成互不依賴的文件
entry: ["app.js","main.js"];? ? ?3.對象
? ? ?對象中的每一個屬性都會被打包,形成互不依賴的文件
一般入口文件中多是 import 或者 require 等模塊導入命令。
出口
output 顧名思義,Webpack打包后文件的具體配置 常用的屬性有 4 個
path: ${__dirname }/dist
打包后文件所在路徑
filename: "js/[name].js"
打包后文件的名字,這里有 4 種常用的寫法
自定義
[name].js
代表的便是入口的文件名
[hash].js
此次打包后的hash值
[chunkhash]
該塊打包后的hash值
publicPath: "http://cdn.com/"
上線時的公共路徑,主要應用于線上
chunkFilename: 'js/[name].js'
按需加載模塊時輸出的文件名稱
Loader
Loader 是 Webpack 中最振奮人心的東西了!
將一切瀏覽器不支持的語言,處理成 瀏覽器可以支持。 針對各個文件類型,都有各種的 Loader 等你去挖掘。
Loader 的工作方式 是從右向左執行,鏈式地按照順序進行編譯。 loader 鏈中的第一個返回值給下一個 loader,在最后一個 loader,返回所預期的結果。
loader 可以是同步或異步函數,也可使用 options 對象去接受配置參數。
基礎結構
module:{rules:[{test:/\.xxx$/,//以xxx結尾的文件loader: "xxx-loader",exclude: {排除的路徑},include: {包含的路徑},options: {Loader配置}}] }
可以很清楚的看到,Loader 利用 test 的正則 找到各個類型文件,然后使用 loader 進行處理,便可轉換成瀏覽器支持的文件。
其中我知道的 loader 的寫法有兩種:
loaders:[{loader:"style-loader"},{ loader: "css-loader?modules", options: { importLoaders: 1 } },{loader: "less-loader"} ]
loader: "style-loader!css-loader?importLoaders=1!less-loader"
下面介紹三個 前端必備的 Loader 方式
css
?style-loader
通過注入<style>標簽將 CSS 添加到 DOM
css-loader
css-loader像import / require()一樣解釋@import和url()并解析它們。
postcss-loader
補充 不兼容的css屬性 的瀏覽器前綴
less-loader
將Less 轉換成 CSS
javascript
babel
主要用于將 es6 轉換成 es2015
npm install --save-dev babel-core babel-loader babel-preset-es2015
圖片 & 字體
file-loader
用于壓縮文件
url-loader
如果文件下于 規定限制,將會轉換成 二進制編碼
ejs
另外 我想介紹一下 自己常用的 ejs-loader
npm install --save-dev ejs-loader
test:/\.ejs$/ , loader:"ejs-loader",
<div class="layer"><div><%= name %></div><% for(let i = 0; i < Array.length;++i) { %><%= Array[i] %><% } %> </div>
//入口文件 import tpl from "./layer.ejs";document.body.innerHTML = tpl({name:"Simon",arr:["Apple","Xiaomi"] });
運行 生成后的頁面 ,便會發現 ejs 組件已經被加進去了, 想象一下,我們在平時工作中是否可以把 一個輪播圖,或者 排行榜 、評論 當成一個組件呢?
插件
plugins
在日常工作中,我們使用 Loader 處理不同類型的文件,當有某種其他方面的需求時,比如 抽離 CSS 、生成多頁面 HTML ,plugins 便派上了用場。
插件的使用,一般都要先 require 出來,然后在 plugins 屬性中 進行初始化
const htmlWebpackPlugin = require("html-webpack-plugin"); ...... plugins: [ new htmlWebpackPlugin({/* options */}) ]
下面將介紹 一些工作中常用的插件
clean-webpack-plugin
主要用于 打包之前 先清空 打包目錄下的文件,防止文件混亂
html-webpack-plugin
主要用于生成HTML,可以規定 模板HTML,也可以為 模板傳入參數,壓縮文件等
new htmlWebpackPlugin({//打包后的文件名filename: "index.html",//模板template: "index.html",//為true自動生成script標簽添加到html中//或者寫 body/head 標簽名inject: false,//js的注入標簽//通過<%= htmlWebpackPlugin.options.title %>引用title: "參數title",//通過<%= htmlWebpackPlugin.options.date %> 引用date: new Date()//網站的圖標favicon: 'path/to/yourfile.ico'//生成此次打包的hash//如果文件名中有哈希,便代表有 合理的緩沖hash: true,//排除的塊excludeChunks: [''],//選中的塊 與入口文件相關chunks: ['app','people'],//壓縮minify:{ removeComments: true,collapseWhitespace: true,minifyJS: true, minifyCSS: true,minifyURLs: true,}}),
那么問題來了,我們在模板文件中 又該怎樣使用參數呢? 直接按照 ejs 的語法寫入 html 文件即可!
<!DOCTYPE html> <html lang="en"> <%= htmlWebpackPlugin.options.date %> </html>
生成后的模板文件
<!DOCTYPE html> <html lang="en"> Thu Dec 07 2017 10:01:58 GMT+0800 (中國標準時間) </html>
另外,如果想生成 多頁面應用,只需 將上面的配置,多復制幾遍即可。
new htmlWebpackPlugin({ filename: "index1.html", } new htmlWebpackPlugin({ filename: "index2.html", } new htmlWebpackPlugin({ filename: "index3.html", }
3.UglifyJsPlugin
主要用于壓縮 Javascript 文件
4.webpack.ProvidePlugin
自動加載模塊,全局使用變量,下面借助 官網的DEMO
open-browser-webpack-plugin
打開服務器后 會自動打開瀏覽器端口,用起來 很方便
HotModuleReplacementPlugin
熱更新插件
常用命令
-
webpack
最基本的啟動webpack命令
-
webpack -w
監控代碼變化,實時進行打包更新
-
webpack -p
對打包后的文件進行壓縮,利用線上發布
-
webpack -d
提供SourceMaps,方便調試代碼
-
webpack --colors
輸出結果帶彩色,可以更詳細的查看信息
-
webpack --profile
輸出性能數據,可以看到每一步的耗時
devtool
不知道你現在時候有沒有一個想法? webpack 打包后的文件就一定正確無誤嗎? 如果發生錯誤的話,該怎么辦呢?
devtool 屬性 便提供了生成 sourcemap 的功能,具體有下面這些選項。
source-map
此選項具有最完備的source map,但會減慢打包的速度;
cheap-module-source-map
生成一個不帶列映射的map
eval-source-map
使用eval打包源文件模塊,生成一個完整的source map。
cheap-module-eval-source-map
這是最快生成source map的方法,生成后的Source Map 會和打包后的 JavaScript 文件同行顯示,但沒有列映射,所以慎用
devServer
contentBase: "./dist",
本地服務器所加載的頁面所在的目錄
historyApiFallback: true,
再找不到文件的時候默認指向index.html
inline: true,
當源文件改變時會自動刷新頁面
hot: true,
熱加載開啟
port:8080
設置默認監聽端口
resolve
extensions: [".js", ".html", ".css", ".txt","less","ejs","json"],
自動擴展文件后綴名,意味著我們require模塊可以省略不寫后綴名
alias: { Temp: path.resolve(__dirname, "src/templates/") }
模塊別名定義,直接 require('AppStore') 即可,方便后續直接引用別名
其他功能
path
常用于字符串拼接路徑。
有兩個 API
path.resolve()
將相對路徑轉換成絕對路徑
const aPath = path.resolve("__dirname","js","main.js"); // aPath = 當前目錄下的 js 文件夾的 main.js 文件的路徑
? 2.path.join()
? ? 對路徑進行拼接
熱更新
上面我們已經提過了 webpack -w 命令,它可以實時的監控 代碼的改變,從而自動進行打包,但是 有個缺點 在于它不能及時的刷新界面。
在我們 開啟服務器后,是無法使用 此命令的,這個時候,如果你還想進行 自動打包,又想自動刷新界面,熱更新 便是不二之選,另外 Webpack 只會熱更新 發生改變的模塊,不會重新加載整個頁面,便可加快開發速度。
開啟步驟:
devServer: {hot: true,//熱加載開啟inline: true,//文件改變時會自動刷新頁面 }
const webpack = require("webpack"); //Other property plugins: [new webpack.HotModuleReplacementPlugin() ]
結束語
現在是一個 Web 技術蓬發的時代,一定要把握住時代潮流。
原文發布時間為:2017年12月08日
原文作者:SimonMa
本文來源:掘金 如需轉載請聯系原作者
?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Webpack飞行手册的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot—— @Compon
- 下一篇: 最详细的phpmailer的使用方法