第二章:配置(深入浅出 Webpack 笔记)

Entry(配置模块的入口,必填)

context:

Webpack 在寻找相对路径的文件时会以 context 为根目录, context 默认为执行启动 Webpack 时所在的当前工作目录。

// 改变 context 的默认配置
module.exports = {
    context: path.resolve (__dirname, 'app')
}
Entry 类型:

string、array、object

Chunk 的名称:

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

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

将 Entry 设置成一个函数动态地返回配置

Output(配置如何输出最终想要的代码)

filename:

配置输出文件的名称,为 string 类型,如果只有一个输出文件,则 可以将它写成静态不变的;
在有多个 Chunk 要输出时,就需要借助模板和变量了 filename: '[name]. js'

chunkFilename:

配置无入口的 Chunk 在输出时的文件名称

path:

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

publicPath:

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

crossOriginLoading:

用于配置需要异步加载(原理:通过 JSONP 实现, 即动态地向 HTML 中插入一个 <script src="url"></script> 标签去加载异步资源)的代码块标签的 crossorigin 值,可以取以下值:

  • anonymous(默认) 在加载此脚本资源时不会带上用户的 Cookies;
  • use-credentials 在加载此脚本资源时会带上用户的 Cookies。
    通常用设置 crossorigin 来获取异步加载的脚本执行时的详细错误信息。
libraryTarget 和 library

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

  • var (默认): 编写的库将通过 var 被赋值给通过 library 指定名称的变量
  • commonjs:编写的库将通过 CommonJS 规范导出
  • commonjs2:编写的库将通过 CommonJS2 规范导出
    CommonJS2 和 CommonJS 规范很相似,差别在于 CommonJS 只能用 exports 导出,而 CommonJS2 在 CommonJS 的基础上增加了 module.exports 的导出方式。
    在 output.libraryTarget 为 commonjs2 时,配置 output.library 将没有意义。
  • this:编写的库将通过 this 被赋值给通过 library 指定的名称
  • window:编写的库将通过 window 被赋值给通过 library 指定的名称,即把库挂载到 window 上
  • global:编写的库将通过 global 被赋值给通过 library 指定的名称,即把库挂载到 global 上
libraryExport

output.libraryExport 配置要导出的模块中哪些子模块需要被导出,它只有在 output.libraryTarget 被设置成 commonjs 或者 commonjs2 时使用才有意义。

Module(配置如何处理模块)

rules:

配置模块的读取和解析规则,通常用来配置 Loader。其类型是一个数组,数组里每一项都描述了如何去处理部分文件。

1. 条件匹配:通过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件,参数可以是一个字符串、正则或数组类型。
2. 应用规则:对选中后的文件通过 use 配置项来应用 Loader,可以只应用一个 Loader 或者按照从后往前的顺序应用一组 Loader,同时还可以分别给 Loader 传入参数。
3. 重置顺序:一组 Loader 的执行顺序默认是从右到左执行,通过 enforce 选项可以让其中一个 Loader 的执行顺序放到最前或者最后。在 Loader 需要传入很多参数时,还可以通过一个 Object 来描述。
noParse:

noParse 配置项可以让 Webpack 忽略对部分没采用模块化的文件的递归解析和处理,这样做的好处是能提高构建性能。
注意被忽略掉的文件里不应该包含 import 、 require 、 define 等模块化语句,不然会导致构建出的代码中包含无法在浏览器环境下执行的模块化语句。

parser:

因为 Webpack 是以模块化的 JavaScript 文件为入口,所以内置了对模块化 JavaScript 的解析功能,支持 AMD、CommonJS、SystemJS、ES6。
parser 属性可以更细粒度的配置哪些模块语法要解析哪些不解析,和 noParse 配置项的区别。在于 parser 可以精确到语法层面, 而 noParse 只能控制哪些文件不被解析。

Resolve(配置 Webpack 如何寻找模块所对应的文件)

alias:

resolve.alias 配置项通过别名来把原导入路径映射成一个新的导入路径。

mainFields:

有一些第三方模块会针对不同环境提供几分代码,Webpack 会根据 mainFields 的配置去决定优先采哪份代码。

extensions:

在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试访问文件是否存在。 resolve.extensions 用于配置在尝试过程中用到的后缀列表。extensions: ['.ts', '.js', '.json']

modules:

resolve.modules 配置 Webpack 去哪些目录下寻找第三方模块,默认是只会去 node_modules 目录下寻找。 modules:['./src/components','node_modules']

descriptionFiles:

resolve.descriptionFiles 配置描述第三方模块的文件名称,也就是 package.json 文件。默认如下:descriptionFiles: ['package.json']

enforceExtension:

resolve.enforceExtension 如果配置为true, 所有导入语句都必须要带文件后缀。 例如开启前 import './foo' 能正常工作,开启后就必须写成 import './foo.js'

enforceModuleExtension:

enforceModuleExtensionenforceExtension 作用类似,但 enforceModuleExtension 只对 node_modules 下的模块生效。

Plugin(用于扩展 Webpack 功能)

配置 Plugin:

plugins 配置项接受一个数组,数组里每一项都是一个要使用的 Plugin 的实例,Plugin 需要的参数通过构造函数传入。

const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');

module.exports = {
  plugins: [
    // 所有页面都会用到的公共代码提取到 common 代码块中
    new CommonsChunkPlugin({
      name: 'common',
      chunks: ['a', 'b']
    }),
  ]
};

devServer

只有在通过 DevServer 去启动 Webpack 时配置文件里 devServer 才会生效,因为这些参数所对应的功能都是 DevServer 提供的,Webpack 本身并不认识 devServer 配置项。

hot:

devServer.hot 配置是否启用模块热替换功能。
DevServer 默认的行为是在发现源代码被更新后会通过自动刷新整个页面来做到实时预览,开启模块热替换功能后将在不刷新整个页面的情况下通过用新模块替换老模块来做到实时预览。

inline:

DevServer 的实时预览功能依赖一个注入到页面里的代理客户端去接受来自 DevServer 的命令和负责刷新网页的工作。

  • 如果开启 inlineDevServer 会在构建完变化后的代码时通过代理客户端控制网页刷新。如果你想使用 DevServer 去自动刷新网页实现实时预览,最方便的方法是直接开启 inline
  • 如果关闭 inlineDevServer 将无法直接控制要开发的网页。这时它会通过 iframe 的方式去运行要开发的网页,当构建完变化后的代码时通过刷新 iframe来实现实时预览。 但这时你需要去 http://localhost:8080/webpack-dev-server/实时预览你的网页了。
historyApiFallback:

单页应用要求服务器在针对任何命中的路由时都返回一个对应的 HTML 文件,浏览器端的 JavaScript 代码会从 URL 里解析出当前页面的状态,显示出对应的界面。

  • 只有一个 HTML 文件的应用:historyApiFallback: true,任何请求都会返回 index.html 文件。

  • 由多个单页应用组成的应用:需要 DevServer 根据不同的请求来返回不同的 HTML 文件,配置如下:

historyApiFallback: {
  // 使用正则匹配命中路由
  rewrites: [
    // /user 开头的都返回 user.html
    { from: /^\/user/, to: '/user.html' },
    { from: /^\/game/, to: '/game.html' },
    // 其它的都返回 index.html
    { from: /./, to: '/index.html' }
  ]
}
contentBase:

devServer.contentBase 配置 DevServer HTTP 服务器的文件根目录。 默认情况下为当前执行目录,通常是项目根目录。
contentBase 只能用来配置暴露本地文件的规则,可以通过 contentBase: false 来关闭暴露本地文件。

headers:

devServer.headers 配置项可以在 HTTP 响应中注入一些 HTTP 响应头。

host:

devServer.host 配置项用于配置 DevServer 服务监听的地址。

port:

devServer.port 配置项用于配置 DevServer 服务监听的端口,默认使用 8080 端口。

allowedHosts:

devServer.allowedHosts 配置一个白名单列表,只有 HTTP 请求的 HOST 在列表里才正常返回。

allowedHosts: [
  // 匹配单个域名
  'host.com',
  'sub.host.com',
  // host2.com 和所有的子域名 *.host2.com 都将匹配
  '.host2.com'
]
disableHostCheck:

devServer. disableHostCheck 配置项用于配置是否关闭用于 DNS 重绑定的 HTTP 请求的 HOST 检查。 DevServer 默认只接受来自本地的请求,关闭后可以接受来自任何 HOST 的请求。

https:

DevServer 默认使用 HTTP 协议服务,它也能通过 HTTPS 协议服务。

devServer: {
  https: true
}
clientLogLevel:

devServer. clientLogLevel 配置一个白名单列表,只有 HTTP 请求的 HOST 在列表里才正常返回。

clientLogLevel:

devServer. clientLogLevel 配置在客户端的日志等级,这会影响到你在浏览器开发者工具控制台里看到的日志内容。 clientLogLevel 是枚举类型,可取如下之一的值 none | error | warning | info 。 默认为 info 级别,即输出所有类型的日志,设置成 none 可以不输出任何日志。

compress:

devServer. compress 配置是否启用 gzip 压缩。默认为 false

open:

devServer. open 用于在 DevServer 启动且第一次构建完时自动用你系统上默认的浏览器去打开要开发的网页。 同时还提供 devServer.openPage 配置项用于打开指定 URL 的网页。

其它配置项

Target:

target 配置项可以让 Webpack 构建出针对不同运行环境的代码。

Devtool:

devtool 配置 Webpack 如何生成 Source Map(以方便调试),默认值是 false 即不生成 Source Map

Watch 和 WatchOptions:

Webpack 的监听模式,它支持监听文件更新,在文件发生变化时重新编译。
在使用 Webpack 时监听模式默认是关闭的,在使用 DevServer 时,监听模式默认是开启的。

Externals:

Externals 用来告诉 Webpack 要构建的代码中使用了哪些不用被打包的模块,也就是说这些模版是外部环境提供的,Webpack 在打包时可以忽略它们。
通过 externals 可以告诉 Webpack JavaScript 运行环境已经内置了哪些全局变量,针对这些全局变量不用打包进代码中而是直接使用全局变量。

module.export = {
  externals: {
      // 把导入语句里的 jquery 替换成运行环境里的全局变量 jQuery
      jquery: 'jQuery'
  }
}
ResolveLoader:

ResolveLoader 用来告诉 Webpack 如何去寻找 Loader,因为在使用 Loader 时是通过其包名称去引用的, Webpack 需要根据配置的 Loader 包名去找到 Loader 的实际代码,以调用 Loader 去处理源文件。
ResolveLoader 的默认配置如下,常用于加载本地的 Loader

module.exports = {
    resolveLoader: {
        // 去哪个目录下寻找 Loader
        modules: ['node_modules'],
        // 入口文件的后缀
        extensions: ['.js', '.json'],
        // 指明入口文件位置的字段
        mainFields: ['loader', 'main']
    }
}

总结

通常你可用如下经验去判断如何配置 Webpack

  • 想让源文件加入到构建流程中去被 Webpack 控制,配置 entry
  • 想自定义输出文件的位置和名称,配置 output
  • 想自定义寻找依赖模块时的策略,配置 resolve
  • 想自定义解析和转换文件的策略,配置 module,通常是配置 module.rules 里的 Loader
  • 其它的大部分需求可能要通过 Plugin 去实现,配置 plugin
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 模块化 模块化是指把一个复杂的系统分解到多个模块以方便编码。 缺点 命名空间冲突,两个库可能会使用同一个名称,例如...
    Upcccz阅读 585评论 0 3
  • 一、入门loader可以看作是翻译员,配置module.rules数组里的规则,告诉webpack遇到哪些文件使用...
    zx_lau阅读 2,984评论 0 0
  • publicPath指定了一个在浏览器中被引用的URL地址。 对于使用 和 加载器,当文件路径不同于他们的本地磁盘...
    飞呀飞哥阅读 1,693评论 0 0
  • Plugin Plugin 用于扩展 Webpack 的功能 , 各种各样的 Plugin 几乎可以让 Webpa...
    Upcccz阅读 362评论 0 1
  • 构建一个小项目——FlyBird,学习webpack和react。(本文成文于2017/2/25) 从webpac...
    布蕾布蕾阅读 16,801评论 31 98