From 3755228ee00117ab8a9a04179a445702e5788f61 Mon Sep 17 00:00:00 2001 From: Ming Date: Wed, 26 Jun 2024 21:44:09 +0800 Subject: [PATCH] feat(deploy): export handleDependencies (#5854) --- .changeset/cold-squids-rhyme.md | 6 ++ packages/server/core/package.json | 2 +- packages/solutions/app-tools/package.json | 10 ++- .../src/plugins/deploy/dependencies/index.ts | 78 ++++++++++++------- .../src/plugins/deploy/dependencies/utils.ts | 31 ++++---- .../app-tools/src/plugins/deploy/exports.ts | 1 + .../src/plugins/deploy/platforms/netlify.ts | 8 +- .../src/plugins/deploy/platforms/node.ts | 12 +-- .../src/plugins/deploy/platforms/vercel.ts | 8 +- pnpm-lock.yaml | 26 +++---- 10 files changed, 108 insertions(+), 74 deletions(-) create mode 100644 .changeset/cold-squids-rhyme.md create mode 100644 packages/solutions/app-tools/src/plugins/deploy/exports.ts diff --git a/.changeset/cold-squids-rhyme.md b/.changeset/cold-squids-rhyme.md new file mode 100644 index 000000000000..3b3d8f13ec54 --- /dev/null +++ b/.changeset/cold-squids-rhyme.md @@ -0,0 +1,6 @@ +--- +'@modern-js/app-tools': patch +--- + +feat: export handleDependencies +feat: 暴露 handleDependencies 方法 diff --git a/packages/server/core/package.json b/packages/server/core/package.json index e108a1714561..aa69020b6f18 100644 --- a/packages/server/core/package.json +++ b/packages/server/core/package.json @@ -87,7 +87,7 @@ "exports": { ".": { "types": "./dist/types/index.d.ts", - "import": "./dist/esm-node/index.d.ts", + "import": "./dist/esm-node/index.js", "default": "./dist/cjs/index.js" }, "./node": { diff --git a/packages/solutions/app-tools/package.json b/packages/solutions/app-tools/package.json index d96cb9a49f56..17eac3331b2d 100644 --- a/packages/solutions/app-tools/package.json +++ b/packages/solutions/app-tools/package.json @@ -15,7 +15,7 @@ "modern", "modern.js" ], - "version": "2.54.3", + "version": "2.54.3-alpha.6", "jsnext:source": "./src/index.ts", "types": "./src/index.ts", "main": "./dist/cjs/index.js", @@ -43,6 +43,11 @@ "types": "./dist/types/exports/server.d.ts", "jsnext:source": "./src/exports/server.ts", "default": "./dist/cjs/exports/server.js" + }, + "./deploy": { + "types": "./dist/types/plugins/deploy/exports.d.ts", + "jsnext:source": "./src/plugins/deploy/exports.ts", + "default": "./dist/cjs/plugins/deploy/exports.js" } }, "engines": { @@ -58,6 +63,9 @@ ], "server": [ "./dist/types/exports/server.d.ts" + ], + "deploy": [ + "./dist/types/plugins/deploy/exports.d.ts" ] } }, diff --git a/packages/solutions/app-tools/src/plugins/deploy/dependencies/index.ts b/packages/solutions/app-tools/src/plugins/deploy/dependencies/index.ts index 102a74879f3d..7cfd94c6f4c6 100644 --- a/packages/solutions/app-tools/src/plugins/deploy/dependencies/index.ts +++ b/packages/solutions/app-tools/src/plugins/deploy/dependencies/index.ts @@ -1,4 +1,4 @@ -import path, { isAbsolute } from 'node:path'; +import path from 'node:path'; import { fs as fse, pkgUp, semver } from '@modern-js/utils'; import type { PackageJson } from 'pkg-types'; import { readPackageJSON } from 'pkg-types'; @@ -10,31 +10,32 @@ import { TracedPackage, TracedFile, findEntryFiles, - traceFiles, + traceFiles as defaultTraceFiles, findPackageParents, resolveTracedPath, + readDirRecursive, } from './utils'; -export const handleDependencies = async ( - appDir: string, - serverRootDir: string, - include: string[], - entryFilter?: (filePath: string) => boolean, -) => { +export const handleDependencies = async ({ + appDir, + serverRootDir, + includeEntries, + traceFiles = defaultTraceFiles, + entryFilter, + modifyPackageJson, + copyWholePackage, +}: { + appDir: string; + serverRootDir: string; + includeEntries: string[]; + traceFiles?: typeof defaultTraceFiles; + entryFilter?: (filePath: string) => boolean; + modifyPackageJson?: (pkgJson: PackageJson) => PackageJson; + copyWholePackage?: (pkgName: string) => boolean; +}) => { const base = '/'; const entryFiles = await findEntryFiles(serverRootDir, entryFilter); - const includeEntries = include.map(item => { - if (isAbsolute(item)) { - return item; - } - try { - // FIXME: should appoint paths - return require.resolve(item); - } catch (error) {} - return item; - }); - const fileTrace = await traceFiles( entryFiles.concat(includeEntries), serverRootDir, @@ -161,11 +162,22 @@ export const handleDependencies = async ( tracedPackage.versions[pkgJSON.version!] = tracedPackageVersion; } - tracedFile.path.startsWith(tracedFile.pkgPath) && - tracedPackageVersion.path === tracedFile.pkgPath && - tracedPackageVersion.files.push(tracedFile.path); tracedFile.pkgName = pkgName; tracedFile.pkgVersion = pkgJSON.version; + + const shouldCopyWholePackage = copyWholePackage?.(pkgName); + if ( + tracedFile.path.startsWith(tracedFile.pkgPath) && + // Merged package files are based on the version, not on paths, to handle some boundary cases + tracedPackageVersion.pkgJSON.version === tracedFile.pkgVersion + ) { + if (shouldCopyWholePackage) { + const allFiles = await readDirRecursive(tracedFile.pkgPath); + tracedPackageVersion.files.push(...allFiles); + } else { + tracedPackageVersion.files.push(tracedFile.path); + } + } } const multiVersionPkgs: Record = {}; @@ -191,7 +203,11 @@ export const handleDependencies = async ( singleVersionPackages.map(pkgName => { const pkg = tracedPackages[pkgName]; const version = Object.keys(pkg.versions)[0]; - return writePackage(pkg, version, serverRootDir); + return writePackage({ + pkg, + version, + projectDir: serverRootDir, + }); }), ); @@ -228,7 +244,12 @@ export const handleDependencies = async ( const pkg = tracedPackages[pkgName]; const pkgDestPath = `.modernjs/${pkgName}@${version}/node_modules/${pkgName}`; - await writePackage(pkg, version, serverRootDir, pkgDestPath); + await writePackage({ + pkg, + version, + projectDir: serverRootDir, + _pkgPath: pkgDestPath, + }); await linkPackage(pkgDestPath, `${pkgName}`, serverRootDir); for (const parentPkg of parentPkgs) { @@ -249,7 +270,8 @@ export const handleDependencies = async ( } const outputPkgPath = path.join(serverRootDir, 'package.json'); - await fse.writeJSON(outputPkgPath, { + + const newPkgJson = { name: `${projectPkgJson.name || 'modernjs-project'}-prod`, version: projectPkgJson.version || '0.0.0', private: true, @@ -261,5 +283,9 @@ export const handleDependencies = async ( ]), ].sort(([a], [b]) => a.localeCompare(b)), ), - }); + }; + + const finalPkgJson = modifyPackageJson?.(newPkgJson) || newPkgJson; + + await fse.writeJSON(outputPkgPath, finalPkgJson); }; diff --git a/packages/solutions/app-tools/src/plugins/deploy/dependencies/utils.ts b/packages/solutions/app-tools/src/plugins/deploy/dependencies/utils.ts index e1ca90d10c2c..3db910ed23aa 100644 --- a/packages/solutions/app-tools/src/plugins/deploy/dependencies/utils.ts +++ b/packages/solutions/app-tools/src/plugins/deploy/dependencies/utils.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import { fs as fse } from '@modern-js/utils'; import type { PackageJson } from 'pkg-types'; import { parseNodeModulePath } from 'mlly'; -import { nodeFileTrace, resolve } from '@vercel/nft'; +import { nodeFileTrace } from '@vercel/nft'; export type TracedPackage = { name: string; @@ -35,12 +35,15 @@ function applyPublicCondition(pkg: PackageJson) { } } -export const writePackage = async ( - pkg: TracedPackage, - version: string, - projectDir: string, - _pkgPath?: string, -) => { +interface WritePackageOptions { + pkg: TracedPackage; + version: string; + projectDir: string; + _pkgPath?: string; +} + +export const writePackage = async (options: WritePackageOptions) => { + const { pkg, version, projectDir, _pkgPath } = options; const pkgPath = _pkgPath || pkg.name; for (const src of pkg.versions[version].files) { if (src.includes('node_modules')) { @@ -156,7 +159,8 @@ export const findPackageParents = ( const parentPkgs = [ ...new Set( versionFiles.flatMap(file => - file.parents + // Because it supports copyWholePackage configuration, not all files exist. + file?.parents .map(parentPath => { const parentFile = tracedFiles[parentPath]; @@ -170,7 +174,7 @@ export const findPackageParents = ( ), ), ]; - return parentPkgs as string[]; + return parentPkgs.filter(parentPkg => parentPkg) as string[]; }; export const traceFiles = async ( @@ -181,15 +185,6 @@ export const traceFiles = async ( return await nodeFileTrace(entryFiles, { base, processCwd: serverRootDir, - resolve: async (id, parent, job, isCjs) => { - if (id.startsWith('@modern-js/prod-server')) { - return require.resolve(id, { - paths: [require.resolve('@modern-js/app-tools')], - }); - } else { - return resolve(id, parent, job, isCjs); - } - }, }); }; diff --git a/packages/solutions/app-tools/src/plugins/deploy/exports.ts b/packages/solutions/app-tools/src/plugins/deploy/exports.ts new file mode 100644 index 000000000000..3f24784cd6ff --- /dev/null +++ b/packages/solutions/app-tools/src/plugins/deploy/exports.ts @@ -0,0 +1 @@ +export { handleDependencies } from './dependencies'; diff --git a/packages/solutions/app-tools/src/plugins/deploy/platforms/netlify.ts b/packages/solutions/app-tools/src/plugins/deploy/platforms/netlify.ts index f79701c615c4..5b9485a3a862 100644 --- a/packages/solutions/app-tools/src/plugins/deploy/platforms/netlify.ts +++ b/packages/solutions/app-tools/src/plugins/deploy/platforms/netlify.ts @@ -138,9 +138,11 @@ export const createNetlifyPreset: CreatePreset = ( if (!needModernServer) { return; } - await handleDependencies(appDirectory, funcsDirectory, [ - '@modern-js/prod-server', - ]); + await handleDependencies({ + appDir: appDirectory, + serverRootDir: funcsDirectory, + includeEntries: [require.resolve('@modern-js/prod-server')], + }); }, }; }; diff --git a/packages/solutions/app-tools/src/plugins/deploy/platforms/node.ts b/packages/solutions/app-tools/src/plugins/deploy/platforms/node.ts index 36353c9f2d86..874728d1dcda 100644 --- a/packages/solutions/app-tools/src/plugins/deploy/platforms/node.ts +++ b/packages/solutions/app-tools/src/plugins/deploy/platforms/node.ts @@ -81,12 +81,12 @@ export const createNodePreset: CreatePreset = (appContext, config) => { return !filePath.startsWith(staticDirectory); }; // Because @modern-js/prod-server is an implicit dependency of the entry, so we add it to the include here. - await handleDependencies( - appDirectory, - outputDirectory, - ['@modern-js/prod-server'], - filter, - ); + await handleDependencies({ + appDir: appDirectory, + serverRootDir: outputDirectory, + includeEntries: [require.resolve('@modern-js/prod-server')], + entryFilter: filter, + }); }, }; }; diff --git a/packages/solutions/app-tools/src/plugins/deploy/platforms/vercel.ts b/packages/solutions/app-tools/src/plugins/deploy/platforms/vercel.ts index 99947635091b..a9943bc7f8e2 100644 --- a/packages/solutions/app-tools/src/plugins/deploy/platforms/vercel.ts +++ b/packages/solutions/app-tools/src/plugins/deploy/platforms/vercel.ts @@ -143,9 +143,11 @@ export const createVercelPreset: CreatePreset = ( if (!needModernServer) { return; } - await handleDependencies(appDirectory, funcsDirectory, [ - '@modern-js/prod-server', - ]); + await handleDependencies({ + appDir: appDirectory, + serverRootDir: funcsDirectory, + includeEntries: [require.resolve('@modern-js/prod-server')], + }); }, }; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4ed05171a809..d9c1848b2252 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8673,13 +8673,11 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - transitivePeerDependencies: - - supports-color + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-module-imports': 7.24.6 + '@babel/helper-simple-access': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 dev: false /@babel/helper-module-transforms@7.24.6(@babel/core@7.24.6): @@ -8702,13 +8700,11 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.24.7 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - transitivePeerDependencies: - - supports-color + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-module-imports': 7.24.6 + '@babel/helper-simple-access': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 dev: false /@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7): @@ -11003,8 +10999,6 @@ packages: '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.7) '@babel/helper-plugin-utils': 7.24.6 '@babel/helper-simple-access': 7.24.6 - transitivePeerDependencies: - - supports-color dev: false /@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.7):