Webpack 是當下最熱門的前端資源模塊化管理和打包工具。它可以將不少鬆散的模塊依照依賴和規則打包成符合生產環境部署的前端資源。javascript
經過 loader 的轉換,不論什麼形式的資源都可以視做模塊,比方 CommonJs 模塊、 AMD 模塊、 ES6 模塊、CSS、圖片、 JSON、Coffeescript、 LESS 等。css
可以經過npm來安裝,全局安裝:html
$ npm install -g webpack項目根文件夾下安裝。經過cmd環境進入到項目根文件夾下:
$ npm install --save-dev webpack
(注)此時在項目根文件夾會出現一個package.json文件前端
在項目根文件夾下新增一個webpack.config.js文件。內容例如如下:java
var webpack = require('webpack'); module.exports = { //根文件夾 context: __dirname + "", //文件入口 entry: { index: './js/main.js', other: './js/other.js' }, //文件出口 output: { path: __dirname + "/dist", // 設置輸出文件夾 filename: '[name].bundle.js', // 輸出文件名稱 }, module: { //載入器配置 loaders: [ //.css文件使用 style-loader 和 css-loader 來處理 //【$ npm install css-loader style-loader --save-dev】命令行表示初始化style-loader, css-loader { test: /\.css$/, loader: "style!css" }, //圖片文件使用 url-loader來處理,小於8kb的直接轉爲base64 //【$ npm install url-loader --save-dev】 //【$ npm install file-loader --save-dev】 { test: /\.(jpeg|png|gif|svg)$/i, loader: 'url-loader?limit=8192&name=[name].[ext]' }, //字體文件使用 url-loader來處理。小於8kb的直接轉爲base64 //{ test: /\.(woff|woff2|eot|ttf|otf)$/i, loader: 'url-loader?limit=8192&name=[name].[ext]' }, //.js文件使用 babel-loader 來處理 //【$ npm install babel-loader】 //{ test: /\.js$/, loader: 'babel-loader' , exclude: /node_modules/}, //.scss 文件使用 style-loader、css-loader 和 sass-loader 來處理 //{ test: /\.js?$/, loaders: ['react-hot-loader', 'babel-loader'], exclude: /node_modules/ }, //{ test: /\.scss$/, loader: 'style!css!sass?sourceMap' }, //.less文件使用 style-loader、css-loader 和 less-loader來處理 //{ test: /\.less$/, loader: "style!css!less" }, //.jsx文件使用 babel-loader來處理 //{ test: /\.jsx$/, loader: ['babel-loader'] , exclude: /(node_modules|bower_components)/} //【$ npm install --save-dev react-hot-loader】 //【$ npm install --save-dev webpack-dev-server】 //【$ npm install less --save-dev】命令行表示初始化less //【$ npm install css-loader style-loader --save-dev】命令行表示初始化style-loader, css-loader //【$ npm install less less-loader --save-dev】命令行表示初始化less-loader, 基於style-loader,css-loader ] }, // 插件 plugins: [ // 默認會把所有入口節點的公共代碼提取出來,生成一個common.js new webpack.optimize.CommonsChunkPlugin('common'), // 壓縮代碼擡頭凝視 new webpack.BannerPlugin('此處加入打包擡頭凝視!'), // 代碼壓縮 new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ], //其餘解決方式配置 resolve: { // 配置簡寫,配置事後。書寫該文件路徑的時候可以省略文件後綴。如require("common") extensions: ['.js', '.jsx', '.coffee'] }, //由於壓縮後的代碼不易於定位錯誤,配置該項後錯誤發生時就能夠採用source-map的形式直接顯示你出錯代碼的位置。該文件中已經作了相關凝視,主要想說的一點是文件入口entry配置。假設你僅僅有一個文件入口。則直接用devtool: 'eval-source-map' }node
entry: "./js/main.js"本例中我使用了兩個文件入口文件。各自是main.js和other.js。這裏項目已經搭建完畢,項目整體文件夾結構例如如下:
此例中新建了2個模塊,各自是MyFunction.js和MyObject.js這兩個文件代碼例如如下:react
MyFunction.js:
jquery
var content = new Object(); content.showContent = function() { console.log("This is my Function!"); } exports = module.exports = content;MyObject.js:
function content() { var showContent = function() { console.log("This is my Object!"); } var object = new Object(); object.showContent = showContent; return object; } exports = module.exports = content;(注)這兩個模塊代碼也展現了兩種不一樣建立模塊js寫法的規範
$(document).ready(function() { console.log("Test Start---------------------"); async.auto({ //運行代碼 [建立型對象] t1: function(callback) { var MyObject = require("./core/MyObject.js"); var myObject = new MyObject(); myObject.showContent(); callback(null); }, //運行代碼 [方法型對象] t2: function(callback) { var MyFunction = require("./core/MyFunction.js"); MyFunction.showContent(); callback(null); }, //運行代碼 [圖片型對象] t3: function(callback) { $("#img").attr("src", "./js/assets/img.png"); callback(null); }, //運行代碼 [解析JSON數據] t4: function(callback) { $.getJSON("./js/assets/data.json", function(data) { console.log("this is type of " + typeof data); callback(null); }); }, //運行代碼 [AJAX請求同域數據] t5: ["t4", function(callback, results) { $.ajax({ url: "./js/assets/data.txt", async: false, error: function(response, state) { console.log("ajax_error:" + response); callback(null); }, success: function(response, state) { console.log("ajax_ok:" + response); callback(null); } }); }], access: ["t1", "t2", "t3", "t4", "t5", function(callback, results) { callback(null); } ] }, function(error, results) { console.log("Test End-----------------------"); }); });該主程文件用到了async異步運行。這樣就可以更清晰的看到打印結果。
在cmd環境下進入到你的項目根文件夾。運行打包命令:webpack
$ webpack -d
(注)webpack還有其它的一些打包和編譯命令,可以本身搜索一下,此處再也不介紹web
打包成功後的顯演示樣例如如下:此時會在項目根文件夾下新增了一個dist文件夾。裏面有三個文件,分別爲common.bundle.js、index.bundle.js和other.bundle.js,當中common.bundle.js表示兩入口文件共同擁有模塊,咱們現在僅僅測當中一個入口文件就能夠,在index.html將打包文件引入就能夠展現運行代碼。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script src="js/libs/async.js"></script> <script src="js/libs/jquery-1.8.0.min.js"></script> <script src="dist/common.bundle.js"></script> <script src="dist/index.bundle.js"></script> </head> <body> <img id="img" /> </body> </html>運行結果:
要記住一點,Webpack儘管都支持CommonJS規範和AMD規範。但是終於的主程序是打包到同一個bundle.js文件裏,這就意味着bundle.js文件有可能較大。此時若將Webpack應用於瀏覽器環境而不是服務端環境時,由於同步載入緣由就有可能引發瀏覽器載入過程較慢的狀況發生。
此時的決策是(1)在webpack.config.js配置項中plugins除去沒必要要的插件;(2)壓縮代碼,webpack 自帶了一個壓縮插件 UglifyJsPlugin,僅僅需要在配置文件裏引入就能夠。
{ plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ] }增長了這個插件以後,編譯的速度會明顯變慢,因此通常僅僅在生產環境啓用。
在描寫敘述Webpack中有說到,它都支持CommonJS規範和AMD規範,在Web前端中,模塊化規範主要有3種,各自是CommonJS規範、AMD規範和CMD規範,然後兩種規範都是在CommonJS規範的基礎上發展而來。
commonJS規範基本的標誌是定義了require和exports或module.exports的寫法實現代碼模塊化管理。
CommonJS是在瀏覽器環境以外構建JavaScript生態系統爲目標產生的項目。比方server和桌面環境中。CommonJS規範是爲了解決JavaScript的做用域問題而定義的模塊形式,可以使每個模塊在它自身的命名空間中運行。該規範的主要內容是:模塊必須經過 module.exports導出對外的變量或接口。經過require()來導入其它模塊的輸出到當前模塊。寫法例如如下:
// moduleA.js module.exports = function( value ){ return value * 2; } // moduleB.js var multiplyBy2 = require('./moduleA'); var result = multiplyBy2(4);CommonJS是同步載入模塊。 server端的Node.js遵循CommonJS規範。核心思想是贊成模塊經過require 方法來同步載入所要依賴的其它模塊。而後經過 exports或module.exports來導出需要暴露的接口。
可以說當初定義CommonJS規範的主要目的是應用在服務端。
(注)應用實現如Node.js
AMD規範是在CommonJS規範的基礎上應用而來,因爲CommonJS規範是同步運行,不利於在瀏覽器上運行,因此AMD規範應運而生。AMD規範的主要標誌是定義了define寫法,是異步載入模塊。AMD規範事實上僅僅有一個主要接口 define(id,dependencies,factory),它要在聲明模塊的時候指定所有的依賴dependencies。並且還要當作形參傳到factory中,對於依賴的模塊提早運行,依賴前置。
define("module", ["dep1", "dep2"], function(d1, d2) { return someExportedValue; }); require(["module"], function(module) { /* ... */ });(注)應用實現如require.js框架
CMD規範與AMD規範差點兒同樣,惟一不一樣的是在定義模塊時不需要知道其依賴條件。即無依賴前置一說。在需要調用其它模塊時直接require進來就可以使用,即遵循就近依賴。延時運行的原則。
define(function(require, exports, module) { var $ = require('jquery'); var Spinning = require('./spinning'); exports.doSomething = ... module.exports = ... })
(注)應用實現如seajs.js框架
RequireJS 想成爲瀏覽器端的模塊載入器,同一時候也想成爲 Rhino / Node 等環境的模塊載入器。
SeaJS 則專一於 Web 瀏覽器端,同一時候經過 Node 擴展的方式可以很是方便跑在 Node server端。據統計。針對模塊化框架的使用狀況。國外較喜歡使用AMD規範,而國內則較多使用CMD規範,畢竟CMD規範是從國內發展而來。
實例Demo:http://download.csdn.net/detail/zeping891103/9796332