你們確定都發現了,如今愈來愈多的前端工具支持用JavaScript來進行自定義配置了。(好比說Babel或ESLint)無論你們以前出於什麼緣由選擇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配置後,全部的問題都不是問題了,真香!框架
主要是由於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它不香麼?😕