huruji / blog

红日初升,其道大光:sun_with_face::house_with_garden:请star或watch,不要fork
https://juejin.im/user/5894886f2f301e00693a3e49/posts
158 stars 11 forks source link

编写前端配置文件的正确姿势 #75

Open huruji opened 5 years ago

huruji commented 5 years ago

现在前端有非常多的工具(webpack、rollup、eslint、prettier、husky、lerna、commitlint等等),这些工具都是为了优化提高前端的开发体验而诞生的。但是问题来了,这些工具有非常多的配置字段,基本靠记忆是搞不定的,所以很多情况都是前人写好,后人拷贝。但是本着不想成为成为拷贝工程师的原则,我辛辛苦苦看完了各个文档,写的时候却发现压根记不住那些配置字段,我的内心是崩溃的,说好的开发体验呢,有个锤子体验呀。。。

编写配置文件应该是能够智能提示字段,并且当我字段写错的时候是能够标红的,就像编写 ts 一样

很多前端工具都支持rc文件、.json.yaml.yml.js 文件中编写配置项目,因为其实基本上都是使用了 cosmiconfig 这个库(或者有类似功能的库)。

如果配置文件是 .ts 文件的话是能够通过编写声明文件来约束和智能提示的,但是如果说配置文件还需要通过 tsc 来编译过去,这样就有点傻了。

所幸的其实我们可以通过 jsdoc 注释来实现对 js 的类型约束。

首先配置下 vscode 的设置,打开 setting,设置 javascript.implicitProjectConfig.checkJs 为true,可以通过可视化栏目,搜索 checkjs,勾选对应的选项:

或者直接在 settings.json 文件中写入:

"javascript.implicitProjectConfig.checkJs": true

要约束对应的类型,使用 jsdoc 的 @type 即可,如:

约束变量name为数字,赋值字符串就标红提醒了。

那么现在的关键就是需要有对应工具配置项的 interface,这样就能约束和智能提示了。

webpack 为例,webpack 声明文件导出了一个名为 Configuration 的 interface,使用这个可以约束和智能提示 webpack 的配置:

同理,我也找到了 rollup 的是 RollupOptions

按照这个思路,如果说这些工具有相应的声明文件并且声明文件里定义了配置项的类型,并且这个工具可以支持以 .js 文件配置,那么就可以按照上面的思路来约束和提示。

但是很不幸的是,有些工具不支持以 .js 文件配置,比如 lerna ,同样还有很多工具并没有相应的声明文件,比如 lernahuskycommitlint

当然自己编写声明文件这个思路是可以的,但是 lerna 这类只支持 .json 文件配置怎么解决?

很明显这需要一个 json 数据校验器,很棒的是开源社区的巨巨们其实已经为我等菜鸡编写好了大部分的校验器。

巨巨们发起的项目叫 schemastore ,网站是 http://schemastore.org/json/ ,打开网站便是映入眼帘的满满的各类 json schema:

接下来的问题就是通过设置 vscode 来对特定 json 文件进行约束和智能提示。

直接在 vscode 的 settings.json 文件中编写,如约束lerna 的:

"json.schemas": [{
       "fileMatch": [
            "lerna.json"
        ],
        "url": "http://json.schemastore.org/lerna.json"
    }
]

棒棒棒,这才是可以接受的开发体验呀。

我挑选了常用的 babellernahuskyeslintprettiertravis 等,配置如下:

{
    "json.schemas": [{
        "fileMatch": [
            "/.babelrc"
        ],
        "url": "http://json.schemastore.org/babelrc"
    }, {
        "fileMatch": [
            "lerna.json"
        ],
        "url": "http://json.schemastore.org/lerna.json"
    }, {
        "fileMatch": [
            "/.huskyrc"
        ],
        "url": "http://json.schemastore.org/huskyrc"
    }, {
        "fileMatch": [
            "/.csslintrc"
        ],
        "url": "http://json.schemastore.org/csslintrc"
    }, {
        "fileMatch": [
            ".eslintrc"
        ],
        "url": "http://json.schemastore.org/eslintrc"
    }, {
        "fileMatch": [
            ".htmlhintrc"
        ],
        "url": "http://json.schemastore.org/htmlhint"
    }, {
        "fileMatch": [
            "jsconfig.json"
        ],
        "url": "http://json.schemastore.org/jsconfig"
    }, {
        "fileMatch": [
            ".prettierrc"
        ],
        "url": "http://json.schemastore.org/prettierrc"
    }, {
        "fileMatch": [
            ".travis.yml"
        ],
        "url": "http://json.schemastore.org/travis"
    }, {
        "fileMatch": [
            ".lintstagedrc"
        ],
        "url": "http://json.schemastore.org/lintstagedrc.schema"
    }]
}

当然以上情况不可能满足所有的情况,有很多小众但是非常优秀的轮子和工具,但是以上就是思路和意识,当碰到类似情况的时候,就可以自己动手编写声明文件和 jsonschema 来解决了。