《深入浅出Webpack》阅读笔记(三)
三、 webpack基本配置速查
配置webpack的方式有一下两种:
(1)通过JavaScript文件描述配置,例如webpack.config.js
文件里的配置。
(2)执行Webpack可执行文件时通过命令参数传入,例如webpack--devtool source-map
。
1、Entry
模块配置的入口,webpack执行构建的第一步,必填。
-
context
webpack在寻找相对路径文件时会以context为根目录,context默认为执行启动webpack时所在的当前工作目录。改变context默认配置,可以如下设置:module.exports = { context: path.resolve(_dirname,'app') }
还可以通过在启动webpack时带上参数webpack --context来设置context。
entry的路径及其依赖的模块的路径均可能采用相对于context的路径描述,context会影响到这些相对路径所指向的真实文件。 -
入口文件的类型
(1)string:'./app/entry'
(2)array:['./app/entry1' , './app/entry2']
搭配output.library配置使用,只有数组中的最后一个入口文件的模块会被导出。
(3)object:{a:'./app/entry-a', b:['./app/entry-b1' , './app/entry-b2']}
配置了多个入口文件 -
Chunk的名称
如果entry是string或Array类型,则会产生一个chunk,此时名称为main
如果是object类型,可能会出现多个chunk,此时chunk的名称是object键值对中键的名称。 -
配置动态Entry
如果项目中有多个页面,则需要为每个页面的入口配置一个Entry,随着页面的增多,可以将Entry设置成一个函数动态的返回配置。
代码配置如下://同步函数 entry :()=>{ return { a: './pages/a', b: './pages/b', } }; //异步函数 entry :()=>{ return new promise ((resolve)=>{ resolve({ a: './pages/a', b: './pages/b', }); }); };
2、Output输出
Output配置如何输出最终想要的代码。Output是一个Object。
-
filename
配置输出文件的名称,如果只有一个输出文件则可以写成静态文件filename : ‘bundle.js’
;在有多个chunk输出时,需要借助模板和变量。可以根据Chunk的名称区分输出的文件:filename:'[name].js'
其中[name]
表示使用内置的name替换[name],每个要输出的Chunk都会通过这个函数去拼接输出的文件名称。 -
chunkFilename
output.chunkFilename配置无入口的chunk在输出时的文件名称,chunkFilename只用于指定在运行过程中生成的chunk在输出时的文件名称。
在运行时生成chunk的常用场景有:
(1)使用CommonChunkPlugin
(2)使用import('path/to/module')
动态加载等。 -
path
output.path配置输出文件存放在本地的目录。path: path.resolve(_dirname, 'dist_[hash]')
-
publicPath
在复杂的项目中有一些构建出的资源需要异步加载,加载这些异步资源需要对应的URL地址,output.publicPath配置发布到线上资源的URL前缀,为string类型。默认值时空字符串‘’,即相对路径。
-
crossOriginLoading
webpack输出的部分代码块可能需要异步加载,异步加载时通过JSONP方式实现的,JSONP的原理是动态向HTML中插入一个<script src = "url"></script>
标签去加载异步资源。output.crossOriginLoading
用于配置异步插入的标签的crossorigin的值(取值为anonymous(不带用户的cookies);use-credentials(带用户的cookies))。 -
libraryTarget和library
使用webpack构建一个可以被其他模块导入使用的库时用到。
output.library
配置以何种方式导出库
output.library
配置导出库的名称
(1)var:编写的库通过var被赋值给通过library指定名称的变量。
(2)commonjs:编写的库将通过CommonJS规范导出。
(3)commonjs2:commonjs2与commonjs的区别在于CommonJS只能用exports导出,而CommonJS2在CommonJS的基础上增加了module.exports方式导出。 -
this
编写的库将通过this被赋值给通过library指定的名称。//webpack输出的代码 this['LibraryName'] = lib_code; //使用库的方法 this.LibraryName.doSomething();
-
window
编写的库通过window被赋值给通过library指定的名称。 -
global
编写的库通过window被赋值给通过library指定的名称。//webpack输出的代码 global['LibraryName'] = lib_code; //使用库的方法 global.LibraryName.doSomething();
-
libraryExport
配置要导出的模块中哪些子模块需要被导出。只有在output.libraryTarget被设置成commonjs或者commonjs2时使用才有意义。
3、Module模块
module配置处理模块的规则
-
配置loader
例子:module:{ rules:[ { test:/\.js$/, //使用babel-loader转换JavaScript文件, //?cacheDirectory表示传给babel-loader的参数,用于缓存babel的编译结果,加快重新编译的速度。 use:[ { loader:'babel-loader', options:{ cacheDirectory:true, }, enforce:'post' }, ], include:path.resolve(__dirname,'src') }, { test:/\.scss$/, //使用loader去处理SCSS文件 //处理顺序为从后到前,即先交给sass-loader处理,再将结果交给CSS-loader,最后交给style-loader use:['style-loader','css-loader','sass-loader'], exclude:path.resolve(__dirname,'node_modules') }, { //对非文本文件采用 file-loader 加载 test: /\.(gif|png|jpe?g|eot|woff|ttf|svg|pdf) $/, use: ['file-loader'], } ] }
当loader需要传入很多参数的时候,可以通过一个Object来描述,如上述代码中的babel-loader。其中test、include、exclude三个配置项也支持数组类型,数组中的每项之间是“或”的关系。
由上述例子可知,配置一向rules时可以通过以下方式完成:
(1)条件匹配:test、include、exclude三个配置项来选中Loader要应用规则的文件。
(2)应用规则:使用use配置项来应用一个或多个loader,还可向loader传入参数。
(3)重置顺序:一组loader的执行顺序默认是从右向左的,通过enforce选项可以将其中一个loader的执行顺序放在最前或者最后。 -
noParse
该配置项可以让webpack忽略对部分没有采用模块化的文件的递归解析和处理,从而提高构建性能。一些库如jQuery,ChartJS庞大且没有模块化标准。
noParse是可选的配置项,类型是RegExp、[RegExp]、function中的一种。//正则表达式 noParse: /jQuery|chartjs/, //使用函数 noParse: (content)=>{ return /jQuery|chartjs/.test(content); }
被忽略的文件中不应包含import、require、define等模块化语句。
-
parser
解析选项对象,所有应用的解析选项都将合并。该属性可以更细粒度的配置哪些模块语法被解析,哪些不被解析。与noParse(只能控制哪些文件不被解析)不同的是,parser可以精确到语法层面。parser:{ amd:false, //禁用AMD commonjs:false, //禁用commonjs requireInclude:false, //禁用require.include ... }
4、Resolve解析
Resolve配置webpack如何寻找模块所对应的文件
-
alias
resolve.alias配置项通过别名来将原导入路径映射成一个新的导入路径,例如://将导入语句里的components关键字替换成`./src/components` resolve:{ alias:{ components:'./src/components' } }
alias还支持通过$符号缩小范围到只命中以关键字结尾的导入语句。
//只命中以react结尾的导入语句 resolve:{ alias:{ react$:'/path/to/react.min.js' } }
-
mainFields
Webpack会根据mainField的配置决定优先采用哪份代码,默认为mainFileds:['browser','main']
Webpack会按照数组里的顺序在package.json文件里寻找,只会使用找到的第一个文件。 -
extensions
导入语句没有带文件后缀时,webpack会自动带上后缀去尝试访问文件是否存在。extensions:['.js','.json']
webpack会优先寻找.js文件,如果不存在再去寻找.json文件。 -
modules
配置Webpack去哪些目录下寻找第三方模块,默认只会去node_modules目录下寻找。
应用场景:项目中会有一些模块被其他模块大量依赖和导入,由于其他模块的位置不定,针对不同的文件需要不同的相对路径,可以利用modules配置项优化。modules:['./src/components','node_modules']
-
descriptionFiles
该配置描述第三方模块的文件名称,也就是package.json文件,descriptionFiles:['package.json']
-
enforceExtension
如果被配置为true,则所有导入语句都必须带文件后缀。 -
enforceModuleExtension
类似于enforceExtension,但只针对node_modules下的模块生效。两者经常搭配使用,因为安装的第三方模块中大多数导入语句都没有文件后缀,所以通过配置enforceModuleExtension:false
来兼容第三方模块。
5、Plugin
plugin用于扩展Webpack的功能,接收一个数组,数组中的每一项都是一个要使用Plugin的实例。
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
webpack无法直接实现的功能可以在社区找到开源的plugin解决。
6、DevServer
配置DevServer除了可以在配置文件中通过devserver传入参数,还可以通过命令行参数传入。只有通过DevServer启动Webpack时,配置文件里的DevServer才会生效。
-
hot
devserver.hot配置是否启用模块热替换功能。 -
inline
DevServer的实时预览功能依赖一个注入页面里的代理客户端,去接收来自DevServer的命令并负责刷新网页的工作。devserver.inline用于配置是否将这个代理客户段自动注入将运行在页面中的chunk里,默认自动注入。
使用DevServer的模块热替换机制去实现实时预览,最方便的方法是直接开启inline。 -
historyApiFallback
用于方便的开发使用了HTML5 History API的单页应用,要求服务器在针对任何命中的路由时,都返回对应的HTML文件。 -
contentBase
配置了DevServerHTTP服务器的文件根目录。 -
headers
在HTTP响应中注入一些HTTP响应头 -
host
配置DevServer服务监听的地址,只能通过命令行参数传入。 -
port
配置DevServer服务监听的端口 -
allowHosts
白名单列表,只有HTTP请求的HOST在列表里才正常返回。 -
disableHostCheck
用于配置是否关闭用于DNS重新绑定的HTTP请求的Host检查。 -
HTTPS
使用HTTPS服务,可以配置自己的证书。 -
clientLogLevel
配置客户端的日志等级。 -
compress
配置是否启用Gzip压缩。 -
open
用于在devServer启动且第一次构建完时,自动为我们的系统的默认浏览器去打开要开发的网页。
7、其他配置项
-
Target
让Webpack构建出针对不同运行环境的代码 -
Devtool
配置Webpack如何生成 Source Map -
Watch和WatchOption
监听模式,使用WatchOption灵活的控制监听模式。 -
Externals
告诉在Webpack要构建的代码中使用了哪些不用被打包的模块,即这些模块时外部环境提供的,webpack在打包时可以忽略他们。 -
ResolveLoader
用来告诉Webpack如何去寻找loader。
8、整体配置结构
9、多种配置类型
-
导出一个function
module.exports = function (enc = {} ,argv){ }
-
导出一个返回promise的函数
module.exports = function (enc = {} ,argv){ return new Promise((resolve,reject)=>{ }) }
-
导出多份配置:数组
module.exports = [ {}, function(){ renturn{} }, function(){ return Promise(); }]
10、总结
- 配置Entry: 让源文件加入构建流程中被webpack控制。
- 配置output: 自定义输出文件的位置和名称。
- 配置resolve: 自定义寻找依赖模块
- 配置module: 自定义解析和转换文件的策略
- 配置Plugin: 其他需求