大家好!我是萝卜上一篇文章介绍了入口和出口相关的配置。本文将介绍Webpack的其他重要配置。resolveWebpack构建时,会从入口文件(entry)开始遍历,找到各个模块的依赖。resolve配置是为了帮助Webpack找到依赖的模块。通过resolve配置,可以帮助Webpack快速找到依赖,也可以替换相应的依赖(比如开发环境使用的是dev版本的lib等)。下面介绍一下常用的resolve配置。1.resolve.extensionsresolve.extensions是帮助Webpack解析扩展的配置,默认值:['.wasm','.mjs','.js','.json'],所以我们引入js和json文件,可以不写他们的扩展名,通常我们可以加上.css,.less等,但是要保证同目录下没有同名的css或者js文件。如果它们存在,请写下整个路径。module.exports={resolve:{extensions:['.js','.json','.css']}}2.resolve.aliasresolve.alias是最常用的配置,设置alias可以帮助webpack更快的找到模块依赖,也方便我们写代码。比如我们在实际开发中经常将源代码放在src文件夹下。目录结构如下:src├──lib│└──utils.js└──pages└──demo└──index.jsinsrc如果要引用src/lib/utils.jsin/pages/demo/index.js,可以通过:importutilsfrom'../../lib/utils',目录越深越难看,这个可以通过设置alias缩短,例如:module.exports={resolve:{src:path.resolve(__dirname,'src'),'@lib':path.resolve(__dirname,'src/lib')}}设置别名后,我们可以无论目录结构如何,直接在任何文件中使用require('@lib/utils')或require('src/lib/utils')来帮助Webpack定位模块。提示:别名可以使用@!~和其他特殊字符。在实际使用中,别名使用一种类型,或者不同类型使用一种类型,这样可以区别于正常的模块导入,增加识别度。3.resolve.mainFields有一些我们使用的模块会针对不同的宿主环境提供几段代码,比如针对ES5和ES6提供两段代码,或者针对浏览器环境和nodejs环境提供两段代码,此时在package.json中将在文件中进行以下配置:{'jsnext:main':'es/index.js',//使用ES6语法的代码入口文件'main':'lib/index.js',//使用ES5语法的代码入口文件,node'brower':'lib/web.js'//Thisisaversionspecificallyforbrowsers}在Webpack中,会根据resolve.mainFields的设置决定先使用哪个版本的模块代码。mainFields默认配置如下:module.exports={resolve:{mainFields:['brower','main','jsnext:main]}}webpack会按照数组的顺序在package.json文件中搜索,并且只会使用找到的第一个文件.如果我们想优先处理ES6代码,可以这样配置:module.exports={resolve:{mainFields:['jsnext:main,'main','brower']}}下面是不常用的或者比较简单的配置:resolve.mainFiles:解析目录时的默认文件名,默认是index,即搜索目录下的文件;索引+解析.扩展;resolve.modules:搜索模块依赖时,默认是node_modules;resolve.symlinks:是否Resolveconforminglinks(软链接,symlinks);resolve.plugins:添加解析插件,数组格式;resolve.cachePredicate:是否缓存,支持boolean和function,function传入一个带有path和require的对象,必须返回一个boolean值。modulewebpack在解析模块时,不同的模块需要用不同类型的模块处理器进行处理。这部分设置在模块配置中。模块有两种配置:module.noParse和module.rules。1、module.noParsemodule.noParse配置项可以让Webpack忽略一些没有模块化的文件的递归解析处理。这样做的好处是可以提高构建性能。接收到的类型是正则表达式或正则表达式数组或者是接收模块路径参数的函数:module.exports={module:{//使用正则表达式noParse:/jquery|loadsh///使用函数noParse:(content)=>{//content代表一个模块文件路径//returntrueorfalsereturn/jquery|loadsh/.test(content);}}}Tips:这里一定要保证被排除的模块代码中不能包含import、require、define等,以保证webpack打包的所有模块都被包含进来,否则打包后的js会因为缺少模块而报错。2.解析器控制模块化语法因为webpack以模块化的JavaScript文件为入口,所以内置了对模块化JavaScript的解析功能。支持AMD、Commonjs、SystemJs、ES6。parse属性可以配置哪些模块语法被解析,哪些不被解析。简单来说,如果设置了parser.commonjs=false,那么代码使用commonjs的require语法导入模块,相应的模块不会被解析成依赖,也不会被处理。支持的选项包括:module:{rules:[{test:/\.js$/,use:['babel-loader'],parser:{amd:false,//禁用AMDcommonjs:false,//禁用CommonJS系统:false,//禁用SystemJS和谐:false,//禁用ES6导入/导出requireInclude:false,//禁用require.includerequireEnsure:false,//禁用require.ensurerequireContext:false,//禁用require.contextrequireJs:false,//disablerequirejsbrowserrify:false//Disablebrowserify}}]}Tips:parser是语法限制,noParse只能控制哪些文件不被解析。3.module.rulesmodule.rules是在处理模块时,将满足规则条件的模块提交给相应的处理器进行处理。它通常用于配置加载程序。它的类型是一个数组,数组中的每一项描述了如何处理一些文件。每条规则大致可以由以下三部分组成:条件匹配:通过test、include、exclude等配置命中可以应用规则的模块文件;应用规则:对于满足匹配条件的模块,使用use配置项应用loader,可以从后到前依次应用一个loader或应用一组loader。当然,我们也可以给对应的loader传入不同的参数;resetorder:一组loader的默认执行顺序是从后到前(或从右到左)执行,通过enforce选项,可以将其中一个loader的执行顺序放在前面(pre)或at结束(邮寄)。4.条件匹配上面提到了条件匹配相关的配置包括test、include、exclude、resource、resourceQuery和issuer。符合条件的对象包括三种类型:resource、resourceQuery和issuer。resource:请求文件的绝对路径。已经按照resolve规则解决了;issuer:请求资源(requestedtheresource)的模块文件的绝对路径,即导入时的位置。例如:import'./style.css?inline'fromapp.js:resourceis/path/to/style.css;resourceQuery在?;之后内联发行人是/path/to/app.js。再举个例子,下面规则的配置项匹配条件是:来自src和test文件夹,不包括node_modules和bower_modules子目录,模块的文件路径是以.tsx和.jsx结尾的文件.{测试:[/\.jsx?$/,/\.tsx?$/],包括:[path.resolve(__dirname,'src'),path.resolve(__dirname,'test')],排除:[path.resolve(__dirname,'node_modules'),path.resolve(__dirname,'brower_modules')]}loader配置Loader是一个解析处理器,通过loader我们可以将ES6语法的js转成ES5语法,并将图片转成base64的dataURL,JavaScript文件中css和html的直接导入也是通过相应的loader实现的。在我们使用相应的加载器之前,我们需要先安装它。比如我们要在JavaScript中引入less,需要安装less-loader:npmi-Dless-loader并在module.rules中指定*.less文件使用less-loader:Module.exports={Module:{规则:[Test:/\.less$/,Use:'less-loader']}}简单理解上面的配置,测试项使用/.less$/正则模式匹配需要处理的模块文件(也就是less后缀的文件),然后交给less-loader处理。这里的less-loader是一个字符串,最终会直接作为require()的参数。这样less文件就会被less-loader处理成对应的css文件。1、Loader的参数传递给loader有两种方式:通过options传入。通过查询传入。//通过选项传入模块:{rules:[{test:/\.html$/,use:[{loader:'html-loader',options:{minimize:true,removeComments:false,collapseWhitespace:false}}]}]}//通过queyr传入模块:{rules:[{test:/\.html$/,use:[{loader:'html-loader?Minimize=true&removeComments=false&collapseWhitespace=false',}]}]}PluginPluginPlugin是Webpack的重要组成部分。通过plugin可以解决loader解决不了的问题。Webpack本身是由很多插件组成的,所以内置的插件也很多,我们可以直接通过webpack对象的属性来使用,例如:webpack.optimize.UglifyJsPluginModule.exports={//...Plugins:[//压缩jsNewwebpack.optimize.UglifyJsPlugin()]}除了内置插件,我们还可以通过NPM包使用插件://非默认插件constExtractTextPlugin=require('extract-text-webpack-plugin');Tips:loader是面向解决某个或某类模块的问题,而plugin是面向整个项目的,解决loader解决不了的问题。小结本文对Webpack除entry和output之外的基本配置项进行了讲解。这里总结了经常配置的和比较重要的配置项列表,供大家查阅:resolve:模块依赖搜索相关配置;resolve.extensions:可以省略解析扩展的配置。配置过多会导致webpack解析效率下降;resolve.alias:设置alias可以帮助webpack更快的找到模块依赖,简化写代码时相对路径的写法;module.rules:loader相关的配置,每条规则的重要内容是:test:正则匹配待处理的模块文件;use:loader数组配置,里面有loader和options;包括:包括;排除:排除;插件:插件。
