七:webpack.config.js文件的高級配置


一、多個入口文件

之前我們配置的都是 一個入口 

var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');

module.exports = {

    //頁面入口文件配置
    entry: {
        index: './src/index.js'
    },
    //入口文件輸出配置
    output: {

        path: path.join(__dirname, "dist/"),
        filename: "bundle.js"
    }
};

 

 
但是有的 時候我們需要多個入口文件,這個時候該如何配置?

entry 參數支持設置對象,可以設置多個入口文件,這個時候output的filename就不能是固定名字 了,因為入口是多個文件,所以 同時也要修改 output參數:


var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');

module.exports = {

    //頁面入口文件配置
    entry: {
        app: ['./src/index.js'],
        login: ['./src/login.js']
    },
    //入口文件輸出配置
    output: {

        path: path.join(__dirname, "dist/"),
        filename: "bundle_[name].js"
    }
};

 


這里的filename: "bundle_[name].js" 中的[name]是一個 正則表達式匹配的,這里的[name]名字指的是鍵值對的鍵,上面的實例中第一個入口文件是app: ['./src/index.js'],[name]名字對應的是app而不是index。運行一下webapck命令就會在dist生成bundle_app.js和bundle_login.js兩個文件




二、plugins插件


常用Plugins介紹

  • 代碼熱替換, HotModuleReplacementPlugin

  • 生成html文件,HtmlWebpackPlugin

  • 將css成生文件,而非內聯,ExtractTextPlugin

  • 報錯但不退出webpack進程,NoErrorsPlugin

  • 代碼丑化,UglifyJsPlugin,開發過程中不建議打開

  • 多個 html共用一個js文件(chunk),可用CommonsChunkPlugin

  • 清理文件夾,Clean

  • 調用模塊的別名ProvidePlugin,例如想在js中用$,如果通過webpack加載,需要將$與jQuery對應起來

 



1、CommonsChunkPlugin抽取公共資源

  CommonsChunkPlugin 常用參數:

name:與 entry 中的鍵對應

filename:公共文件的輸出名字

minChunks :公共模塊被使用的最小次數。比如配置為3,也就是同一個模塊只有被3個以外的頁面同時引用時才會被提取出來作為common chunks。

minSize:作用類似於minChunks,只不過這里控制的文件大小。

 


項目中可能會使用很多的第三方插件,如果把所有的插件和自己的js文件,打包成一個js文件,這樣網頁加載會很慢,並且在優化方面完全可以把第三方插件進行單獨的緩存。這個時候就需要把所有的第三方插件單獨 打包 為一個js包。CommonsChunkPlugin插件就可以幫助我們實現這個功能。

CommonsChunkPlugin是一個對象,所以使用的時候要 進行實例化

new webpack.optimize.CommonsChunkPlugin('common.js')


CommonsChunkPlugin的參數支持字符串和json

下面我們在webpackDemo中實現CommonsChunkPlugin功能,首先我們通過npm安裝 jquery和moment第三方插件:

npm install jquery --save
npm install moment --save

 
接下來在webpack.config.js文件配置CommonsChunkPlugin

var webpack = require('webpack');
var WebpackDevServer = require("webpack-dev-server");
var path = require('path');
var CURRENT_PATH = path.resolve(__dirname); // 獲取到當前目錄
var ROOT_PATH = path.join(__dirname, '../'); // 項目根目錄
var MODULES_PATH = path.join(ROOT_PATH, './node_modules'); // node包目錄
var BUILD_PATH = path.join(ROOT_PATH, './dist'); // 最后輸出放置公共資源的目錄


module.exports = {

    //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字
    entry: {
        app: ['./src/index.js'],
        login: ['./src/login.js'],
        vendors: ['jquery', 'moment'] //需要打包的第三方插件

    },

    //輸出的文件名,合並以后的js會命名為bundle.js
    output: {
        path: path.join(__dirname, "dist/"),
        publicPath: "http://localhost:8088/dist/",
        filename: "bundle_[name].js"
    },
    devServer: {
        historyApiFallback: true,
        contentBase: "./",
        quiet: false, //控制台中不輸出打包的信息
        noInfo: false,
        hot: true, //開啟熱點
        inline: true, //開啟頁面自動刷新
        lazy: false, //不啟動懶加載
        progress: true, //顯示打包的進度
        watchOptions: {
            aggregateTimeout: 300
        },
        port: '8088' //設置端口號
    },
    plugins: [
        //new webpack.HotModuleReplacementPlugin()
        //提取公共部分資源
        new webpack.optimize.CommonsChunkPlugin({
            // 與 entry 中的 vendors 對應
            name: 'vendors',
            // 輸出的公共資源名稱
            filename: 'common.bundle.js',
            // 對所有entry實行這個規則
            minChunks: Infinity
        }),
    ],
    devtool: 'source-map'

};

 


index.html

由於進行了公共資源的提取,所以頁面上 要引入公共部分js文件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <h1 id="welcome">welcome to 68kejian.com</h1>
    <script src="dist/common.bundle.js"></script>
    <script src="dist/bundle_app.js"></script>
</body>

</html>

 


 index.js

var login=require('./login');
var $=require('jquery');//引用jquery模塊

$("#welcome").html(login.sayName());

 


login.js


var userName="68kejian";
module.exports.userName=userName;
module.exports.sayName=function(){
    return userName;
};

 




 
這個時候運行webpack執行命令在dist目錄下面就會生成如下js文件:





2、
ProvidePlugin全局掛載插件

ProvidePlugin插件主要是進行設置全局模塊,比如jquery插件幾乎所有的頁面都用到,使用require('jquery')引用寫起來比較多,這個時候就可以使用ProvidePlugin 把jquery設置為全局的, 每個頁面就可以 直接使用了。

plugins: [
        //new webpack.HotModuleReplacementPlugin()
        //提取公共部分資源
        new webpack.optimize.CommonsChunkPlugin({
            // 與 entry 中的 vendors 對應
            name: 'vendors',
            // 輸出的公共資源名稱
            filename: 'common.bundle.js',
            // 對所有entry實行這個規則
            minChunks: Infinity
        }),
        // 把jquery作為全局變量插入到所有的代碼中
        // 然后就可以直接在頁面中使用jQuery了
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        }),
    ],

 


index.js


var login=require('./login');
var data = require('data');

$("#welcome").html(data);

 



3、自動生成html插件html-webpack-plugin

html-webpack-plugin不是webpack的內置插件所以需要單獨安裝

npm install html-webpack-plugin --save-dev

 


html-webpack-plugin插件默認會在打包根目錄生成一個index.html頁面, 通過相關參數 可以定義輸出名字以及其它的相關配置,下面我們看一下相關的參數:


 
new HtmlWebpackPlugin({      title: 'My App',//設置title的名字 
      filename: 'admin.html',//設置這個html的文件名  
      template:'header.html',//要使用的模塊的路徑  
      inject: 'body',//把模板注入到哪個標簽后 'body'      favicon:'./images/favico.ico',//給html添加一個favicon  './images/favico.ico'      minify:true,//是否壓縮  true false 
      hash:true,//是否hash化 true false , 
      cache:false,//是否緩存, 
      showErrors:false,//是否顯示錯誤,  
      xhtml:false //是否自動關閉標簽 默認false 
    })
 

 

下面我們在webpackDemo項目中加入 這個插件:


var webpack = require('webpack');
var WebpackDevServer = require("webpack-dev-server");
var path = require('path');
var CURRENT_PATH = path.resolve(__dirname);
// 獲取到當前目錄
var ROOT_PATH = path.join(__dirname, '../');
// 項目根目錄
var MODULES_PATH = path.join(ROOT_PATH, './node_modules');
// node包目錄
var BUILD_PATH = path.join(ROOT_PATH, './dist');
// 最后輸出放置公共資源的目錄
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字  
    entry: {
        app: ['./src/js/index.js'],
        vendors: ['jquery', 'moment']
            //需要打包的第三方插件   
    },
    //輸出的文件名,合並以后的js會命名為bundle.js    
    output: {
        path: path.join(__dirname, "dist/"),
        publicPath: "http://localhost:8088/dist/",
        filename: "bundle_[name].js"
    },
    devServer: {
        historyApiFallback: true,
        contentBase: "./",
        quiet: false, //控制台中不輸出打包的信息      
        noInfo: false,
        hot: true, //開啟熱點   
        inline: true, //開啟頁面自動刷新  
        lazy: false, //不啟動懶加載   
        progress: true, //顯示打包的進度     
        watchOptions: {
            aggregateTimeout: 300
        },
        port: '8088' //設置端口號   
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
        //提取公共部分資源       
        new webpack.optimize.CommonsChunkPlugin({
            // 與 entry 中的 vendors 對應          
            name: 'vendors',
            //   // 輸出的公共資源名稱          
            filename: 'common.bundle.js',
            // 對所有entry實行這個規則      
            minChunks: Infinity
        }),
        // 把jquery作為全局變量插入到所有的代碼中
        // 然后就可以直接在頁面中使用jQuery了    
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        }),
        //生成index.html頁面   
        new HtmlWebpackPlugin({
            title: '68kejian.com',
            filename: 'index.html',
            template: 'header.html',
            inject: 'body',
            favicon: './images/favico.ico',
            minify: false,
            hash: true,
            cache: false,
            showErrors: false
        })
    ],
    externals: {
        // require('data') is external and available
        //  on the global var data    
        //      'data': 'data'    
    },
    devtool: 'source-map'
};

 


header.html


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>

 


可以看到htmlWebpackPlugin里面的對象通過<%= htmlWebpackPlugin.options.title %>可以打印到頁面里面。



運行webpack命令,就會在dist 目錄生成了index.html頁面



通過截圖可以看到html-webpack-plugin會把生成的js文件自動插入到頁面中去。


4、提取樣式插件extract-text-webpack-plugin

我們 知道webpack使用require()方法可以引用css文件和圖片,但是由於它們不像js文件准尋CMD格式, 所有在使用的時候需要通過加載器進行處理。 需要用到兩個基本的加載器:css-loader、style.lader,所謂加載器就是一個處理器,它們會把 相關的文件處理為webpack可以使用的規范。加載器不是webpack內置,所有需要npm進行安裝,同時,extract-text-webpack-plugin也需要單獨安裝。

npm install extract-text-webpack-plugin --save-dev
npm install css-loader style-loader less-loader

 


下面是相關配置:

var webpack = require('webpack');
var WebpackDevServer = require("webpack-dev-server");
var path = require('path');
var CURRENT_PATH = path.resolve(__dirname);
// 獲取到當前目錄
var ROOT_PATH = path.join(__dirname, '../');
// 項目根目錄
var MODULES_PATH = path.join(ROOT_PATH, './node_modules');
// node包目錄
var BUILD_PATH = path.join(ROOT_PATH, './dist');
// 最后輸出放置公共資源的目錄
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
        //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字 
        entry: {
            app: ['./src/js/index.js'],
            vendors: ['jquery', 'moment']
                //需要打包的第三方插件   
        },
        //輸出的文件名,合並以后的js會命名為bundle.js   
        output: {
            path: path.join(__dirname, "dist/"),
            publicPath: "http://localhost:8088/dist/",
            filename: "bundle_[name].js"
        },
        devServer: {
            historyApiFallback: true,
            contentBase: "./",
            quiet: false, //控制台中不輸出打包的信息   
            noInfo: false,
            hot: true, //開啟熱點    
            inline: true, //開啟頁面自動刷新     
            lazy: false, //不啟動懶加載   
            progress: true, //顯示打包的進度     
            watchOptions: {
                aggregateTimeout: 300
            },
            port: '8088' //設置端口號    },   
            module: {
                loaders: [
                    // 把之前的style&css&less loader改為     
                    {
                        test: /\.css$/,
                        loader: ExtractTextPlugin.extract('style-loader', 'css-loader'),
                        exclude: /node_modules/

                    }, {
                        test: /\.less$/,
                        loader: ExtractTextPlugin.extract('style', 'css!less'),
                        exclude: /node_modules/

                    },
                ]
            },
            plugins: [
                new webpack.HotModuleReplacementPlugin()
                //提取公共部分資源   
                new webpack.optimize.CommonsChunkPlugin({
                    // 與 entry 中的 vendors 對應  
                    name: 'vendors', // 輸出的公共資源名稱     
                    filename: 'common.bundle.js',
                    // 對所有entry實行這個規則        
                    minChunks: Infinity
                }),
                // 把jquery作為全局變量插入到所有的代碼中
                // 然后就可以直接在頁面中使用jQuery了    
                new webpack.ProvidePlugin({
                    $: 'jquery',
                    jQuery: 'jquery',
                    'window.jQuery': 'jquery'
                }),
                //生成index.html頁面       
                new HtmlWebpackPlugin({
                    title: '68kejian',
                    filename: 'index.html',
                    template: 'header.html',
                    inject: 'body',
                    favicon: './images/favico.ico',
                    minify: false,

                    hash: true,
                    cache: false,
                    showErrors: false
                }),
                // 分離css      
                new ExtractTextPlugin('[name].bundle.css', {
                    allChunks: true
                }),
            ],
            externals: {
                // require('data') is external and available
                //  on the global var data    
                //      'data': 'data'   
            },
            devtool: 'source-map'
        };

 

代碼詳解:


 
module: {
     loaders: [
         // 把之前的style&css&less loader改為    
         {
             test: /\.css$/,
             loader: ExtractTextPlugin.extract('style-loader', 'css-loader'),
             exclude: /node_modules/

         }, {
             test: /\.less$/,
             loader: ExtractTextPlugin.extract('style', 'css!less'),
             exclude: /node_modules/

         },
     ]
 }

 


module對象用來設置加載器的相關配置, loader就是所有加載器的數組。設置加載器的參數如下:


 test: /\.css$/,//文件類型,在整個項目 目錄  
 loader: ExtractTextPlugin.extract('style-loader', 'css-loader'),//使用的加載器 
 exclude: /node_modules/    //排除的目錄

 



ExtractTextPlugin插件的使用和其他的一樣,引用、實例化然后在plugins配置。執行webpack命令就會把所有的 js里面引用的css文件抽取到一個css文件里面。






5、
拷貝資源插件copy-webpack-plugin

官方這樣解釋 Copy files and directories in webpack ,在webpack中拷貝文件和文件夾。

需要安裝

npm install --save-dev copy-webpack-plugin

 


相關參數:

from : 定義要拷貝的源目錄   __dirname + ‘/src/public’
to : 定義要拷貝的目標目錄  __dirname + ‘/dist’
toType : file 或者 dir , 可選,默認是文件
force : 強制覆蓋先前的插件 , 可選 默認false
context : 不知道作用 , 可選 默認 base context 可用 specific context
flatten :只拷貝文件不管文件夾 , 默認是false
ignore : 忽略拷貝指定的文件 ,可以用模糊匹配


下面我們對webpackDemo增加一個復制 圖片的配置


var webpack = require('webpack');
var WebpackDevServer = require("webpack-dev-server");
var path = require('path');
var CURRENT_PATH = path.resolve(__dirname);
// 獲取到當前目錄
var ROOT_PATH = path.join(__dirname, '../');
// 項目根目錄
var MODULES_PATH = path.join(ROOT_PATH, './node_modules');
// node包目錄
var BUILD_PATH = path.join(ROOT_PATH, './dist');
// 最后輸出放置公共資源的目錄
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
    //項目的文件夾 可以直接用文件夾名稱 默認會找index.js ,也可以確定是哪個文件名字    
    entry: {
        app: ['./src/js/index.js'],
        vendors: ['jquery', 'moment'] //需要打包的第三方插件    
    }, //輸出的文件名,合並以后的js會命名為bundle.js    
    output: {
        path: path.join(__dirname, "dist/"),
        publicPath: "http://localhost:8088/dist/",
        filename: "bundle_[name].js"
    },
    devServer: {
        historyApiFallback: true,
        contentBase: "./",
        quiet: false, //控制台中不輸出打包的信息        
        noInfo: false,
        hot: true, //開啟熱點        
        inline: true, //開啟頁面自動刷新        
        lazy: false, //不啟動懶加載        
        progress: true, //顯示打包的進度        
        watchOptions: {
            aggregateTimeout: 300
        },
        port: '8088' //設置端口號    
    },
    module: {
        loaders: [
            // 把之前的style&css&less loader改為            
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract('style-loader', 'css-loader'),
                exclude: /node_modules/

            }, {
                test: /\.less$/,
                loader: ExtractTextPlugin.extract('style', 'css!less'),
                exclude: /node_modules/

            },
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
        //提取公共部分資源        
        new webpack.optimize.CommonsChunkPlugin({
            // 與 entry 中的 vendors 對應            
            name: 'vendors', // 輸出的公共資源名稱            
            filename: 'common.bundle.js',
            // 對所有entry實行這個規則            
            minChunks: Infinity
        }),
        // 把jquery作為全局變量插入到所有的代碼中
        // 然后就可以直接在頁面中使用jQuery了       
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        }),
        //生成index.html頁面        
        new HtmlWebpackPlugin({

            title: '68kejian',
            filename: 'index.html',
            template: 'header.html',
            inject: 'body',
            favicon: './images/favico.ico',
            minify: false,
            hash: true,
            cache: false,
            showErrors: false
        }),
        // 分離css        
        new ExtractTextPlugin('[name].bundle.css', {
            allChunks: true
        }),
        new CopyWebpackPlugin([
            { from: './src/images' }

        ])
    ],
    externals: { // require('data') is external and available
        //  on the global var data        
        'data': 'data'
    },
    devtool: 'source-map'
};

 


執行webpack命令就可以拷貝了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM