別再用JSON配置文件了

你們確定都發現了,如今愈來愈多的前端工具支持用JavaScript來進行自定義配置了。(好比說BabelESLint)無論你們以前出於什麼緣由選擇JSON來寫配置信息,從如今開始不要這麼幹了,改用JavaScript吧。前端

爲何呢?npm

一開始 我犯了個錯

前段時間,我爲了模塊化項目,把一些通用的代碼抽象出來造成了單獨的庫,每一個新的項目中都要把以前開發中配置的工具再配置一遍,Lint,Prettier等等。編程

一開始我想偷懶,每一個新的項目都要配置一遍,那這些配置性的東西我想寫的越少越好,因此我用了package.json中的JSON配置。而後我把全部的配置文件放在一個單獨的包中,基於咱們使用的工具(好比Babel)提供的擴展機制,咱們能夠共享配置。就像這樣:json

{
  "name": "nice-project",
  "version": "1.0.0",
  "babel": {
    "extends": "awesome-config",
    "plugins": ["lodash"]
  }
}
複製代碼

簡單吧?可是!並非每一個工具都實現這種extends機制。babel

很巧的是,我還遇到了。發現缺乏工具支持後,我在Github上尋找相關解決方案,確定有大佬在我以前也遇到了這樣的問題。果真還有不少小夥伴遇到了相似的問題。不過很快我也發現了,有的開發者沒有考慮提供對全部可能的工具都提供擴展機制,由於已經存在一個自然的更好的選擇了:使用JavaScript配置文件。markdown

好吧,大佬就是大佬,我能怎麼辦呀,那我也只能用JavaScript來配置這些工具咯。當我用JavaScript重寫了以前的JSON配置後,全部的問題都不是問題了,真香!框架

爲何要使用JavaScript配置

主要是由於JSON是一種數據格式,而JavaScript是編程語言。咱們經過編程語言能夠實現各類各樣的計算與組合,不須要藉助其它的工具就能夠實現強大的配置功能。編程語言

並且,咱們能夠在JavaScript配置中寫註釋,甚至對它們作測試(雖然這看起來沒多大意義)。ide

咱們從幾個方面展開來講說使用Javascript配置的好處:模塊化

輕鬆覆蓋

咱們若是require了一個JavaScript配置文件,咱們能夠輕鬆地修改返回的對象並從新導出它。

就像這樣,咱們的包裏須要另一個Babel插件時,像修改普通的對象同樣修改它就行了。

const base = require("../babel.config.js");

module.exports = {
   ...base,
   plugins: [...base.plugins, "lodash"],
};
複製代碼

動態配置

我剛剛也說了,JSON是一種數據格式,缺少動態性,咱們喜歡用它來傳數據,可是用來作配置其實不太行。若是使用JSON配置,哪怕有一丁點兒不一樣咱們都要新建一個新的配置文件,若是換成JavaScript配置,咱們能夠經過一些編程技巧動態地返回須要的內容。

好比說咱們只想在生產環境中使用某個插件,小菜一碟。

const base = require("../babel.config.js");

module.exports = {
  ...base,
  plugins: process.env.NODE_ENV === "production" 
    ? [...base.plugins, "lodash"]
    : base.plugins,
};
複製代碼

共享配置

進入前端世界後,一個比較爽的點是什麼代碼均可以經過npm發佈 ,咱們只須要建立一個恰當的package.json,而後npm publish就行了。

{
  "name": "my-babel-config",
  "version": "1.0.0",
  "description": "My babel config. ",
  "main": "babel.config.js",
  "files": ["babel.config.js"]
}
複製代碼

發佈後,咱們只須要在須要用到的項目中require便可:

const base = require("my-babel-config");

  module.exports = {
     ...base,
     plugins: [...base.plugins, "lodash"],
  };
複製代碼

註釋

JSON不支持註釋。有人說咱們可使用某些奇特的技巧實現這一需求,可是它們並它們不是JSON規範的一部分。JavaScript做爲編程語言自然支持註釋。咱們能夠將它們放在任意位置,ide還會給咱們作好高亮。

module.exports = {
  "plugins": ["lodash"],
};
複製代碼

可測試

剛剛也提到了,咱們能夠測試Javascript配置文件,它們跟其它代碼沒有什麼區別。 有沒有這個必要你們能夠根據本身的場景判斷,若是有須要,咱們可使用任何咱們熟悉的測試框架來測試,好比Jest。

describe("config", () => {
  beforeEach(() => {
    oldEnv = process.env.NODE_ENV;
  });
  afterEach(() => {
    jest.resetModules();
    process.env.NODE_ENV = oldEnv;
  });

  it("uses lodash plugin in production", () => {
    process.env.NODE_ENV = "production";
    const config = require("./babel.config.js");
    expect(config.plugins.includes("lodash")).toBe(true);
  });

  it("does not use lodash plugin in other envs", () => {
    process.env.NODE_ENV = "production";
    const config = require("./babel.config.js");
    expect(config.plugins.includes("lodash")).toBe(false);
  });
});
複製代碼

總結

使用編程語言來配置工程能夠輕鬆地實現不少JSON配置須要工具支持才能實現的功能,也讓共享配置的門檻進一步下降,安卓很早就採用了Gradle來配置項目,就是看中了Gradle腳本使用groovy代碼編寫使得配置更加靈活方便,省了折騰那些花裏胡哨的工具的時間多寫兩個BUG它不香麼?😕

相關文章
相關標籤/搜索