<什么是webpack>
webpack是一個模塊打包器,任何靜態資源(js、css、圖片等)都可以視作模塊,然后模塊之間也可以相互依賴,通過webpack對模塊進行處理后,可以打包成我們想要的靜態資源。
gulp的打包是將js、css、圖片等分開打包的,但是webpack是將所有的靜態資源打包到一起,因此一個請求就可以了。
<webpack的特點>
·支持CommonJs(require的寫法)和AMD模塊,也就是說基本可以無痛遷移舊項目
·支持模塊加載器和插件機制,可對模塊靈活定制,特別是babel-loader,有效支持es6
·可以通過配置,打包成多個文件。有效利用瀏覽器的緩存功能提升性能。將公用的東西抽離出來,比如jQuery等
·將樣式文件和圖片等靜態資源視為模塊進行打包。配合loader加載器,支持sass、less等css預處理器
·內置有source map,即使打包在一起也方便調試
<webpack的安裝>
1,先全局安裝
npm install webpack -g
·webpack -w 提供watch方法,實時進行打包更新
·webpack -p 對打包后的文件進行壓縮
·webpack -d 提供sourcemap,方便調試
·webpack --config 以某個config作為打包
·webpack --help 更多命令
2,再本地安裝
npm init 先初始化一下,生成package.json。再安裝,這樣可以方便的查看依賴的文件
npm install webpack --save-dev 開發式依賴,一些打包工具,像gulp、webpack等都是開發式依賴,上線時並不需要
<webpack初體驗>
比如說所有的文件打包到bundle.js中,則要在頁面中引入bundle.js
webpack ./entry.js bundle.js //編譯entry.js並打包到bundle.js
<模塊依賴>
·webpack會分析入口文件,解析包含依賴關系的各個文件
·這些文件(模塊)都打包到bundle.js文件中
·webpack會給每個模塊分配一個唯一的id並通過這個id索引和訪問模塊
·頁面啟動時先執行entry.js代碼,其他的模塊會在require時懶加載
<loader加載器>
·webpack本身只能處理JavaScript模塊,如果要處理其他類型的文件,就需要使用loader進行轉換
·Loader可以理解為是模塊和資源的轉換器,可以轉換任何類型(jsx、jade等)的模塊
·Loader可以通過管道方式鏈式調用,每個loader可以把資源轉換成任意格式並傳遞給下一個loader,但是最后一個loader必須返回JavaScript,因為webpack只認識js。不同的文件,使用的loader也不一樣
·Loader可以接受參數,以此來傳遞配置項給loader。
·Loader可以通過npm安裝
·Loader可以通過文件擴展名(或正則表達式)綁定不同的加載器
<加載css文件>
安裝兩個loader:npm install css-loader style-loader
·首先將style.css也看作一個模塊
·用css-loader來讀取它
·用style-loader把它內嵌到html中
在entry.js中引入:
require("css!./style.css")//相當於require("css-loader!.style.css").因為css-loader的-loader是固定的,所以一般省略-loader。
/*將原始的css通過css-loader讀出來,需要傳遞給style-loader。所以該require還需要補充為如下所示:*/
require("style!css!./style.css")
//!相當於gulp中的流一樣,從右向左依次流動
再次執行
webpack ./entry.js bundle.js
編譯entry.js引入的樣式文件打包到bundle.js
<加載圖片url-loader>
url-loader會將樣式中引用到的圖片轉為模塊來處理
npm install url-loader
limit的參數意思是圖片大小小於這個限制的時候,會自動啟用base64編碼圖片
<配置文件>
·webpack在執行的時候可以通過指定的配置文件
·默認情況下會執行當前目錄中的webpack.config.js,當輸入webpack時,會自動尋找該文件。
·配置文件是一個node.js模塊,返回一個json格式的配置信息對象
·添加配置文件,然后執行webpack --progress --colors就可以了
配置文件格式為:
var webpack = require("webpack") module.exports = { entry:"./entry.js",//指定打包的入口文件,每個鍵值對,就是一個入口文件。 output:{//配置打包結果 path:__dirname,//定義了輸出的文件夾 filename:"bundle.js"//定義了打包結果文件的名稱 }, module:{//定義了模塊的加載邏輯 loaders:[//定義了一系列的加載器 {test:/\.css$/,loader:"style!css"},//當需要加載的文件匹配`test`的正則時,就會使用相應的loader {test:/\.(png|jpg)$/,loader:"url?limit=40000"}, {test:/\.js?$/,loader:"babel",exclude:/node_modules/,query:{compact:false,presets:['es2015']}}//對於所有的js文件,用babel-loader //進行加載,忽略node_modules下面 // 的js文件。query表示參數,相當於 // url-loader的?形式。 ] }, plugins:[//插件的使用一般在webpack配置信息plugins選項中指定,我們可以向生成的打包文件頭部插入一些信息 new webpack.BannerPlugin("//叮呤在學習webpack"),//向打包之后的文件頭部添加注釋信息 new webpack.optimize.CommonChunkPlugin("common.js")//把多個模塊中的公共部分,單獨提取出來,單獨加載 ], resolve:{ alias:{//別名,它的作用是把用戶的一個請求重定向到另一個路徑 jquery:"./js/jquery.js" //這樣,在使用jQuery的組件中只需要require("jquery")即可,而不再需要逐級去尋找jQuery的存放位置 } } }
·expose,如果想在前台使用打包的jQuery,需要把jQuery暴露出來,先安裝該模塊 npm install expose-loader --save-dev
eg:把$作為別名為jquery的變量暴露到全局上下文中require("expose?$!jquery"),在引入jquery的時候,把jQuery對象綁定到window的$上面
·entry屬性可以使一個對象,而對象名也就是key,會作為下面output的filename屬性的name
entry:{
bundle1:"./entry1.js",
bundle2:"./entry2.js"
}
output:{
path:__dirname,
filename:"[name].js"//此處的[name]就表示bundle1和bundle2
}
假如bundle1和bundle2都包含有功能相同的部分,則可以把這部分提取出來
·公共模塊。我們利用插件可以智能的提取公共部分,以提供我們瀏覽器的緩存復用
plugins:[
new webpack.optimize.CommonChunkPlugin("common.js")//把多個模塊中的公共部分,單獨提取出來,單獨加載
]
我們需要手動在html上加載common.js,並且是必須最先加載
<使用es6>
npm install babel-core --save-dev
npm install babel-loader --save-dev
npm install babel-preset-es2015
<webpack-dev-server>
npm install webpack-dev-server -g
安裝好之后,執行webpack-dev-server,在當前目錄啟動一個express服務,會自動打包和實時刷新
<與webpack相比gulp的優勢>
webpack不可以做自動部署和代碼檢查,webpack只是個打包工具。所以可以采用gulp與webpack混合使用的方法
var gutil = require("gulp-util"); var webpack = require("webpack"); var webpackConfig = require("./webpack.config.js"); gulp.task("webpack",function(callback){ var myConfig = Object.create(webpackConfig); webpack(myConfig,function(err,stats){ callback(); }) }) gulp.task("default",function(){ gulp.watch("./**",["webpack"]); })