webapck 基本配置以及plugin和loader的用法

可以結合慕課網的視頻來讀這篇文章,地址:http://www.imooc.com/learn/802

Webpack簡介:

給JS準備的一個打包工具,可以把很多的模塊打包成很好的靜態,且有一個自己的特性叫做代碼分割 ,webpack有個整個loader的概念,通過loader可以處理各種各樣的文件,可處理css common.js 圖片文件 AMD less文件 es6 自定義文件如:vue文件等。

官方的定義:它是一個模塊的打包器。

大概的處理過程:左邊 .css .js .png 等都視為一個模塊通過箭頭之間有依賴關系的模塊群之后webpack會對依賴的模塊群進行處理把它打包成瀏覽器可以直接運行的JS文件和CSS文件還有真實的圖片

Webpack的最大特點是代碼分割;
代碼分割:在項目中只是加載當時只需要的那部分文件;

####### Webpack的目標:

  • 切分它的依賴數,會把它的依賴數切分到不同的代碼塊里,然后按需
    加載這些代碼塊(類似于懶加載概念)
  • 為了保持初始化的加載時間更少
  • 任何一個靜態的資源都是被視為一個模塊,在項目中被引用(在開發過程中有很多的便利)
  • 它可以整合一些第三方的類庫,并且把第三方類庫也視為一個模塊,并在項目中引用
  • 打包的過程中可以自定義,幾乎每一個部分都可以自定義,做一些自己想做的事情,非常適合大型項目
Webpack和其他打包工具的不同:
  • code Spliting 代碼分割
  • loaders
  • 模塊熱更新(在開發過程中大大提高的調試和效率)

webpack 安裝

進入目錄 cd xxx
建立一個文件夾 如:mkdir webpack-text
進入文件的 cd wabpack-text
在文件下初始化 npm init
全局安裝webpack:npm install webpack -g
初始化完之后裝webk:npm install webpack --save-dev
安裝完之后可以看見項目下有 package.json和一個node_modules的一個文件,安裝完之后用編譯器打開當前目錄,就可以創建開始編碼了,寫好了之后,就可以在命令中輸入如:
Webpack hello.js hello.bundle.js webpack直接跟文件的名稱后面再去跟打包后的名稱
這就完成一次簡單的打包操作
操作成功之后它會給我們一部分值(在命令行中可以看到以下參數):

  • 哈希值 webpack版本
  • 這次打包花費的時間
  • Asset 顯示這次打包生成的文件
  • size這次打包文件的大小
  • Chunks 這次打包的分塊
  • chunk Names 這次打包的塊名稱
打包文件后在文件中看到的效果

Webbpack 支持三種的模塊化方式AMD commonjs es6的模塊化


圖中畫圈的部分用的就是commonjs
圖中webpack把上上圖中畫圈的commonjs中的require 轉換成webpack內置的__webpack_require_(1)
圖中如果沒有給webpack安裝專門處理css的loader就會報錯

安裝好之后還要指定相應的loader 才可以引入如:require(‘css-loader!./style.css’) 加上之后就可以執行了

image.png

要是引入的css生效還需要借助 style-loader! 如:require(‘style-loader!css-loader!./syle.css’)

image.png
image.png
圖中要使引入的css生效,還的引入style-loader

很多人就有了疑問,我每次都得加這么多loader么?那不是很麻煩

對引入的css的文件,還有一種處理方式:在命令行輸入 :
Webpack hello.js hello.bund --module-bind’css=style-loader!css-loader’ 這個方法也很麻煩,每次文件改變都得輸入這個命令,下面是更簡便方法,文件改變打包的文件也自動更新、自動打包。
對于以上兩種方法也和繁瑣可以通過文件自動打包,自動更新 如:Webpack hello.js hello.bund --module-bind’css=style-loader!css-loader’ --watch
Webpack 還有可以看到打包的過程的方法 : 右下可以看到百分比讀條(右下可以看到短暫的百分比讀條)
Webpack hello.js hello.bund --module-bind’css=style-loader!css-loader’ --progress

特別注意:上圖path中的要寫對

webpack的基本配置以及webpack配置里面的一些參數的功能

webpack 的配置文件 在webpack下建立一個 webpack.config.js 的文件 為什么要這樣建立配置文件:
如果直接使用webpack這個命令的話,webpack會在根目錄下尋找webpack.config.js 把它作為默認的配置取運行
配置文件的最基礎的配置

 module.exports = {
               entry: ‘./src/srcipt/main.js’,  //表示配置入口
               output:  {
                        path:  ‘./dist/js’,   //指明打包以后的文件放到什么地方
                        filename: ‘bundle.js’  //打包以后的文件名
                           } 
                       }

配置好之后直接在命令行輸入 webpack 就可以執行了

若給配置改個名的處理方法 如 配置不叫 webpack.config.js 而是 webpack.dev.config.js
可以通過命令行來通過webpack的參數config來指定 如:
Webpack --config webpack.dev.config.js 這樣就生效了

在有配置的情況下怎么加參數 :
可以配合npm的腳本 package.json 中的 “scripts”中定義一段腳本 :
“webpack”: “Webpack --config webpack.config.js --progress --display-module --colors”
在腳本中定義好之后就可以在命令行中輸入:
npm run webpack 腳本就可以運行了

數組的方式:入口文件放到數組里面
 module.exports = {
               entry: [‘./src/srcipt/main.js’,’./src/script/a.js’],  //表示配置入口  處理文件多的話另一種寫法
               output:  {
                        path:  ‘./dist/js’,   //指明打包以后的文件放到什么地方
                        filename: ‘bundle.js’  //打包以后的文件名
                           } 
                       }
圖中是后臺運行打包數組的總的文件的情況
圖中的0模塊就是把兩個不相干的入口文件,把它們require到一起,相當于打包到一起了,這樣就可以在開發中使用它了

#######entry是對象的方式

圖中要是entry是對象的模式,下面output需要寫成[name ]、[hash]、[chunkhash]這三種,若寫成bundle.js這種的,就會報錯
圖中紅色圓圈是上上那個圖中[name]-[hash]

注意:文件上面的哈希值互相不一樣了,可以認為是文件的版本號,也可以認為是MD5值(MD5算法就是為了保證每個文件的唯一性),也就是說只有當這個文件發生改變的時候,這個哈希值才會變化,這個特點,在我們的項目中對靜態資源版本號的管理是非常有用的,平時我們項目中上線的時候,正好需要只上線那些已經被我們改過的文件

生成項目中的的html頁面文件

就想上面對象為入口的話,它的文件名是[name]是不確定的,難道每一次這種打包都要手動去設置路徑嗎,那豈不是非常麻煩:用webpack的插件來解決這個問題

先用npm install html-webpack-plugin --save-dev

好了之后去webpack的配置文件webpack.confing.js中

用commonjs的方法引入webpack的插件模塊
圖中對引入的進行初始化
做完上述的操作在命令行中輸入npm run webpack就可以了,如下圖:(紅線的部分說明已經生效)

但是上面有一個弊端就是插件生成的index.html文件是在js中,而在我們自定義的index.html之間沒有建立任何的聯系,這是不滿足項目的需求的,下圖

自定義的index.html和插件生成的index.html建立聯系

解決方法:在配置文件的plugins 的初始化對象傳參(這是為了讓咱們自定義的index.html和文件中生成的index.html建立聯系)

解決方法
context

把生成號的html放到dist中而js需要放到js的文件中,在配置中如下操作:

image.png

Plugins 還有什么參數呢,還可以指定我們生成的名稱(filename),還有我們可以直接指定想吧我們的腳本放在頭部還是body標簽里面,如下圖:

plugins參數
title
在index.html中取title的值

通過上兩幅圖的方法就可以取到在plugin中設置title的值

data
在index.html中取data的值

通過上面兩個獲取data的值

htmlWebpackPlugin中的屬性files和options對象中的鍵值
htmlWebpackPlugin中的屬性files和options對象中的鍵值

上兩個圖是對htmlWebpackPlugins下files和options 屬性中插件參數的遍歷

圖中一部分放到head中,一部分放到body中
pulicPath用法

puliPath在頁面中的顯示

上兩個圖就是output中的pulicPath就是設置上線時候的前面的網址

上線的時候需要壓縮用minify屬性

注:[www.npmjs.com中搜html-webpackplugin(http://www.npmjs.comhtml-webpack-plugin) 可以看到webpack中的插件的使用和說明

Webpack插件的多頁面應用

根據不同的頁面可以指定不同的模塊(或者根據不同的頁面指定相同的模板),不下圖:

webpack中plugin的多頁面應用
吧模塊里手動引入的指向生成完的那個文件去掉

注:如果用chunks或excludeChunks來引入模塊的話,index.html 里面不能有任何注釋,否則會瘋狂報錯

chunks用法

把配置里面的inject:‘body’ 自動引入發到body里面,chunks只加載需要的塊就可以了
上面的這種方法需要一一去對應,就顯得非常的麻煩,所有就提供了另外一個參數(excludeChunks[除了那個都是要加載的])

excludeChunks用法

再往下深入一點,如果我們要把頁面的性能達到極致的話,吧初始化的腳本直接嵌入到頁面,而不以鏈接的形式引入在頁面,如下圖就是以鏈接形式引入頁面的,這種方式會增加http請求


鏈接的方式

GitHub中的實例

上圖是githup里面webpack的初始haul的腳本直接嵌入到頁面的方法

有同學會想到既然我們webpack這個配置文件中運行js,那我們為什么不調用nodejs的讀取文件的API直接讀取我們想要引入進來的文件呢
但是會有一個問題,就是直接引入這個文件,不會經過webpack處理的,而你想要引用這個經過webpack流處理過后的文件,通過這種方式你是做不到的。

那么通過什么方式能做到呢,通過compilation(webpack它自身暴露出來的給我們可以使用的一個引用)

通過files對象中chunks.main.entry來截取字符串

截取到沒有publicPath的地址

上兩圖的操作就可以直接拿到不帶publicPath 的路徑,若htmlWebpackPlugin.files.chunks.main.entry 只是這樣寫,沒有后面的substr(..)的話,獲取到的還是帶有publicPath的路徑,之后就可以如下圖中的方法取到它里面的內容:


webpack自身暴露出來的方法compilation

公共部分直接嵌入頁面

上圖公用的是上面的紅圈部分是直接嵌入頁面,而下面的a、b、c是引入進來的。

總結webpack中plugin的內容:首先講到了如何使我們的html和我們的動態的生成的文件名稱一一對應上,然后我們探查了一下這個htmlWebpackPlugin究竟通過它能夠怎么樣的自定義我們的這個html,并且可以通過模塊,還有它里面的一些參數,如何傳參;之后我們一起學習了多頁面的時候,如何通過htmlWebpackPlugin來生成多個html,最后我們一起深入的探究了一下怎么通過htmlWebpackPlugin并且結合模板的方式,去吧我們的生成的js里面的內容直接inline的形式引入到我們的html里面中

什么是Loader以及Loader的特性

#######loader的定義:
loader只是處理資源文件的,也就是說它接受資源文件為一個參數,然后它處理完了之后會返回一個新的資源,這么一個過程就是loader的處理。比如說你用 了loader,就可以告訴webpack處理的這個CoffeScript或者是JSX的時候去使用loader,就可以處理這兩種webpack不支持的這兩種格式。
#######Loader的特性:

  • 可以是被串聯的 如:之前的 css-loader!style-loader! 這種串聯的方式去使用loader
  • 可以是同步也可以是異步的
  • 可以在nodejs環境下去運行
  • 可以接受一些參數
  • 可通過正則表達式,指定的后綴名,在這個配置中就可指定這個某一個后綴名的文件有某個loader來執行(這是一個它的特點)
  • loader可以通過npm來安裝 npm install
  • loader可以獲取configuration (也就是webpack的配置)
  • 我們的插件可以給loader更多的特性
  • loader還可以生產額外的文件(除了處理我們指定的文件之外,loader還可以生產額外的文件)

#######使用loader的方式有三種:

  • 在require中就可以指定指定這個loader 如[ require( “./loader! ./dir/file.txt” ) ] [ require( “ !style!css!less!bootstrap/less/bootstap.lesss ” ) ]
  • 這配置在我們的配置文件
  • 直接使用CLI(在命令行中 webpack --module-bind jade --module-bind ‘css=style!css’)

三種方式的的第一種和第三種都用過了,這個用第二種在配置文件的使用:

在配置文件中

[http://babeljs.io/docs/setup/#installation(http://babeljs.io/docs/setup/#installation) 點擊Build systems中的webpack 可以看到:

安裝babel-loader
通常之后我們還的給它一個配置 {
                    “presets”: [ “es2015” ] 
// babel 也有自己的的插件都在更新和落實,給各個瀏覽器支持,不斷的發布草案,不斷的修訂
//我們可以通過指定presets來告訴我們 這個babel-loader 知道來轉換某一些特性,為我們的js,若這個時候你需要它轉換為所有的特性,直接指定latest(包括es2015,es2016,es2017)
}        
//指定presets其實就是告訴babel-loader 怎么去處理這個我們這些的js,給不同的特性,我們需要轉換哪個個特性

那么怎么去指定這個插件,涉及到之前說的參數的問題,直接loader 指定一個參數如下兩圖:


三種方式指定loader

persets用法

注:指定完之后還的安裝這個插件:


安裝babrel-preset-latest
在配置中指定presets

也可以通過上圖的方式來指定presets,這樣我們就不用再我們的配置文件中指定了

babel-loader

注意:在配置中loader:’babel’這樣寫是會報錯的,調好好久,一點不要省略babel后面的loader(之前webpack1.x的時候可以省略,但是webpack2.0就不可以省略)

圖中是babel后面不加loader所報的錯誤
babel-loader打包時間長

打包的時間長,原因在loader上,因為babel-loader是非常耗時的轉換,那么如何去改善呢

Loaders定義的參數有五個 exclude 排除范圍 (如:某一目錄下不讓去處理)【一些打包過后的文件不希望去處理】如下圖:


loaders參數

exclude的用法

include 指定包含的范圍
loaders可以把一長串的loader一個數組表示

注意:Webpack中的Using Loaders只說了一些簡單的定義如何去使用,真正的文檔是在 Configuration

圖中紅圈的部分意思是只打包src目錄下的,而exclude意思排除范圍(不去打包的范圍)
用了exclude后的時間

用了exclude 之后吧已經打包好的文件排除了,不進行二次打包之后,執行效果很快

condition

Condition可以是一個正則表達式,也可以是一個字符串(包含著絕對路徑的),還可以是一個函數或者是包含著絕對路徑的一個數組

exclude

總結:安裝了babel之后,如何通過webpack的配置來使我們的webpack來處理es6中的代碼,把es6代碼轉換成可以運行的es代碼

處理項目中的css

安裝style-loader 和css-loader
npm install style-loader css-loader --save-dev

loaders中的配置

引入完畫紅圈的部分,就可以在js中處理css文件了

!串聯loader

flex布局兼容瀏覽器效果還不是很好,需要加前綴(手動加前綴太麻煩),webpack里面也有加前綴的loader 是:postcss-loader(它是一個后處理器)
先安裝上npm install postcss-loader --save-dev
還需要安裝 npm install autoprefixer --save-dev
在安裝一個 npm install precss --save-dev

postcss-loader

引入autoprefixer

特別注意:上圖是再創建一個新的postcss.config.js文件,里面寫上上述內容
注:這一點webpac2.0 和webpack1.0也是有很大差別的


加前綴的效果圖

從外部引進的css文件,也是可以的

注:webpack2.0 之后從外部引入文件不用在里面loader里面加入importloader=1,可以直接執行postcss-loader了
webpack 處理less和sass
首先安裝less-loader:npm install less-loader --save-dev 若沒有安裝less,先安裝less:npm install less
之后在loaders數組里新增一個匹配規則:


less的配置

loader 的處理方式是從右到左的,less-loader或sass-loader處理完了以后,再處理postcss-loader
Sass的處理和less的處理方式一樣,也是在loaders里面新增一個匹配規則
處理項目中模板文件
模板

可以看到項目中有一個模板layer.html,通常處理這種模板的文件的做法,是webpack把這個模板文當做字符串進行處理,還有就是把這個webpack當做已經編譯好的一個處理函數
打開webpack的官網,可以看到左邊有一個List of loaders,進入,右邊有目錄點擊templating,之后就可以看到出到出來模板的相關loader都在這里列出來了


在layer.js中引入layer.html

如上圖在layer.js 中吧模板引入進來,.html文件是作為一個字符串進行處理

圖中把layer模塊放到app.js中

別忘了在index.html中加ID

處理模塊還需要安裝 npm install html-loader --save-dev
安裝好之后在loaders規則中加一個匹配規則

html-loader
圖中是引入模塊成功后的的頁面

實際項目中,更復雜,需要用到模板語法;
假設模塊是.ejs結尾的模板;

ejs模板

首先安裝npm install ejs-loader --save-dev


處理ejs模板需要的配置
把layer下的文件在改成tpl 表示模板,之后在loaders里面在匹配一下規則

如上圖,layer.js 文件也的變動,圖中當我們載入ejs模板的時候,webpack官網有說明,它會返回的是一個function,所以tpl它就不代表字符串了,它表示已經編譯過的一個函數,那么函數時干什么用的呢,可以在app.js中傳入我們所需要的數據,如下圖:

tpl模塊中的數據設置

完成后的效果圖

Jsx表示react框架 用的非常廣的一個loader,已經被寄生到了babel這個工具里面了,只需要一個寫設置,就可以支持jsx

處理項目中圖片文件以及其他文件

處理圖片文件分幾種情況:
第一種 css文件里面會有很多圖片文件
第二種 模板里面直接引入某一張圖片
第三種 最底部文件 index.html中對圖片的引用

css中引入圖片

引入圖片之后,先安裝 npm install file-loader --save-dev
只有在loaders中增加對圖片處理的規則


配置中制定規則file-loader處理圖片

圖中命令行中已經顯示圖片被打包了

上面是指定第一種情況,在css中根據路徑來打包圖片文件

index.htm中引入圖片

在index.html中直接引入圖片一會直接被loaders匹配的設置好的規則處理好,顯示在頁面(第三種)

圖中是解決在模塊中引入圖片的方法(第二種)

圖片打包后的輸入地址,想改變它的地址,從默認下放到dist的目錄下,如果我們要改變它的話,給loader加一些參數


name中占位符
name中占位符的用法 ext

在命令行中看到的效果

安裝url-loader:npm install url-loader --save-dev
url-loader 其實和 file-loader 很類似,但是可以指定一個參數,limit這個參數,limit是當你的圖片或者文件大小,大于了你指定的limit后,它就會直接丟給file-loader去處理,然而當你小于limit指定的大小限制的時候,它會把的文件或者圖片轉為base64的編碼,它就不在是一個url了

limit用法

使用limit的效果圖img中成了base64

上圖limit設置一個大于它圖片的大小,在頁面中轉換成了base64(文件一下就變大了很多,影響了文件的大小),可以通過這種方式來區分哪些圖片應該打包成圖片,哪些圖片應該打包成base64

壓縮圖片 需要安裝:npm install image-webpack-loader --save-dev

壓縮圖片

loaders可以包含多個loader;
Limit改變的,小于了,圖片的大小,圖片壓縮打包之后圖片大小變?。ū仍瓉淼奈募夹。?/p>

謝謝讀者朋友耐心讀完這篇文章。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容