webpack 入門及實踐
原文 http://www.w3ctech.com/topic/1557
React自發布以來吸引了越來越多的開發者,React開發和模塊管理的主流工具webpack也被大家所熟知。那么webpack有哪些優勢,可以成為最主流的React開發工具呢?本文和大家一起探索一下。
webpack是什么?
web開發中常用到的靜態資源主要有JavaScript、CSS、圖片、Jade等文件,webpack中將靜態資源文件稱之為模塊。webpack是一個模塊打包工具,其可以兼容多種js書寫規范,且可以處理模塊間的依賴關系,具有更強大的js模塊化的功能。 官方網站 中用下圖清晰的描述了webpack采用不同的loader加載不同的資源文件,打包生成多個js文件,也可以根據設置生成獨立的圖片、css文件等。
why webpack?
在以往的開發過程中,經常會遇到以下三種情況:
- 項目中資源多樣性和依賴性 - js、css、png、less、jade等 為了方便開發,我們經常會使用不同的語法來編寫文檔,用less、sass、jade等會提高開發效率,但同時我們需要借助gulp或grunt來編寫任務編譯文件或對圖片進行壓縮等。
- js模塊規范復雜化 - AMD、CommonJS、UMD、ES6等 requireJS主要用來處理AMD規范的js文件,若使用CommonJS規范的js庫文件,需進行AMD規范的封裝,才能正常使用。而browserify主要處理CommonJS規范的文件,其他規范也需要進行轉化。近期ES6的興起,前面兩種打包工具已經不能滿足我們的需求了。
- 開發與線上文件不一致性(打包壓縮造成影響) </ol>
- 對js、css、圖片等資源文件都支持打包
- 串聯式模塊加載器以及插件機制,讓其具有更好的靈活性和擴展性,例如提供對CoffeeScript、ES6的支持
- 有獨立的配置文件webpack.config.js
- 可以將代碼切割成不同的chunk,實現按需加載,降低了初始化時間
- 支持 SourceUrls 和 SourceMaps,易于調試
- 具有強大的Plugin接口,大多是內部插件,使用起來比較靈活
8.webpack 使用異步 IO 并具有多級緩存。這使得 webpack 很快且在增量編譯上更加快</pre>
webpack 安裝及使用
webpack 可以作為全局的npm模塊安裝,也可以在當前項目中安裝。
npm install -g webpack
- 命令行使用:webpack <entry.js> <result.js>其中entry.js是入口文件,result.js是打包后的輸出文件
- node.js API使用:
var webpack = require('webpack'); webpack({ //configuration }, function(err, stats){});
- 默認使用當前目錄的webpack.config.js作為配置文件。如果要指定另外的配置文件,可以執行:webpack --config webpack.custom.config.js </ul>
- webpack最基本的啟動webpack命令
- webpack -w提供watch方法,實時進行打包更新
- webpack -p對打包后的文件進行壓縮
- webpack -d提供SourceMaps,方便調試
- webpack --colors輸出結果帶彩色,比如:會用紅色顯示耗時較長的步驟
- webpack --profile輸出性能數據,可以看到每一步的耗時
- webpack --display-modules默認情況下 node_modules 下的模塊會被隱藏,加上這個參數可以顯示這些被隱藏的模塊 </ul>
- 其中entry參數定義了打包后的入口文件,數組中的所有文件會打包生成一個filename文件
- output參數定義了輸出文件的位置及名字,其中參數path是指文件的絕對路徑,publicPath是指訪問路徑,filename是指輸出的文件名。 </ul>
- 基于Node.js Express框架的輕量開發服務器
- 靜態資源Web服務器
- 開發中會監聽文件的變化在內存中實時打包 </ul>
webpack可以很好地解決上面的問題,它具有Grunt、Gulp對于靜態資源自動化構建的能力,是一個出色的前端自動化構建工具、模塊化工具、資源管理工具。
webpack 特性
webpack具有requireJs和browserify的功能,但仍有很多自己的新特性:
1. 對 CommonJS 、 AMD 、ES6的語法做了兼容
npm install --save-dev webpack</pre>
webpack的使用通常有三種方式:
webpack 常用命令
webpack的使用和browserify有些類似,下面列舉幾個常用命令:
前面的四個命令比較基礎,使用頻率會比較大,后面的命令主要是用來定位打包時間較長的原因,方便改進配置文件,提高打包效率。
webpack 配置文件
項目中靜態資源文件較多,使用配置文件進行打包會方便很多。最簡單的Webpack配置文件webpack.config.js如下所示:
module.exports = { entry:[ './entry.js', ... ], output: { path: __dirname + '/output/', publicPath: "/output/", filename: 'result.js' } };
開發中需要將多個頁面的公用模塊獨立打包,從而可以利用瀏覽器緩存機制來提高頁面加載效率,減少頁面初次加載時間,只有當某功能被用到時,才去動態的加載。這就需要使用webpack中的CommonsChunkPlugin插件。具體配置如下:
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { entry: { a: "./a", b: "./b" }, output: { filename: "[name].js" }, plugins: [ new CommonsChunkPlugin("common.js") ] }
在文件中根據下面的方式引用即可。
<script src="common.js"></script> <script src="a.js"></script> <script src="b.js"></script>
webpack 模塊加載器
在webpack中JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,圖片等靜態文件都是模塊,不同模塊的加載是通過模塊加載器(webpack-loader)來統一管理的。loaders之間是可以串聯的,一個加載器的輸出可以作為下一個加載器的輸入,最終返回到JavaScript上。loader的配置可以寫在配置文件中,通過正則表達式的方式對文件進行匹配,具體可參見下面的示例:
module: { loaders: [{ test: /\.less/, loader: 'style-loader!css-loader!less-loader' }, { test: /\.(png|jpg)$/, loader: 'url-loader?limit=10000&name=build/[name].[ext]' }] }
loader也支持在js文件中通過require的方式進行加載,只需要在require資源path的前面指定loader,用!來串聯不同的loader和資源即可。
require(“style!css!less!./mystyles.less”);
css文件獨立打包
在webpack中編寫js文件時,可以通過require的方式引入其他的靜態資源,可通過loader對文件自動解析并打包文件。通常會將js文件打包合并,css文件會在頁面的header中嵌入style的方式載入頁面。但開發過程中我們并不想將樣式打在腳本中,最好可以獨立生成css文件,以外鏈的形式加載。這時extract-text-webpack-plugin插件可以幫我們達到想要的效果。需要使用npm的方式加載插件,然后參見下面的配置,就可以將js中的css文件提取,并以指定的文件名來進行加載。
npm install extract-text-webpack-plugin –save-dev
plugins: [ new ExtractTextPlugin('styles.css') ]
圖片打包
webpack中對于圖片的處理,可以通過url-loader來實現圖片的壓縮。
div.img{ background: url(../image/xxx.jpg) } //或者 var img = document.createElement("img"); img.src = require("../image/xxx.jpg"); document.body.appendChild(img);
針對上面的兩種使用方式,loader可以自動識別并處理。根據loader中的設置,webpack會將小于指點大小的文件轉化成 base64 格式的 dataUrl,其他圖片會做適當的壓縮并存放在指定目錄中。
module: { { test: /\.(png|jpg)$/, loader: 'url-loader?limit=10000&name=build/[name].[ext]' }] }
對于上面的配置,如果圖片資源小于10kb就會轉化成 base64 格式的 dataUrl,其他的圖片會存放在build/文件夾下。
webpack-dev-server 靜態資源服務器
webpack除了可以對模塊進行打包,還提供了一個開發服務器。它的特點是:
webpack-dev-server需要單獨安裝,命令如下:
npm install -g webpack-dev-server
可以使用webpack-dev-server直接啟動,也可以增加參數來獲取更多的功能,具體配置可以參見 官方文檔 。默認啟動端口8080,通過localhost:8080/webpack-dev-server/可以訪問頁面,文件修改后保存時會在頁面頭部看到sever的狀態變化,并且會進行熱替換,實現頁面的自動刷新。
雙服務器模式
項目開發中,僅有一臺靜態服務器是不能滿足需求的,我們需要另啟一臺web服務器,且將靜態服務器集成到web服務器中,就可以使用webpack的打包和加載功能。我們只需要修改一下配置文件就可以實現服務器的集成。
entry: [ './src/page/main.js', 'webpack/hot/dev-server', 'webpack-dev-server/client?http://127.0.0.1:8080' ] output: { path: __dirname, filename: '[name].js', publicPath: "http://127.0.0.1:8080/assets/" } plugins: [ new webpack.HotModuleReplacementPlugin() ]
如果在開發中啟動兩個服務器并不是一個很好地選擇,webpack提供了一個中間件webpack-dev-middleware,但其只能在生產環境中使用,可以實現在內存中實時打包生成虛擬文件,供瀏覽器訪問以及調試。使用方式如下:
var webpackDevMiddleware = require("webpack-dev-middleware"); var webpack = require("webpack"); var compiler = webpack({ // configuration output: { path: '/' } }); app.use(webpackDevMiddleware(compiler, { // options }));
最后
通過上面的介紹,基本涵蓋了webpack的各個特性及簡單的使用方法。近來,有一個webpack的優化版 hjs-webpack ,可以簡化webpack中復雜的配置項,只需要安裝開發中所需的loader,無需再module中配置,即可正確使用。有興趣的同學可以嘗試一下。