博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
webpack搭建多页面系统(三) 理解webpack.config.js的四个核心概念
阅读量:6594 次
发布时间:2019-06-24

本文共 12618 字,大约阅读时间需要 42 分钟。

webpack是需要自己编写自己需要的一个配置对象,取决你如何使用webpack,下面指定了所有的可用的配置选项。

参考文档:

webapck.config.js

var path = require('path'); #使用Node内置的path模块,并在它前面加上__dirname这个全局变量。可以防止不同操作系统之间的文件路径问题,并且可以使用相对路径按照预期工作。var webpackConfig = {    devtool:'inline-source-map', //开发错误提示,嵌入到源文件    entry:{ },  //string | object | array ;这里应用程序开始执行;webpack开始打包    output:{ },  //webpack 如何输出结果的相关选项    devServer:{ },  //开发服务器配置,    module:{         //关于模块配置        rules:[]     //模块规则(配置loader、解析器等选项)    },    plugins:plugins, //附加插件列表}module.exports = webpackConfig;

1、entry参数:入口文件配置

entry: //string | array | object。入口文件是应用程序的起点入口,从这里应用程序启动执行。如果传递的是一个数组,        那么数组的每一项都会执行。规则:每个HTML页面都有一个入口起点。单页应用(SPA):一个入口起点;多页应用(MPA):多个入口起点。命名:如果传入一个字符串或字符串数组,chunk会被命名为main。如果传入一个对象,则每一个键(key)是chunk的名称,        该值描述了chunk的入口起点。在我的配置中,由于是对多页面的处理,所以采用entry:object;每一个键(key)是chunk的名称,同时又是chunk的入口起点。

webpack.config.js

//glob在webpack中对文件的路径处理var glob = require('glob');const HtmlWebpackPlugin = require("html-webpack-plugin")var webpackConfig = {    /*webpack基础配置*/};    //封装方法,获取指定路径下的入口文件//返回的结构 [ 'src/pages/contact/contact/index.js',//            'src/pages/index/index/index.js',//            'src/pages/join/join/index.js',//            'src/pages/pagea/index/index.js' ]function getEntries(globPath){    //方法: glob.sync(pattern,[options]);该方法成功后,返回匹配搜索之后的数组,    //没有匹配返回一个空数组;pattern:'src/pages/**/index.js';这里‘**’匹配模式表示的是    位于src/pages/和/index.js的这两层文件名    var files = glob.sync(globPath),    entries = {};    files.forEach(function(filepath){        //取倒数第二层(pages下面的文件夹)做包名        var split = filepath.split('/');        var name = split[split.length - 2];                entries[name] = './' + filepath;    });    return entries;};//var entries = getEntries('src/pages/**/index.js');Object.keys(entries).forEach(function(name){    //这里循环输出每一个页面的entry,    webpackConfig.entry[name] = entries[name];    //判断是否是登陆页面;因为登陆页面和其他页面是两个不同的模板    //HtmlWebpackPlugin插件的详细用法参考:https://segmentfault.com/a/1190000007294861    if(name == 'login/login'){        var plugin = new HtmlWebpackPlugin({            //有模板生成的html文件名            filename:'login.html',            //登陆页面的html模板            template:'./src/login.html',            inject:'body',            chunks:['commons',name]        });    }else{        var plugin = new HtmlWebpackPlugin({            //有模板生成出来的html文件名            filename:name + '.html',            //除登陆页面外,多个页面使用同一个模板            template:'./src/index.tmpl.html',            inject:'body',            chunks:['commons',name]        })    }})

2、output参数:输出文件配置

output包括一组选项,指示webpack如何去输出、以及在哪里输出你的(bundle、asset和其他你所打包或使用webpack载入的任何内容)。

常用的参数path、publicPath、filename、chunkFilename.
在我的webpack.config.js的配置中:
webpack.config.js:

var webpackConfig = {        devtool:'inline-source-map',        entry:{ },        output:{            path:__dirname + 'build',            filename: "js/[name].bundle-[chunkhash:8].js"        },        devServer:{ },        module:{            rules:rules        },        plugins:plugins    }

output.path:string;output目录对应一个绝对路径 #path:path.resolve(__dirname,'bulid')

output.filename:string;此选项决定了每一个输出bundle的名称。这些bundle将写入到output.path选项指定的目录下。
两种情况:
1、对于单入口起点,filename会是一个静态名称。filename:"bundle.js"。
2、对于多入口起点、代码拆分或各种插件创建多个bundle,应该使用以下四种方式:

(a)使用入口名称:  filename:"[name].bundle.js"; (b)使用内部chunk id : filename:"[id].bundle.js"; (c)使用每次构建过程中,唯一的hash生成:filename:"[name].[hash].bundle.js"; (d)使用基于每个chunk内容的hash: filename:"[chunkhash].bundle.js";

这里涉及到缓存的知识:参考文档:

可以通过命中缓存的技术,以降低网络流量,使网站加载速度更快,如果我们在部署新版本时不更改资源的文件名,浏览器就可能认为它没有更新,就会使用它的缓存版本,通过必要的配置,以确保webpack编译生成的文件能够被客户端缓存,而在文件内容变化后,能够请求到新的文件。
输出文件的文件名(output.filename):
通过使用output.filename的不同的方式,可以确保浏览器获取修改后的文件。文档中建议使用[chunkhash]替换,在文件名中包含一个chunk相关的哈希。

3、常用loader(加载器)配置:module参数

Loaders的常用的加载器,参考文档:

安装相对应的loader:

npm install --save-dev css-loader;作用是指示webpack对每个.css使用css-loader

使用Loader的方法:

在应用程序中,有三种使用loader的方式:1、配置(推荐):在webpaack.config.js文件中指定loader。2、内联:在每个import 语句中显示指定loader。3、CLI: 在shell命令中指定它们。配置[Configuration]:    module.rules允许你在webpack配置中指定多个loader。这是展示loader的一种简明方式,有助于使代码变得简洁。    这是我经常用的书写方式。    module:{        rules:[            {              test:/\.css$/,              use:[                  { loader: 'style-loader' },                  {                    loader:'css-loader',                    options{                        modules:true                    }                  }              ]            }        ]    }

下面介绍一些常用的loader的用法:

1、html-loader

html-loader 导出HTML为字符串,需要引用静态资源。

关于模板(templating)的有好几种:html-loader、pug-loader、jade-loader、markdown-loader、posthtml-loader、react-markdown-loader、handlebars-loader、markup-inline-loader。

只介绍html-loader的使用:参考文档:https://doc.webpack-china.org/loaders/html-loader安装:    npm install --save-dev html-loader用法:    默认情况下,每个本地的都需要require(require(./image.png))来进行加载。    不过这需要file-loader或url-loader(这个后面有介绍)。示例:    module:{        rules:[{            test:/\.html$/,        #匹配以‘.html’结尾的模块;            loader:'html-loader',  #html-loader加载器            options:{              #可选项(一般用于上线的webpack.build.config中)                minimize: true,            #Boolean: 是否压缩html                removeComments: true,      #Boolean: 是否删除注释                  collapseWhitespace: true, #Boolean: 是否删除空格              }        }]    }

2、babel-loader

babel-loader 加载es2015代码,并且将代码转译为ES5

参考文档:

安装:npm install --save-dev babel-loader babel-core babel-preset-env用法:在webpack配置对象中,需要添加babel-loader到module的loader列表中,像下面这样:module:{    rules:[        {            test:/\.js$/,          #匹配以‘.js’结尾的文件            loader:'babel-loader', #babel-loader加载器            include:path.resolve(__dirname,'src'),   #只包括src             exclude:path.resolve(__dirname,'node_modules'), #排除node_module            query:{                presets:['preset-env']            }        }    ]}babel-loader编译很慢的,为了确保转译尽可能少的文件,可能使用/\.js$/来匹配,排除node_modules,配置exclude选项,提高编译速度。

3、less/css-loader

less/css-loader是对css的处理,下面分别介绍处理css时,用到的css-loader、less-loader、style-loader、postcss-loader。这几种loader配合使用。

一次安装所有的loader:
npm install --save-dev autoprefixer css-loader less-loader style-loader postcss-loader
less-loader:

大家可以了解一些less的用法:http://less.bootcss.com/less-loader: 把less编译成css。使用css-loader或者raw-loader把它变成一个JS模块,并使用ExtractTextPlugin把它解压到一个单独的文件中,这样你的样式不依赖于JavaScript。另外,less-loader并不会针对url()语法做特别的转换,如果想把url()语句里涉及的文件(比如图片、字体文件)也一并用webpack打包的话,就必须利用css-loader进一步处理。参考文档:https://doc.webpack-china.org/loaders/less-loader/用法:将css-loader、style-loader、less-loader链式调用,使用ExtractTextPlugin把它解压到单独的文件webpack.config.js:    const ExtractTextPlugin = require("extract-text-webpack-plugin");    plugin = [...     new ExtractTextPlugin("css/[name]-[chunkhash:8].css",{allChunks:false}), //css分离和压缩     ...    ];    module:{        rules:[            {                text:/\.less$/,                use:ExtractTextPlugin.extract({                    fallback:"style-loader",                    use:[                        {                            loader:'css-loader',                            options:{                                minimize:false;    #是否对css进行压缩                            }                        },                        {                            loader:'postcss-loader', #自动添加浏览器前缀                        },                        {                            loader:'less-loader'                        }                    ]                })            }        ]    }

css-loader:

用法:css-loader解释@import 和 url(),在import/require()后再解析它们。选项:    参考文档:https://doc.webpack-china.org/loaders/css-loader/    常用的就是是否对css进行代码压缩(Minification):minimize:Boolean;还有就是对url()语句的处理。    在less/css里url()语句,一般使用相对路径的方式来指定文件路径;请不要使用‘/’开头    (即相对于网站的根目录,因为对于文件系统来说,这令人混淆)。

style-loader:

用法: 通过注入

postcss-loader:

参考文档:https://doc.webpack-china.org/loaders/postcss-loader/用法:用于处理浏览器前缀,这里使用postcss-loader需要在写一个关于postcss.config.js的文件。postcss.config.js:    module.exports = {        plugins:[            require('autoprefixer')        ]    }autoprefixer:将使用基于当前浏览器流行度和属性支持的数据为您应用前缀。

4、url/file-loader

用于打包处理图片和字体。

安装:
npm install --save-dev file-loader url-loader
file-loader:

参考文档:https://doc.webpack-china.org/loaders/file-loader/功能:将源文件迁移到指定的目录,返回新的文件路径。用法:传入name参数,该参数接受以下变量:    以我的src/images/banner.jpg为例;    [ext]:文件的后缀名,‘jpg’。    [name]:文件名本身,‘banner’。    [path]:相对于当前执行webpack命令的目录的相对路径(不含文件名本身),在我的项目中源文件中的图片是在‘src/images/**’中,在根目录内执行webpack命令,也就是当前的上下文环境与src目录同级    [hash]:源文件内容的hash,用于缓存解决方案    webpack.config.js     {         module:{             rules:[                 test:/\.(png|jpg|gif)$/,      #匹配图片资源                 loader:'file-loader',                 options:{                     name:'images/[name].[ext]' #新文件的路径                 }             ]         }     }     当npm run build 后,我的图片资源路径是要拼上webpack配置中的output.publicPath参数;所以最终的图片路径是‘build/iamges/banner.jpg’,

url-loader:

参考文档:https://doc.webpack-china.org/loaders/url-loader/功能:在文件大小(单位byte)低于指定的限制时,将源文件转换成DataUrl(声明文件base64编码)。图片和字体文件的DataUrl都是可以被浏览器所识别的,减少HTTP连接数。参数:    limit:Number;     #表示目标文件的体积小于限定的字节就用url-loader;大于限制字节时,就用file-loader来处理    mimetype:String;   #指定文件的类型(否则从文件的扩展名)    fallback:String;   #当文件大于限制时(以字节为单位)为文件指定加载程序webpack.config.js     {         module:{             rules:[                 test:/\.(png|jpg|gif)$/,      #匹配图片资源                 loader:'url-loader',                 options:{                     limit:8192,                 }             ]         }     }

字体文件:

{    test:/\.(eot|woff|woff2|ttf|svg)$/,    loader:'url-loader'}

4、plugins插件的介绍

有时候搞不明白 plugins 和 loaders的区别:

插件(plugins)是用来拓展webpack功能的,它们会在整个构建过程中生效,执行相关的任务。
loaders是在打包构建过程中用来处理源文件的(.js、.less、.html、img、字体),一次处理一个;
插件并不直接操作单个文件,它直接对整个构建过程作用。
webpack.config.js

var plugins = [    new webpack.ProvidePlugin({        $:"jquery",        jQuery:"jquery",        "window.jQuery":"jquery"    }),    new ExtractTextPlugin("css/[name]-[chunkshash:8].css",{allChunks:false}),    new webpack.optimize.CommonsChunkPlugin({        name:"commons",        minChunks:2    })];

plugins:Array(数组),直接把要用的插件实例化之后丢进去就好了。

1、插件ProvidePlugin

关于插件ProvidePlugin自动加载模块,而不必到处 import 或 require 。为什么要对jQuery进行全局定义?(个人水平有限。)

参考:
使用:jQuery
要自动加载jquery , 我们可以将三个变量都指向对应的node模块:

new webpack.ProvidePlugin({        $:"jquery",        jQuery:"jquery",        "window.jQuery":"jquery"    }),

然后在我们任意源码中:

//in a module$('#item');  //起作用jQuery('#item'); //起作用window.jQuery('#item'); //起作用//$ 自动被设置为“jquery”输出的内容。

2、插件ExtractTextPlugin

作用:从bundle中提取文本(css)到单独的文件。

安装:npm install --save-dev extract-text-webpack-plugin
用法:

const ExtractTextPlugin = require("extract-text-webpack-plugin");module.exports = {    module:{        rules:[            {                test:/\.css$/,                use:ExtractTextPlugin.extract({                    fallback:"style-loader",                    use:"css-loader"                })            }        ]    },    plugins:[        new ExtractTextPlugin("css/[name]-[chunkhash:8].css",{allChunks:false}),    ]}

它会将所有的入口chunk(entry chunks)中引用的*.css,移动到和html页面name对应的独立分离的css文件。样式不在内嵌到JS bundle中。如果你的样式文件大小较大,就会做更快提前加载,因为css bundle 会跟js bundle 并行加载

参考文档:

2、插件CommonsChunkPlugin

CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件的功能,这个文件包括多个入口chunk的公共模块。通过将公共模板拆出来,最终合成的文件能够在最开始的时候加载一次,便缓存供后续使用,这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。

例子:
公共chunk用于入口chunk:生成一个额外的chunk包含入口chunk 的公共模块。

new webpack.optimize.CommonsChunkPlugin({    name:"commons",          //公共chunk的名称    filename:"commons.js",    //公共chunk的文件名    minChunks:3 ,             //模块必须被三个 入口共享      chunks:["pageA","pageB"], //只使用这些入口chunks})

3、插件HtmlWebpackPlugin

HtmlWebpackPlugin简化了HTML文件的创建,加载自己的模板。

安装:npm install --save-dev html-webpack-plugin
使用webpack生成HTML页面的好处:
对于页面相同或相似的部分,尤其导航栏、侧边栏、还有页尾,基本是一致的,如果需要修改页面,传统的都是每个页面都要修改,可维护性很差。

而“用webpack生成html页面”,实际是依赖前端的模板引擎将页面的各个部分拼接在一起,达到公共模块的复用。

利用html-webpack-plugin生成html页面:

html-webpack-plugin的配置项:    每一个html-webpack-plugin的只对象实例化一个页面,因此多页面时,就要配置多个html-webpack-plugin的对象实例。     Object.keys(entries).forEach(function(name){         //每一个页面生成一个entry         webpackConfig.entry[name] = entries[name];         var plugin = new HtmlWebpackPlugin({             //生成出来的html文件名             filename: name + '.html',             //这里多个页面使用一个公共模板             template:'./src/index.tmpl.html',             inject:'body',             chunks:['commons', name]         })         plugins.push(plugin)     }) entries是所有的入口*.js    多页应用常用的配置:        filename:生成的网页html文件的文件名,可以利用‘/’来控制文件目录结构,其最终生成的路径,        是基于webpack配置中的output.path的。        template: 指定一个基于模板引擎语法的模板文件,如果想使用其他格式的模板文件,        需要在webpack配置里设置好相应的loader,比如html-loader。如果是单页应用,那么这个参数        不指定也可以,但对于多页应用来说,我们依赖模板引擎给我们拼装页面,这个参数非常重要。        inject: 将加载的js文件插入到哪里,默认是插入到的末端,如果设置'head',        则把

转载地址:http://tqcio.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
unbantu安装 mysql --- 百度云
查看>>
sql2008性能计数器注册表配置单元一致性失败
查看>>
LNMP环境搭建
查看>>
我的友情链接
查看>>
学习linux—— 磁盘相关指令
查看>>
词法分析与语法分析简介
查看>>
JS中的默认行为
查看>>
我的友情链接
查看>>
Checkio代码闯关小计
查看>>
从oracle到mysql,主从到分库,一个普通项目数据库架构的变迁
查看>>
从零开始学wordpress 之四
查看>>
[LeetCode] Course Schedule
查看>>
selenium层级定位及鼠标键盘操作
查看>>
SpringBoot跨域问题解决方案
查看>>
(转载)hibernate3.0配置文件模板
查看>>
46、练习:输出指定目录下的所有文件名称
查看>>
IP地址与数字地址相互转换
查看>>
Knockout.Js官网学习(创建自定义绑定)
查看>>
win10 x64中 windbg x64 安装配置符号库
查看>>