webpack配置项解析

context

Webpack 在寻找相对路径的文件时会以 context 为根目录, context 默认为执 行启动 Webpack 时所在的当前工作目录。 如果想改变 context 的默认配置,则可以在配置文件 里这 样设置它 : module.exports ={ context: path.resolve (一_dirname ,’ app ’) }

Chunk

Webpack会为每个生成的 Chunk取一个名称, Chunk的名称和 Entry的配置有关。

  • 如果 entry 是一个 string 或 array,就只会生成一个 Chunk,这时 Chunk 的名 称是 main。
  • 如果 entry 是一个 object,就可能会出现多个 Chunk,这时 Chunk 的名称是 object 键值对中键的名称。

output

filename

在有多个 Chunk 要输出时,就需要借助模板和变量了。前面讲到,Webpack 会为每个Chunk 取一个名称,所以我们可以根据 Chunk 的名称来区分输出的文件名: filename : ’[name].js ’

chunkFilename

output.chunkFilename 配置无入口的 Chunk 在输出时的文件名称。 chunkFilename 和filename 非常类似, 但 chunkFilename 只用于指定在运行过程中生成的 Chunk 在输 出时的文件名称。会在运行时生成 Chunk 的常见场景包括:使用 CommonChunkPlugin、使 用 import (’path/to/module ’)动态加载等。 chunkFilename支持和 filename一致的内置 变量。

path

output .path 配置输出文件存放在本地的目录,必须是 string 类型的绝对路径。通常通 过 Node.js 的 path 模块去获取绝对路径 : path: path .resolve( dirname, ’ dist [hash]’)

publicPath

output.publicPath 配置发布到线上资源的 URL 前缀,为 string 类型。默认值 是空 字符串 ” ,即使用相对路径。

crossOriginloading

webpack 输出的部分代码块可能需要异步加载,而异步加载是通过 JSONP; output.crossOriginLoading 则是用于 配置这个异步插入的标签的 crossorigin值。 script标签的 crossorigin 属性可以取以下值: • anonymous (默认),在加载此脚本资源时不会带上用户的 Cookies。 • use-credentials,在加载此脚本资源时会带上用户的 Cookies

libraryTarget 和 library

当用 Webpack 去构建一个可以被其他模块导入使用的库时,需要用到 libraryTarget 和library。 • output.libraryTarget 配置以何种方式导出库。 • output.library 配置导出库的名称。 output.libraryTarget 是字符串的枚举类型 , 支持以下配置。

  1. var (默认) 编写的库将通过 var 被赋值给通过 library 指定名称的变量 。 假如配置了 output.library=’LibraryName’,则输出和使用的代码如下 : //Webpack输出的代码 var LibraryName = lb code ; // 使用库的方法 LibraryName.doSomething(); 假如 output.libra可为空,则直接输出: lib code 其中, lib code 是指导出库的代码内容,是有返回值的一个自执行函数。
  2. commonjs 假如配置了 output.library=’LibraryName’,则输出和使用的代码如下: //Webpack 输出的代码 exports [ ’ LibraryName ’ J = lib_code; //使用库 的方法 require ( ’library-name-in-npm ’)[’ LibraryName ’] .doSomething () ; 其中, library-name-in-npm 是指模块被发布到 Npm 代码仓库时的名称 。
  3. commonjs2 编写的库将通过 CommonJS2 规范导出,输出和使用的代码如下: // Webpack 输出的代码 module.exports = lib code; //使用库的方法 require (’ l ibrary-name-in-npm ’) .doSomething () ;
  4. this 编写的库将通过 this 被赋值给通过 library 指定的名称,输出和使用的代码如 下: // Webpack 输出的代码 this [ ’ LibraryName ’] = lib code; //使用库 的方法 this.LibraryName.doSomething();
  5. window

配置 Loader

条件匹配:通过 test、 include、 exclude 三个配置项来选中 Loader 要应用 规 则的文件。 • 应用规则 : 对选中的文件通过 use 配置项来应用 Loader,可以只应用 一个 Loader 或者按照从后往前的顺序应用一组 Loader,同时可以分别向 Loader传入参数。 • 重置顺序:一组 Loader 的执行顺序默认是从右到左执行的,通过 enforce 选项可以将其中 一个 Loader 的执行顺序放到最前或者最后 。

//命中 JavaScr工pt 文件
test: /\.js丰/,
//用 babel-loader 转换 JavaScript 文件
//cacheDirectory 表示传给 babel-loader 的参数,用于缓存 babel 的编译结果,
use : [’ babel-loader?cacheDirectory ’],
//只命中 src 目录里的 JavaScript 文件,加快 Webpack 的搜索速度 
include: path.resolve( dirname, ’ src ’)
//排除 node modules 目录下的文件
exclude: path.resolve( dirname, ’ node modules ’),
// enforce :’post ’的含义是将该 Loader 的执行顺序放到最后
//enforce 的值还可以是 pre,代表将 Loader 的执行顺序放到最前面 
enforce :’ post ’

Resolve

Webpack 在启动后会从配置的入口模块出发找出所有依赖的模块, 如何寻找模块所对应的文件。 Webpack 内置 JavaScript模块化语法解析功能,默认会采用模块 化标准里约定的规 则去 寻找,但我们也可以根据自己的需要修改默认的规则。

  1. resolve.alias 配置项通过别名来将原导入路径映射成一个新的导入路径。 alias : { components : ‘ .lsrclcomponentsl ’} 这样做可能会命中太多导入语句, alias 还支持通过$符号来缩小范围到只命中以 关键字 结尾的导入语句 :
  2. resolve.modules 配置 Webpack 去哪些目录下寻找第三方模块,默认只会去 node modules 目录下寻 找 。 有 时我们的项目里会有一些模块被其他模块大量依赖和导入,由于 其他模块 的位置不定,针对不同的文件都要计算被导入的模块文件的相对路径 ,这个路径 有时会很长,就像import’../../../components/button’,这时可以利用modules 配置项优化 。假如那些被大量导入的模块都在./ src/components 目录下,则将 modules配置成 modules : [’./ src/cornponents ’,’ node modules ’]后,可以简单地 通过 工rnport ’button ’ 导入 。
  3. resolve.mainFields ,它用于配置第三方模块使用哪个入口文件。 在安装的第三方模块中都会有一个 package.json 文件,用于描述这个模块的 属性 , 其中的某些字段用于描述入口文件在哪里, resolve.mainFields 用于配置采用哪个字段 作为入口文件的描述。 resolve.mainFields 的默认值和当前的 target 配置有关系,对应的关系如 下。 • 当 target为 web或者 webworker时,值是[”browser”,”module”,”main”]。 • 当 target 为其他情况时,值是[ ”module”,”main”]。 以 target等于 web 为例, Webpack会先采用第三方模块中的 browser 宇段去寻找模块的入口 文件,如果不存在,就采用 module 字段,以此类推。

Externals

Externals用来告诉在 Webpack要构建的代码中使用了哪些不用被打包的模块,也就是说这些模板是外部环境提供的,Webpack在打包时可以忽略它们。

页面中 <script src=”path/to/jquery.js"></script>
import $ from ’jquery’;
VUE 文件里
import $ from ’jquery’;
$(’ .my-element ’);
构建后我们会发现输出的 Chunk 里包含的 jQuery 库的内容;
module.export = { externals : {
//将导入语句里的 jquery 替换成运行环境里的全局变量 jQuery 
jquery : ’ jQuery ’}}

Resolveloader

ResolveLoader 用来告诉 Webpack 如何去寻找 Loader,因为在使用 Loader 时是通过其 包名称去 引用的, Webpack需要根据配置的 Loader包名 去找到 Loader 的实际代码,以调用 Loader 去处理源文件。 ResolveLoader 的默认配置如下: module .e xports = { r esolveLoader:{ // 去哪个目录下寻找 Loader modules: [’ node modules ’ ] , // 入口文件的后缀 extensions : [ ’ . j s ’ , ’ . j son ’] , // 指明入口文件位置的字段 mainF工elds: [’ loader ’, ’ main ’] 该配置项常用于加载本地的 Loader。

提取公共代码

Webpack 内置了专门用于提取 多个 Chunk 中的公共部分的插件 CommonsChunkPlugin, CommonsChunkPlugin 的大致使用方法如下 : 通过以下配置就能从网页 A 和网页 B 中抽离出公共部分,放到 common 中 。 new CommonsChunkPlugin({ //从哪些 Chunk 中提取 chunks: [’a’,’b’], // 提取出的公共部分形成 一 个新的Chunk name : ’common ’ }) CommonsChunkPlugin 提供了一个选项 minChunks,表示文件要被提取出 来时需 要在指定的 Chunks 中出 现的最小次数。 假如 minChunks=2、 chunks=[’a’,’b’,’ c ’,’d’],则任何一个文件只要在[’ a ’,b’,’ c ’,’ d ’]中两个以上的Chunk中都出现过,这个文件就会被提取出来 。我们可以根据自己的需求去调整 minChunks 的值,minChunks越小,被提取到 common.js中的文件就会越多,但这也会导致部分页面加载的不相关的资源越多: minChunks越大,被提取到common.js 中的文件就会越少,但这会导致 common.js变小、效果变弱。

加载本地 Loader

  1. Npm link专门用于开发和调试本地的Npm模块,能做到在不发布模块的情况下, 将本 地的 一个正在开发的模块的源码链接到项目的 node modules 目录下,让项目可以 直接使 用本地的 Npm 模块。由于是通过软链接的方式实现的,编辑了本地的 Npm 模块的代 码,所 以在项目中也能使用到编辑后的代码 。 完成 Npm link 的步骤如下: • 确保正在开发的本地 Npm 模块(也就是正在开发的 Loader) 的 package. json 己 经正确配置好: • 在本地的 Npm 模块根目录下执行 npm link,将本地模块注册到全局: • 在项目根目录下执行 npm link loader-name,将第 2步注册到全局的本地 Npm 模块链接到项目的 node moduels 下,其中的 loader-name 是指在第 1 步的 package.json 文件中配置的模块名称 。 链接好 Loader到项目后我们就可以像使用 一个真正的 Npm模块一样使用本地的 Loader了
  2. Resolveloader ResolveLoader用于配置 Webpack如何寻找 Loader,它在默认情 况下只会去 node_modules 目录下寻找 。 为了让 Webpack 加载放在本地项目中的 Loader, 需要修改 resolveLoader .modules。 假如本地项目中的 Loader 在项目目录的./ loaders/loader-name 下, 则 需要如下 module .exports = { resolveLoader:{ //去哪些目录下寻找 Loader,有先后顺序之分 modules : [ ’ node modules ’,’. / loaders / ’], 加上 以上配置后, Webpack 会先去 node_modules 项目下寻找 Loader,如果找不到, 则再去 ./loaders/ 目录下寻找。

Plugin

Webpack 通过 Plugin 机制让其更灵活,以适应各种应用场 景。在 Webpack 运行的生命 周期中会广播许多事件, Plugin 可以监昕这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。