1. 程式人生 > >webpack概念以及配置檔案詳解

webpack概念以及配置檔案詳解

Webpack 概念

本質上,webpack 是一個現代 JavaScript 應用程式的靜態模組打包器(module bundler)。當 webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成一個或多個 bundle。

模組(Modules):
在模組化程式設計中,將程式分解成離散功能模組(discrete chunks of functionality)。
每個模組具有比完整程式更小的接觸面,使得校驗、除錯、測試輕而易舉。精心編寫的模組提供了可靠的抽象和封裝界限,使得應用程式中每個模組都具有條理清楚的設計和明確的目的。


webpack 模組:
webpack 模組能夠以各種方式表達它們3的依賴關係,例如:
ES2015 import語句
CommonJs require()語句
AMD definerequire 語句
css/sass/less 檔案中的 @import 語句
樣式(url(...))或 HTML 檔案(<img src=...>)中的圖片連結(image url)
webpack 1 需要特定的 loader 來轉換 ES 2015 import,然而通過 webpack 2 可以開箱即用。


webpack 支援的模組型別:
webpack 通過 loader 可以支援各種語言和前處理器編寫模組。loader 描述了 webpack 如何處理非 JavaScript(non-JavaScript)模組,並且在 bundle 中引入這些依賴。

webpack是高度可配置的,但是必須先理解4個核心概念:

一、入口(entry):入口起點(entry point)指示 webpack 應該使用哪個模組,來作為構建其內部依賴圖的開始。進入入口起點後, webpack 會找出有哪些模組和庫是入口起點(直接和間接)依賴的。* 每個依賴項隨即被處理,最後輸出到稱之為 bundles 的檔案中。*

    //可以通過在 webpack.config.js 檔案中配置 entry 屬性,來指定一個入口起點:
    module.exports = {
        entry : './path/to/my/entry/files.js'
}

更多使用方法查詢:https://doc.webpack-china.org/concepts/entry-points

二、 輸出(output):告訴 webpack 在哪裡輸出它所建立的 bundles ,以及如何命名這些檔案。

    module.exports = {
        output: {
             path       : './dist',
             //按需載入(on-demand-load)或載入外部資源(external resources)(如圖片、檔案等)
             publicPath : '/dist', 
             filename   : 'js/[name].js'
        }
    }

程式碼解釋:
1.通過 output.filenameoutput.path屬性,來告訴 webpack bundle 的名稱,以及我們想要生成(emit)到哪裡。
2.更多屬性請查詢:https://doc.webpack-china.org/configuration/output

三、loader:讓 webpack 能夠處理那些非 JavaScript 檔案(webpack 自身只理解 JavaScript)。loader 可以將所有型別的檔案轉換為 webpack 能夠處理的有效模組,然後就可以利用 webpack 的打包能力,對它們進行處理。

loader 用於對模組的原始碼進行轉換。loader 可以使你在import或“載入”模組時預處理檔案。因此,loader 類似於其他構建工具中”任務(task)”,並提供了處理前端構建步驟的強大辦法。loader 可以將檔案從不同的語言轉換為 JavaScript ,或將內聯影象轉換為 data URL. loader 甚至允許你直接在 JavaScript 模組中 import CSS 檔案。

使用方法查閱:https://doc.webpack-china.org/concepts/loaders
四、 外掛(plugins):外掛的目的在於解決 loader 無法實現的其他事。

webpack 外掛是一個具有 apply屬性的 JavaScript 物件。apply屬性會被webpack compiler 呼叫,並且 compiler 物件可在整個編譯生命週期訪問。


Function.prototype.apply:通過這個方法可以把任意函式作為外掛傳遞(this將指向compiler)。
具體用法請查閱:https://doc.webpack-china.org/concepts/plugins

完整的 webpack 配置檔案例項(webpack 1.X)

var webpack                      = require('webpack');
var ExtractTextPlugin            = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin            = require('html-webpack-plugin');

//環境變數配置,dev / online
var WEBPACK_ENV              = process.env.WEBPACK_ENV || 'dev';
console.log(WEBPACK_ENV);

//獲取html-webpack-plugin的引數的方法
var getHtmlConfig=function(name,title){
    return {
        template       : './src/view/' + name + '.html',
        filename       : 'view/' + name + '.html',
        title          : title,
        inject         : true,
        hash           : true,
        chunks         : ['common',name]
    };
};

//webpack config
var config ={
    //多個入口配置
     entry : {
        'common'              : ['./src/page/common/index.js','webpack-dev-server/client?http://localhost:8088/'],
        'index'               : ['./src/page/index/index.js'],
        'list'                : ['./src/page/list/index.js'],
        'detail'              : ['./src/page/detail/index.js'],
        'cart'                : ['./src/page/cart/index.js'],
        'order-confirm'       : ['./src/page/order-confirm/index.js'],
        'order-list'          : ['./src/page/order-list/index.js'],
        'order-detail'        : ['./src/page/order-detail/index.js'],
        'payment'             : ['./src/page/payment/index.js'],
        'user-login'          : ['./src/page/user-login/index.js'],
        'user-register'       : ['./src/page/user-register/index.js'],
        'user-pass-reset'     : ['./src/page/user-pass-reset/index.js'],
        'user-center'         : ['./src/page/user-center/index.js'],
        'user-center-update'  : ['./src/page/user-center-update/index.js'],
        'user-pass-update'    : ['./src/page/user-pass-update/index.js'],
        'result'              : ['./src/page/result/index.js'],
     },
     //output
     output : {
         path       : './dist',
         publicPath : '/dist',
         filename   : 'js/[name].js'
     },
     /*防止將某些 import 的包(package)打包到 bundle 中,
     而是在執行時(runtime)再去從外部獲取這些擴充套件依賴*/
     externals : {
            'jquery' : 'window.jQuery'
     },
     //loaders
     module : {
            loaders : [
                { test : /\.css$/, loader:ExtractTextPlugin.extract("style-loader","css-loader")},
                { test : /\.(gif|png|jpg|woff|svg|eot|ttf)\??.*$/, loader:"url-loader?limit=100&name=resource/[name].[ext]"},
                {
                    test   : /\.string$/,
                    loader : 'html-loader',
                    query  : {
                        minimize : true,
                        removeAttributeQuotes : false
                    }
                }
            ]
     },
    //解析
    resolve : {
        //建立 import 或 require 的別名,來確保模組引入變得更簡單。
        alias : {
            node_modules    : __dirname + '/node_modules',
            util            : __dirname + '/src/util',
            page            : __dirname + '/src/page',
            service         : __dirname + '/src/service',
            image           : __dirname + '/src/image'
        }
    },
    //外掛
     plugins : [
            //獨立通用模組到js/base.js
            new webpack.optimize.CommonsChunkPlugin({
                name : 'common',
                filename : 'js/base.js'
            }),
            //把css單獨打包到檔案裡
            new ExtractTextPlugin("css/[name].css"),
            //html模板的處理
            new HtmlWebpackPlugin(getHtmlConfig('index','首頁')),
            new HtmlWebpackPlugin(getHtmlConfig('list','商品列表')),
            new HtmlWebpackPlugin(getHtmlConfig('detail','商品詳情')),
            new HtmlWebpackPlugin(getHtmlConfig('cart','購物車')),
            new HtmlWebpackPlugin(getHtmlConfig('order-confirm','訂單確認')),
            new HtmlWebpackPlugin(getHtmlConfig('order-list','訂單列表')),
            new HtmlWebpackPlugin(getHtmlConfig('order-detail','訂單詳情')),
            new HtmlWebpackPlugin(getHtmlConfig('payment','訂單支付')),
            new HtmlWebpackPlugin(getHtmlConfig('user-login','使用者登入')),
            new HtmlWebpackPlugin(getHtmlConfig('user-register','使用者註冊')),
            new HtmlWebpackPlugin(getHtmlConfig('user-pass-reset','找回密碼')),
            new HtmlWebpackPlugin(getHtmlConfig('user-center','個人中心')),
            new HtmlWebpackPlugin(getHtmlConfig('user-center-update','修改個人資訊')),
            new HtmlWebpackPlugin(getHtmlConfig('user-pass-update','修改密碼')),
            new HtmlWebpackPlugin(getHtmlConfig('result','操作結果')),
     ]
   };

   if('dev' === WEBPACK_ENV){
    config.entry.common.push('webpack-dev-server/client?http://localhost:8088/');
   }

  module.exports = config;

更多配置內容請檢視:https://doc.webpack-china.org/configuration/