Node.js's Config 地狱

Node.js的配置通常会妨碍开发者在构建应用时的生产力。但是,Deno采用了零配置、串联配置的方法,意味着您可以立即提高生产力。

当您启动任何类型的Node仓库时,您的根目录很快就会充斥着配置文件。例如,在最新版本的Next.js中,您会得到next.config.jseslintrc.jsontsconfig.jsonpackage.json

如果添加了样式,还会有postcss.config.jstailwind.config.js

需要中间件吗?添加middleware.ts。想要错误监控?添加sentry.server.config.jssentry.client.config.jssentry.edge.config.js。还有您的env文件、Git文件和Docker文件…

在您意识到这些之前,您的仓库可能会看起来像这样:

根目录中的30个配置文件

所有软件都需要配置。您需要一种方式来设置您正在使用的项目、工具、插件和软件。但是,我们是如何到达需要30个文件来运行一个项目的地步的?我们是如何陷入配置地狱的?

那么我们该如何摆脱这种情况呢?

Config但使用智能默认值

软件并非一刀切适用于所有用户——所有用户的需求略有不同。配置为用户提供了根据其用例获得最大价值的灵活性。

但是,将配置作为使用软件的第一步是一个糟糕的用户体验。

以将TypeScript添加到现有的Next.js项目为例。首先,我们需要安装TypeScript和类型:

1
npm install --save-dev typescript @types/react @types/node

然后我们需要创建自己的tsconfig.json:

1
touch tsconfig.json

然后呢?如果您刚开始使用TypeScript,您不知道想要哪种配置,所以您会像任何尊重自己的开发者一样做的事情:从Stack Overflow上抄一个配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

厌倦了手动为项目添加TypeScript支持?尝试一下Deno,其中原生支持TypeScript

而这仅仅是为了添加TypeScript

有效的软件通过具有智能默认值的偏见来预期其用户正在尝试完成的任务。这些“预设设置”旨在为大多数用户提供优化的体验,而无需手动配置。这些设置仍然可用,但只有在绝对必要时才会暴露出来。

在用户可以使用软件之前要求其配置软件可能会损害用户对您品牌的好感和信任。想象一下,您第一次使用Gmail时被迎接到这个页面:

Gmail设置中的无尽配置选项
您可能会突然对您的旧hotmail账户感到满意。
首选智能默认值;稍后再配置。

所有那些配置文件是什么?

让我们回到上面的列表。所有那些文件都设置了些什么?

  • Ignore files (dockerignoreeslintignoregitignoreprettierignorestyleignore):这些文件被工具用来从操作中排除某些文件和目录。它们有助于保持清洁的环境和高效的流程。

  • 运行命令文件(eslintrc.jsonlintstagedrc.jsonnvmrcnycrcstylelintrc.jsonprettierrc.jsonswcrc):运行命令(rc)配置文件指定运行某些命令时的设置或参数,例如eslintlint-staged等。

  • 包文件(package.jsonyarn.lock):这些文件提供了关于依赖项和自动化脚本的重要信息,允许对项目的环境进行一致的管理。

  • Next.js文件(middleware.tsnext-env.d.tsNext.config.jstsconfig.json):这些文件管理Next.js应用程序的设置和配置。

  • Docker(DockerfileDockerfile.deploydocker-compose.yml):这些文件管理配置以自动化部署和在容器中扩展应用程序。

  • 其他(editorconfighappo.jsbabel.config.jsplaywright.config.tssentry.client.config.jssentry.server.config.jssentry.properties):这些文件是用于自定义和管理开发环境以及第三方工具和库的配置文件。

Next.js、Docker、Sentry、Happo、ESLint、npm、Yarn、Playwright、Babel、VSCode、SWC、Stylelint、Prettier、NVM、NYC、lint-staged、Git

这些工具几乎不是神秘的。它们是部署Next.js应用程序所需的常见集合。要这样做,您需要约30个配置文件。
为什么?

JavaScript生态系统(大多数)太灵活

尽管如今Node.js主要用于构建网站和应用程序,但它最初的目的相对较为简单:使用事件驱动的架构实现异步I/O。随着Node的流行,JavaScript突然被用于一切:与浏览器/DOM、文件系统和Unix的交互、构建系统、bundle、转译等等。

JavaScript的广泛实用性体现在npm注册表上超过200万个模块中。为了有用,JavaScript模块必须支持越来越多的框架、元框架、构建工具等,以便能够适用于任何项目、任何工作流程、任何情况。而最直接的方法是保持模块“没有明确意见”,使用一个详尽的配置文件来暴露与任何框架、工具或堆栈一起工作所需的复杂性。

随着更多工具被添加到Node.js项目中,配置文件不仅变得臃肿,而且还会阻碍开发者的生产力。

简化复杂性

软件是达到目的的手段。有效的软件不会妨碍用户,而是让他们快速完成任务。

Node.js作为一种异步I/O、事件驱动的JavaScript运行时构建,没有预料到它将成为革命性改变网络开发的工具(每三个新的网页或应用程序中就有一个使用了Node)。但是,当开发者使用Node构建新项目时,他们经常会花费大量时间来整理他们喜欢的堆栈和工作流程——设置TypeScript、他们喜欢的测试框架、他们喜欢的构建流程等等。

但是,如果我们为网络构建并且能够立即提高生产力呢?

这就是我们构建Deno的方式,它是一个具有零配置和智能默认值的网络本机运行时,因此您可以立即启动下一个项目并提高生产力。它具有原生TypeScript支持,因此您不需要花时间设置它。Deno提供了一个强大的工具链,内置了格式化、linting、测试等功能,因此您无需设置自己的工具链。最后,Deno使用与网络兼容的API,因此如果您已经在为网络构建应用程序,那么您对Deno已经很熟悉了。

编程是关于管理复杂性,而简化复杂性不需要配置步骤。