可以結合慕課網的視頻來讀這篇文章,地址: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的模塊化
安裝好之后還要指定相應的loader 才可以引入如:require(‘css-loader!./style.css’) 加上之后就可以執行了
要是引入的css生效還需要借助 style-loader! 如:require(‘style-loader!css-loader!./syle.css’)
很多人就有了疑問,我每次都得加這么多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
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’ //打包以后的文件名
}
}
#######entry是對象的方式
注意:文件上面的哈希值互相不一樣了,可以認為是文件的版本號,也可以認為是MD5值(MD5算法就是為了保證每個文件的唯一性),也就是說只有當這個文件發生改變的時候,這個哈希值才會變化,這個特點,在我們的項目中對靜態資源版本號的管理是非常有用的,平時我們項目中上線的時候,正好需要只上線那些已經被我們改過的文件
生成項目中的的html頁面文件
就想上面對象為入口的話,它的文件名是[name]是不確定的,難道每一次這種打包都要手動去設置路徑嗎,那豈不是非常麻煩:用webpack的插件來解決這個問題
先用npm install html-webpack-plugin --save-dev
好了之后去webpack的配置文件webpack.confing.js中
但是上面有一個弊端就是插件生成的index.html文件是在js中,而在我們自定義的index.html之間沒有建立任何的聯系,這是不滿足項目的需求的,下圖
解決方法:在配置文件的plugins 的初始化對象傳參(這是為了讓咱們自定義的index.html和文件中生成的index.html建立聯系)
把生成號的html放到dist中而js需要放到js的文件中,在配置中如下操作:
Plugins 還有什么參數呢,還可以指定我們生成的名稱(filename),還有我們可以直接指定想吧我們的腳本放在頭部還是body標簽里面,如下圖:
通過上兩幅圖的方法就可以取到在plugin中設置title的值
通過上面兩個獲取data的值
上兩個圖是對htmlWebpackPlugins下files和options 屬性中插件參數的遍歷
上兩個圖就是output中的pulicPath就是設置上線時候的前面的網址
注:[www.npmjs.com中搜html-webpackplugin(http://www.npmjs.comhtml-webpack-plugin) 可以看到webpack中的插件的使用和說明
Webpack插件的多頁面應用
根據不同的頁面可以指定不同的模塊(或者根據不同的頁面指定相同的模板),不下圖:
注:如果用chunks或excludeChunks來引入模塊的話,index.html 里面不能有任何注釋,否則會瘋狂報錯
把配置里面的inject:‘body’ 自動引入發到body里面,chunks只加載需要的塊就可以了
上面的這種方法需要一一去對應,就顯得非常的麻煩,所有就提供了另外一個參數(excludeChunks[除了那個都是要加載的])
再往下深入一點,如果我們要把頁面的性能達到極致的話,吧初始化的腳本直接嵌入到頁面,而不以鏈接的形式引入在頁面,如下圖就是以鏈接形式引入頁面的,這種方式會增加http請求
上圖是githup里面webpack的初始haul的腳本直接嵌入到頁面的方法
有同學會想到既然我們webpack這個配置文件中運行js,那我們為什么不調用nodejs的讀取文件的API直接讀取我們想要引入進來的文件呢
但是會有一個問題,就是直接引入這個文件,不會經過webpack處理的,而你想要引用這個經過webpack流處理過后的文件,通過這種方式你是做不到的。
那么通過什么方式能做到呢,通過compilation(webpack它自身暴露出來的給我們可以使用的一個引用)
上兩圖的操作就可以直接拿到不帶publicPath 的路徑,若htmlWebpackPlugin.files.chunks.main.entry 只是這樣寫,沒有后面的substr(..)的話,獲取到的還是帶有publicPath的路徑,之后就可以如下圖中的方法取到它里面的內容:
上圖公用的是上面的紅圈部分是直接嵌入頁面,而下面的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 可以看到:
通常之后我們還的給它一個配置 {
“presets”: [ “es2015” ]
// babel 也有自己的的插件都在更新和落實,給各個瀏覽器支持,不斷的發布草案,不斷的修訂
//我們可以通過指定presets來告訴我們 這個babel-loader 知道來轉換某一些特性,為我們的js,若這個時候你需要它轉換為所有的特性,直接指定latest(包括es2015,es2016,es2017)
}
//指定presets其實就是告訴babel-loader 怎么去處理這個我們這些的js,給不同的特性,我們需要轉換哪個個特性
那么怎么去指定這個插件,涉及到之前說的參數的問題,直接loader 指定一個參數如下兩圖:
注:指定完之后還的安裝這個插件:
也可以通過上圖的方式來指定presets,這樣我們就不用再我們的配置文件中指定了
注意:在配置中loader:’babel’這樣寫是會報錯的,調好好久,一點不要省略babel后面的loader(之前webpack1.x的時候可以省略,但是webpack2.0就不可以省略)
打包的時間長,原因在loader上,因為babel-loader是非常耗時的轉換,那么如何去改善呢
Loaders定義的參數有五個 exclude 排除范圍 (如:某一目錄下不讓去處理)【一些打包過后的文件不希望去處理】如下圖:
include 指定包含的范圍
loaders可以把一長串的loader一個數組表示
注意:Webpack中的Using Loaders只說了一些簡單的定義如何去使用,真正的文檔是在 Configuration
用了exclude 之后吧已經打包好的文件排除了,不進行二次打包之后,執行效果很快
Condition可以是一個正則表達式,也可以是一個字符串(包含著絕對路徑的),還可以是一個函數或者是包含著絕對路徑的一個數組
總結:安裝了babel之后,如何通過webpack的配置來使我們的webpack來處理es6中的代碼,把es6代碼轉換成可以運行的es代碼
處理項目中的css
安裝style-loader 和css-loader
npm install style-loader css-loader --save-dev
引入完畫紅圈的部分,就可以在js中處理css文件了
flex布局兼容瀏覽器效果還不是很好,需要加前綴(手動加前綴太麻煩),webpack里面也有加前綴的loader 是:postcss-loader(它是一個后處理器)
先安裝上npm install postcss-loader --save-dev
還需要安裝 npm install autoprefixer --save-dev
在安裝一個 npm install precss --save-dev
特別注意:上圖是再創建一個新的postcss.config.js文件,里面寫上上述內容
注:這一點webpac2.0 和webpack1.0也是有很大差別的
注:webpack2.0 之后從外部引入文件不用在里面loader里面加入importloader=1,可以直接執行postcss-loader了
webpack 處理less和sass
首先安裝less-loader:npm install less-loader --save-dev 若沒有安裝less,先安裝less:npm install less
之后在loaders數組里新增一個匹配規則:
loader 的處理方式是從右到左的,less-loader或sass-loader處理完了以后,再處理postcss-loader
Sass的處理和less的處理方式一樣,也是在loaders里面新增一個匹配規則
處理項目中模板文件
可以看到項目中有一個模板layer.html,通常處理這種模板的文件的做法,是webpack把這個模板文當做字符串進行處理,還有就是把這個webpack當做已經編譯好的一個處理函數
打開webpack的官網,可以看到左邊有一個List of loaders,進入,右邊有目錄點擊templating,之后就可以看到出到出來模板的相關loader都在這里列出來了
如上圖在layer.js 中吧模板引入進來,.html文件是作為一個字符串進行處理
處理模塊還需要安裝 npm install html-loader --save-dev
安裝好之后在loaders規則中加一個匹配規則
實際項目中,更復雜,需要用到模板語法;
假設模塊是.ejs結尾的模板;
首先安裝npm install ejs-loader --save-dev
如上圖,layer.js 文件也的變動,圖中當我們載入ejs模板的時候,webpack官網有說明,它會返回的是一個function,所以tpl它就不代表字符串了,它表示已經編譯過的一個函數,那么函數時干什么用的呢,可以在app.js中傳入我們所需要的數據,如下圖:
Jsx表示react框架 用的非常廣的一個loader,已經被寄生到了babel這個工具里面了,只需要一個寫設置,就可以支持jsx
處理項目中圖片文件以及其他文件
處理圖片文件分幾種情況:
第一種 css文件里面會有很多圖片文件
第二種 模板里面直接引入某一張圖片
第三種 最底部文件 index.html中對圖片的引用
引入圖片之后,先安裝 npm install file-loader --save-dev
只有在loaders中增加對圖片處理的規則
上面是指定第一種情況,在css中根據路徑來打包圖片文件
在index.html中直接引入圖片一會直接被loaders匹配的設置好的規則處理好,顯示在頁面(第三種)
圖片打包后的輸入地址,想改變它的地址,從默認下放到dist的目錄下,如果我們要改變它的話,給loader加一些參數
安裝url-loader:npm install url-loader --save-dev
url-loader 其實和 file-loader 很類似,但是可以指定一個參數,limit這個參數,limit是當你的圖片或者文件大小,大于了你指定的limit后,它就會直接丟給file-loader去處理,然而當你小于limit指定的大小限制的時候,它會把的文件或者圖片轉為base64的編碼,它就不在是一個url了
上圖limit設置一個大于它圖片的大小,在頁面中轉換成了base64(文件一下就變大了很多,影響了文件的大小),可以通過這種方式來區分哪些圖片應該打包成圖片,哪些圖片應該打包成base64
壓縮圖片 需要安裝:npm install image-webpack-loader --save-dev
loaders可以包含多個loader;
Limit改變的,小于了,圖片的大小,圖片壓縮打包之后圖片大小變?。ū仍瓉淼奈募夹。?/p>
謝謝讀者朋友耐心讀完這篇文章。