From fdb60a6401df6523be59aa273a4c62c9e7cdbec4 Mon Sep 17 00:00:00 2001 From: YiJie Date: Sun, 1 Dec 2024 00:43:19 +0800 Subject: [PATCH] chore: auto detect mono active variable from file system --- .about/zh-Hans/HOW_TO_INSTALL.md | 73 +++++++++++++++++++++++ .jiek-locks/pnpm-lock.vite-plugin.yaml | 2 +- .pnpmfile.cjs | 20 +------ packages/rollup-plugins/.jiek-mono-active | 1 + packages/vite-plugins/.jiek-mono-active | 1 + scripts/utils/getActive.js | 42 +++++++++++-- scripts/utils/logger.js | 34 +++++++++++ 7 files changed, 149 insertions(+), 24 deletions(-) create mode 100644 .about/zh-Hans/HOW_TO_INSTALL.md create mode 100644 packages/rollup-plugins/.jiek-mono-active create mode 100644 packages/vite-plugins/.jiek-mono-active create mode 100644 scripts/utils/logger.js diff --git a/.about/zh-Hans/HOW_TO_INSTALL.md b/.about/zh-Hans/HOW_TO_INSTALL.md new file mode 100644 index 0000000..5643dda --- /dev/null +++ b/.about/zh-Hans/HOW_TO_INSTALL.md @@ -0,0 +1,73 @@ +# 如何安装的依赖 + +由于 Monorepo 可能存在的复杂产物目标,并不是每一个开发者都需要去关心每个子项目的依赖,所以为了方便开发者能最快开始开发,这里提供了一种特殊的方式来安装依赖。 + +> 如果你只是关心本项目的核心功能,你只需要 `pnpm i` 即可,下面的内容也基本与你无关。 + +## 机制 + +在这里先简单介绍一下依赖安装对应的机制,这样能有助于更好地理解应该如何去工作。 + +当安装依赖时,本项目会根据几个情况来确定你当前的开发状态: + +- 会逐层向上寻找 + - .jiek-mono-active 内容 + - `package.json` 中的 `.jiek.active` 字段 +- 当找到则会使用该字段的值作为当前的开发状态 +- 如果同时配置了 JIEK_MONO_ACTIVE 环境变量,则会覆盖上述的配置 + +## 操作 + +### 通常情况 + +在这里假设需要开发基干项目,这个时候的动作非常简单。 + +```shell +pnpm i +``` + +不需要做任何多余的动作便可以安装上基干项目的相关依赖,这是最简单的情况,这个时候我们会安装工作空间内的所有不带有特定模式的项目。 + +### 特定模式 + +假设现在需要开发某个特定模式,这个时候需要做一些额外的操作,但是也不复杂: + +```shell +# unix-like +JIEK_MONO_ACTIVE=模式名称 pnpm i +# windows +set JIEK_MONO_ACTIVE=模式名称 && pnpm i +``` + +同时我们也支持多种模式的同时开发,只需要用逗号分隔即可: + +```shell +# unix-like +JIEK_MONO_ACTIVE=模式名称1,模式名称2 pnpm i +# windows +set JIEK_MONO_ACTIVE=模式名称1,模式名称2 && pnpm i +``` + +除此之外,我们还会自动去寻找当你位于当前文件夹时,应该使用的模式,比如说你在 `packages/foo` 下执行 `pnpm i` 并且你的 `package.json` 中配置了 `.jiek.active` 字段,如: + +```json +{ + ".jiek": { + "active": "模式名称", + // or + "active": ["模式名称1", "模式名称2"] + }, + // or + ".jiek.active": "模式名称", + // or + ".jiek.active": ["模式名称1", "模式名称2"] +} +``` + +这个时候你不需要再手动设置 `JIEK_MONO_ACTIVE` 环境变量,我们会自动帮你设置(但是如果你设置了 `JIEK_MONO_ACTIVE` 环境变量,我们会优先使用环境变量的值)。 + +> 正如在上面所说的,还会向上寻找 `.jiek-mono-active` 文件,同级目录存在 `package.json` 时,这个文件的内容会被优先使用。 +> +> 同时也会向上寻找 `package.json` 中的 `.jiek.active` 字段,比如说: +> +> 在 `packages/foo/src/xx` 下执行 `pnpm i`,会向上寻找到 `packages/foo/package.json` 中的 `.jiek.active` 字段。 diff --git a/.jiek-locks/pnpm-lock.vite-plugin.yaml b/.jiek-locks/pnpm-lock.vite-plugin.yaml index 9a10845..8237b0c 100644 --- a/.jiek-locks/pnpm-lock.vite-plugin.yaml +++ b/.jiek-locks/pnpm-lock.vite-plugin.yaml @@ -4,7 +4,7 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -pnpmfileChecksum: m3lnok5ai36iov3pkdn2yondpa +pnpmfileChecksum: e3ysovqta5yarciiwhfldt2bfe importers: diff --git a/.pnpmfile.cjs b/.pnpmfile.cjs index f33e500..9f99dd8 100644 --- a/.pnpmfile.cjs +++ b/.pnpmfile.cjs @@ -4,25 +4,7 @@ const path = require('node:path') const process = require('node:process') const active = require('./scripts/utils/getActive') - -/* eslint-disable no-console */ -/** - * @typedef {{ [K in 'log' | 'info' | 'debug' | 'warn' | 'error']: (...args: any[]) => void }} Logger - */ -/** - * @type {Logger} - */ -const logger = [ - 'log', - 'info', - 'debug', - 'warn', - 'error' -].reduce((logger, method) => { - logger[method] = (...args) => console[method]('[jiek]', ...args) - return logger -}, {}) -/* eslint-enable no-console */ +const logger = require('./scripts/utils/logger') if (!active.includes('all')) { const lockfileDir = path.resolve(__dirname, '.jiek-locks') diff --git a/packages/rollup-plugins/.jiek-mono-active b/packages/rollup-plugins/.jiek-mono-active new file mode 100644 index 0000000..33e7efc --- /dev/null +++ b/packages/rollup-plugins/.jiek-mono-active @@ -0,0 +1 @@ +rollup-plugin diff --git a/packages/vite-plugins/.jiek-mono-active b/packages/vite-plugins/.jiek-mono-active new file mode 100644 index 0000000..5348f47 --- /dev/null +++ b/packages/vite-plugins/.jiek-mono-active @@ -0,0 +1 @@ +vite-plugin diff --git a/scripts/utils/getActive.js b/scripts/utils/getActive.js index 937aa64..948f9a1 100644 --- a/scripts/utils/getActive.js +++ b/scripts/utils/getActive.js @@ -1,14 +1,48 @@ // @ts-check +const fs = require('node:fs') +const path = require('node:path') const process = require('node:process') +const logger = require('./logger') + +function findDirActiveConfig(dir = process.cwd()) { + const activePath = path.resolve(dir, '.jiek-mono-active') + if (fs.existsSync(activePath)) { + logger.log('Using active config:', activePath) + return fs.readFileSync(activePath, 'utf-8') + .trim() + .split('\n') + .map(x => x.trim()) + } + const pkgPath = path.resolve(dir, 'package.json') + // eslint-disable-next-line no-labels + pkg: if (fs.existsSync(pkgPath)) { + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) + const active = pkg['.jiek']?.active ?? pkg['.jiek.active'] + + // eslint-disable-next-line no-labels + if (!active) break pkg + + logger.log('Using active config from package.json:', pkgPath) + return Array.isArray(active) ? active : [active] + } + if (dir === path.parse(dir).root) { + return undefined + } + return findDirActiveConfig(path.dirname(dir)) +} + const { JIEK_MONO_ACTIVE } = process.env /** @type {string[]} */ -const active = JIEK_MONO_ACTIVE - ?.split(',') - ?.map(x => x.trim()) - ?? [] +const active = ( + JIEK_MONO_ACTIVE + ? JIEK_MONO_ACTIVE + ?.split(',') + ?.map(x => x.trim()) + : findDirActiveConfig() +) ?? [] module.exports = active diff --git a/scripts/utils/logger.js b/scripts/utils/logger.js new file mode 100644 index 0000000..eb473d6 --- /dev/null +++ b/scripts/utils/logger.js @@ -0,0 +1,34 @@ +const process = require('node:process') + +const { + JIEK_LOG_LEVEL = 'info', + JIEK_LOG_SILENT = 'false' +} = process.env + +const silent = JIEK_LOG_SILENT === 'true' + +/** + * @typedef {{ [K in 'log' | 'info' | 'debug' | 'warn' | 'error']: (...args: any[]) => void }} Logger + */ +/** + * @type {Logger} + */ +const logger = [ + 'log', + 'info', + 'debug', + 'warn', + 'error' +].reduce((logger, method) => { + logger[method] = (...args) => { + if (silent) return + if ( + ['info', 'debug', 'warn', 'error'].includes(method) + && ['info', 'debug', 'warn', 'error'].indexOf(JIEK_LOG_LEVEL) < ['info', 'debug', 'warn', 'error'].indexOf(method) + ) return + console[method]('[jiek]', ...args) + } + return logger +}, {}) + +module.exports = logger