babel 7.4 配置文件(翻译)

附文:一文读懂 babel7 的配置文件加载逻辑 blog.csdn.net/weixin_3419…javascript

配置文件

配置文件类型

babel有两种并行配置文件格式,能够一块儿使用,也能够独立使用。java

  • 项目范围配置
  • 文件相对配置
    • .babelrc(和.babelrc.js)文件
    • 带有“babel”键的package.json文件

项目范围配置

在babel 7.x中,babel有一个“根”目录的概念,默认为当前的工做目录。. 对于项目范围的配置,babel将自动在这个根目录中搜索“babel.config.js”。或者,用户可使用显式的“config file”值来覆盖默认的配置文件搜索行为。node

因为项目范围内的配置文件与配置文件的物理位置分离,所以它们很是适合必须普遍应用的配置,甚至容许插件和预设轻松应用于节点模块或符号连接包中的文件,传统上,这些配置对于在Babel6.x中配置。 这个项目范围配置的主要缺点是,由于它依赖于工做目录,因此若是工做目录不是monorepo根目录,那么在monorepo中使用它可能会更痛苦。有关如何在该上下文中使用配置文件的示例,请参阅monorepo文档。json

经过将“configfile”设置为false,还能够禁用项目范围的配置。api

文件相对配置

babel经过从正在编译的“文件名”开始搜索目录结构来加载.babelrc(和.babelrc.js/package.json_babel)文件(受如下注意事项限制)。 这可能很强大, 由于它容许您为包的子部分建立独立的配置。文件相关配置也在项目范围的配置值的顶部进行合并,这使得它们对于特定的覆盖可能有用,尽管也能够经过“覆盖”来实现。 一旦找到包含package.json的目录,搜索将中止,所以相对配置仅适用于单个包。 在编译的“文件名”必须在“babelrcroots”包中,不然将彻底跳过搜索。缓存

这些注意事项意味着: .babelrc文件仅适用于本身包中的文件 除非您选择“babelrc root s”,不然将忽略不属于babel“root”的包中的.babelrc文件。 有关如何配置具备多个包的monorepo的更多讨论,请参阅monorepo文档。 经过将“babelrc”设置为false,也能够禁用文件相对配置。安全

6.x与7.x.babelrc加载

来自Babel6.x的用户可能会遇到这两个边缘案例,这在Babel7.x中是新的。这两个限制是为了解决Babel6.x中的常见问题而增长的:babel

  • .babelrc文件应用于节点模块依赖项,一般是意外的。
  • .babelrc文件没法应用于符号连接节点_模块,由于人们但愿它们的行为相似于正常的依赖项。 节点模块依赖项中的.babelrc文件将被检测到,即便它们内部的插件和预设一般没有安装,甚至可能在编译该文件的babel版本中无效。 这些状况将主要致使Monorepo结构的用户出现问题,由于若是 .babelrc packages/ mod1/ package.json src/index.js mod2/ package.json src/index.js

配置如今将被彻底忽略,由于它跨越包边界。 另外一种选择是在每一个使用“extends”做为 { "extends": "../../.babelrc" }app

不幸的是,这种方法可能有点重复,而且根据Babel的使用方式,可能须要设置“babelrcRoots”。 鉴于此,将.babelrc重命名为项目范围的“babel.config.js”可能更为可取。正如上面的项目范围部分所提到的,这可能须要显式设置“config file”,由于若是工做目录不正确,babel将找不到配置文件。ide

Monorepo

Monorepo结构化存储库一般包含许多包,这意味着它们常常遇到文件相关配置和配置文件加载中提到的警告。本节旨在帮助用户了解如何处理Monorepo配置。 对于monorepo设置,要理解的核心是babel将您的工做目录视为其逻辑“根”,若是您但愿在特定的子包中运行babel工具,而不将babel做为一个总体应用于repo,则会致使问题。 另外,决定是使用.babelrc文件仍是只使用中心babel.config.js也很重要。子文件夹特定配置不须要.babelrc文件,就像在babel 6中同样,所以在babel 7中一般不须要这些文件,而须要babel.config.js。

根babel.config.js文件

任何monorepo结构的第一步都应该是在repository根目录中建立babel.config.js文件。这就创建了babel对存储库基本目录的核心概念。即便您想使用.babelrc文件来配置每一个单独的包,也必须将其做为repo级别选项的位置。 您一般能够将全部repo配置放在根babel.config.js中。使用“overrides”,您能够轻松地指定仅适用于存储库的某些子文件夹的配置,这一般比在repo中建立许多.babelrc文件更容易执行。 您可能会遇到的第一个问题是,默认状况下,babel指望从目录集中加载babel.config.js文件做为其“根”,这意味着若是建立babel.config.js,但在单个包中运行babel,例如。

cd packages/some-package; babel src -d dist

在这种状况下,babel使用的“根”不是monorepo根,它将没法找到babel.config.js文件。 若是全部的构建脚本都是相对于存储库根运行的,那么事情应该已经开始了,可是若是您是在子包中运行babel编译过程,那么您须要告诉babel在哪里查找配置。有几种方法能够作到这一点,但推荐的方法是“向上”的“rootmode”选项,它将使babel从工做目录向上搜索babel.config.js文件,并将其位置用做“根”值。 测试配置是否被检测到的一个有用方法是在其中放置一个console.log()调用。由于它是一个JS文件,因此日志将在babel第一次加载它时执行。 您如何设置此值因项目而异,但如下是几个示例: CLI babel --root-mode upward src -d lib

@babel/register require("@babel/register")({ rootMode: "upward" });

Webpack module: { rules: [{ loader: "babel-loader", options: { rootMode: "upward", } }] }

Jest

jest一般安装在monorepo的根目录下,可能不须要配置,可是若是每一个包都安装了它,那么不幸的是配置起来可能更复杂。 主要部分是建立一个自定义的jest transformer文件,该文件包装babel jest的默认行为,以便设置选项,例如。 module.exports = require("babel-jest").createTransformer({ rootMode: "upward", });

保存到某个地方后,您将经过转换选项在jest选项中使用该文件代替babel jest: "transform": { "^.+\.jsx?$": "./path/to/wrapper.js" },

所以,全部JS文件都将使用您的babel jest版本处理,并启用选项。

其余: 有不少工具,但其核心是,若是工做目录还不是monorepo根目录,那么它们须要启用rootmode选项。

子包.babelrc文件

与babel.config.js文件必须位于“根”中的方式相似,默认状况下.babelrc文件必须位于根包中。这意味着,与工做目录影响babel.config.js加载的方式相同,它也影响.babelrc加载。 假设您已经像上面讨论的那样正确加载了babel.config.js文件,babel将只处理根包中的.babelrc文件(而不是子包),例如package.json babel.config.js packages/ mod/ package.json .babelrc index.js

编译packages/mod/index.js文件将不会加载packages/mod/.babelrc,由于该.babelrc位于子包中,而不是根包。 要启用该.babelrc的处理,您须要使用babel.config.js文件中的“babelrcroots”选项。babelrcRoots: [ ".", "packages/*", ],

所以,babel将考虑容许加载.babelrc文件的全部包/*包,以及原始repo根。

配置格式

单个配置文件自己的格式分为JS文件和JSON5文件。

JSON5

任何不是.js文件的文件都将被解析为json5,而且应该包含一个与babel接受的选项格式相匹配的对象。

javascript

任何.js文件都将require()ed,而且应该导出配置对象,或者在调用时返回配置对象的函数。主要的好处是,用户可使用JS逻辑构建配置结构,这可能使配置逻辑更容易共享。.js文件能够用做项目范围的配置,也能够经过.babelrc.js文件进行文件相关配置。 返回配置的函数有一些特殊的功能,由于它们能够访问babel自己公开的API。有关详细信息,请参阅配置函数API。

配置函数API

JS配置文件可能会导出一个将传递配置函数API的函数: module.exports = function(api) { return {}; }

api对象公开了babel自己从其索引模块公开的全部内容,以及配置文件特定的api:

  • api.version Type: string 正在加载配置文件的babel版本的版本字符串。

  • api.cache JS配置很是好,由于它们能够即时计算配置,但缺点是它会使缓存变得更困难。Babel但愿避免每次编译文件时都从新执行config函数,由于这样它还须要从新执行该配置中引用的任何插件和预设函数。 为了不这种状况,babel但愿配置函数的用户告诉它如何管理配置文件中的缓存。

    • api.cache.forever()-permacache计算的配置,再也不调用函数。
    • api.cache.never()-不要缓存此配置,每次都从新执行函数。
    • api.cache.using(()=>process.env.node_env)-基于node_env值的缓存。每当using回调返回预期值之外的值时,将再次调用整体配置函数,并向缓存中添加一个新条目。
    • api.cache.invalidate(()=>process.env.node_env)-基于node_env值的缓存。每当using回调返回预期值之外的值时,将再次调用整体配置函数,而且缓存中的全部条目都将替换为结果。 因为实际回调结果用于检查缓存项是否有效,所以建议: 回调应该很小而且没有反作用。 回调应返回可能范围最小的值。例如,上面的.using(()=>process.env.node_env)用法并不理想,由于它将根据检测到的node_env值建立未知数量的缓存项。这样作比较安全。使用(()=>process.env.node_env==“development”),由于这样缓存项只能为true或false。 回调应该很小而且没有反作用。
  • api.env(…) 因为node_env是一种很是常见的切换行为的方法,babel还包含一个专门用于此目的的API函数。此API用做快速检查babel加载时使用的“envname”的方法,若是没有设置其余覆盖环境,则会考虑节点env。 它有几种不一样的形式: 若是envname==“production”,则api.env(“production”)返回true。 若是[“development”,“test”]包含(envname),则env([“development”,“test”])返回true。 api.env()返回当前envname字符串。 若是env以“test-”开头,则api.env(envname=>envname.starts with(“test-”))返回true。 这个函数在内部使用下面提到的api.cache来确保babel知道这个构建依赖于一个特定的envname。

  • api.caller(cb) 此API用做访问已传递给babel的调用方数据的方法。因为babel的许多实例可能以不一样的调用方值在同一进程中运行,所以该API被设计为自动配置api.cache,与api.env()的方式相同。 调用者值可用做回调函数的第一个参数。最好和相似的东西一块儿使用 function isBabelRegister(caller) { return !!(caller && caller.name === "@babel/register"); }

module.exports = function(api) { const isRegister = api.caller(isBabelRegister);

return { // ... }; }

根据特定环境切换配置行为。

  • api.assertVersion(range) 虽然api.version在通常状况下颇有用,但有时只声明您的版本是很好的。此API公开了一种简单的方法来实现这一点: module.exports = function(api) { api.assertVersion("^7.2");

    return { // ... }; };

相关文章
相关标签/搜索