• 七: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命令就可以拷贝了

  • 相关阅读:
    echarts中label上下两行展示
    vue中去掉地址栏中的#
    vue中登录超时跳转到登录页面设置拦截器
    在table中,tbody没有充满整个table
    vant中dialog的使用
    水位波纹动画兼容ie8
    在vue中使用XLSX导出表格
    elementUI 选择开始结束日期加限制
    element table 合并同类项并输出后台返回数据
    将后台返回的月份201810,201809转换成正常的9月10月
  • 原文地址:https://www.cnblogs.com/minghui007/p/7268919.html
Copyright © 2020-2023  润新知