Skip to content

Commit

Permalink
🚧 hoist layer deps #28
Browse files Browse the repository at this point in the history
  • Loading branch information
trydofor committed Sep 20, 2024
1 parent 3549638 commit d30a95d
Show file tree
Hide file tree
Showing 7 changed files with 546 additions and 342 deletions.
6 changes: 6 additions & 0 deletions .changeset/wild-flowers-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fessional/razor-common": patch
"@fessional/razor-mobile": patch
---

hoist layer hook to reduce copy deps
137 changes: 137 additions & 0 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
const packageKey = 'hoistLayer';
const cachedFile = 'node_modules/.hoist-layer.json';

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

// find the monorepo root by searching for .pnpmfile.cjs
function findMonorepoRoot(pwd) {
if (fs.existsSync(path.join(pwd, '.pnpmfile.cjs'))) {
return pwd;
}
const dir = path.dirname(pwd);
if (dir === pwd) {
throw new Error('Monorepo root not found, should have .pnpmfile.cjs');
}
return findMonorepoRoot(dir);
}

const monorepoRoot = findMonorepoRoot(process.cwd());
const packageJson = path.resolve(monorepoRoot, 'package.json');
if (packageJson == null) {
throw new Error('package.json is not found in ' + monorepoRoot);
}

const flatLayerMap = new Map();
const hoistLayer = JSON.parse(fs.readFileSync(packageJson, 'utf-8'))[packageKey]; // string[]
if (hoistLayer == null) {
throw new Error('"hoistLayer":[""] is not defined in package.json');
}
// console.log('DEBUG: hoistLayer \n' + JSON.stringify(hoistLayer, null, 2));

const cachedPath = path.resolve(monorepoRoot, cachedFile);
const cacheExist = fs.existsSync(cachedPath);
const resolutionOnly = process.argv.includes('--resolution-only');
if (resolutionOnly && cacheExist) {
fs.rmSync(cachedPath);
}
// console.log(`DEBUG: cachedPath=${cachedPath}`);
// console.log(`DEBUG: cacheExist=${cacheExist}`);
// console.log(`DEBUG: resolutionOnly=${resolutionOnly}`);
if (!resolutionOnly && cacheExist) {
loadFlatLayer();
// console.log('DEBUG: loadFlatLayer \n' + JSON.stringify(Array.from(flatLayerMap.values()), null, 2));
}

function loadFlatLayer() {
const arr = JSON.parse(fs.readFileSync(cachedPath, 'utf-8'));
if (arr == null) return;
// set
for (const pk of arr) {
flatLayerMap.set(pk.name, pk);
}

// flat
for (const pk of arr) {
for (const k of flatLayerMap.keys()) {
if (pk.dependencies[k] != null) {
const it = flatLayerMap.get(k);
pk.dependencies = {
...pk.dependencies,
...it.dependencies,
};
}
if (pk.devDependencies[k] != null) {
const it = flatLayerMap.get(k);
pk.devDependencies = {
...pk.devDependencies,
...it.devDependencies,
};
}
}
}
}

function readPackage(pkg, context) {
if (resolutionOnly) {
if (hoistLayer.includes(pkg.name)) {
context.log('find the hoist layers ' + pkg.name);
flatLayerMap.set(pkg.name, {
name: pkg.name,
dependencies: pkg.dependencies,
devDependencies: pkg.devDependencies,
});
}
if (flatLayerMap.size === hoistLayer.length) {
context.log('write cached hoist-layer to ' + cachedPath);
fs.mkdirSync(path.dirname(cachedPath), { recursive: true });
fs.writeFileSync(cachedPath, JSON.stringify(Array.from(flatLayerMap.values()), null, 2), 'utf-8');
process.exit(0);
}
return pkg;
}

if (flatLayerMap.size === 0) {
context.log('resolution the hoist layers');
execSync('pnpm i --resolution-only', { stdio: 'ignore' });
loadFlatLayer();
if (flatLayerMap.size === 0) {
throw new Error('failed to load layer package by pnpm i --resolution-only');
}
}

// layer dependency
for (const pk of hoistLayer) {
if (pkg.dependencies[pk] != null || pkg.devDependencies[pk] != null) {
context.log('hoist layer' + pk + ' to ' + pkg.name);
const it = flatLayerMap.get(pk);
pkg.dependencies = {
...pkg.dependencies,
...it.dependencies,
};
pkg.devDependencies = {
...pkg.devDependencies,
...it.devDependencies,
};
}
}

return pkg;
}

function afterAllResolved(lockfile) {
if (resolutionOnly && flatLayerMap.size !== hoistLayer.length) {
throw new Error('hoistLayer size is not equal to flatLayerMap size');
}
return lockfile;
}

module.exports = {
packageKey,
cachedFile,
hooks: {
readPackage,
afterAllResolved,
},
};
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"Nuxt",
"nuxtjs",
"revi",
"rimraf",
"serv",
"servs",
"typecheck",
Expand Down
24 changes: 2 additions & 22 deletions layers/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,17 @@
"description": "mobile layer with ionic and capacitor",
"main": "./nuxt.config.ts",
"scripts": {
"build": "nuxi build",
"build": "nuxi generate",
"dev": "nuxi dev",
"generate": "nuxi generate",
"preview": "nuxi preview",
"postinstall": "nuxi prepare",
"test": "vitest"
},
"devDependencies": {
"@nuxtjs/ionic": "catalog:mobile",
"@fessional/razor-common": "workspace:*",
"nuxt": "catalog:common",
"@nuxt/eslint": "catalog:common",
"eslint": "catalog:common",
"vite-plugin-eslint2": "catalog:common",
"typescript": "catalog:common",
"vue-tsc": "catalog:common",
"@nuxt/test-utils": "catalog:common",
"@vue/test-utils": "catalog:common",
"happy-dom": "catalog:common",
"vitest": "catalog:common",
"@iconify-json/mdi": "catalog:common",
"@unocss/core": "catalog:common",
"@unocss/nuxt": "catalog:common",
"@unocss/preset-icons": "catalog:common",
"@unocss/preset-wind": "catalog:common",
"unocss": "catalog:common"
"@nuxtjs/ionic": "catalog:mobile"
},
"dependencies": {
"@vueuse/core": "catalog:common",
"@vueuse/nuxt": "catalog:common",
"vue": "catalog:common",
"@ionic/vue": "catalog:mobile",
"@ionic/vue-router": "catalog:mobile",
"ionicons": "catalog:mobile"
Expand Down
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@
"scripts": {
"deps": "taze -r",
"feat": "changeset",
"bump": "changeset version"
"bump": "changeset version",
"pure": "rimraf --glob '**/node_modules/'"
},
"devDependencies": {
"taze": "catalog:common",
"@changesets/cli": "catalog:common"
}
"taze": "catalog:devops",
"rimraf": "catalog:devops",
"@changesets/cli": "catalog:devops"
},
"hoistLayer": [
"@fessional/razor-common",
"@fessional/razor-mobile"
]
}
Loading

0 comments on commit d30a95d

Please sign in to comment.