纱线安装工作区中单个包的生产依赖项

Posted

技术标签:

【中文标题】纱线安装工作区中单个包的生产依赖项【英文标题】:Yarn install production dependencies of a single package in workspace 【发布时间】:2018-04-06 20:31:54 【问题描述】:

我正在尝试仅为我的工作区中的单个包安装生产依赖项。这可能吗?

我已经试过了:

yarn workspace my-package-in-workspace install -- --prod

但它正在安装我所有软件包的所有生产依赖项。

【问题讨论】:

【参考方案1】:

据我所知,yarn 1 不支持。

如果您尝试在 dockerfile 中安装特定包,则有一种解决方法:

    复制yarn.lock 文件和根package.json

    只复制你需要的包的 package.json:你的包和你的包依赖的其他包(本地在 monorepo 中)。

    在 dockerfile 中,手动删除您复制的所有 package.json 的所有 devDependnecies。

    在根 package.json 上运行 yarn install

注意:

确定性安装 - 建议在 monorepos 中这样做以强制确定性安装 - https://***.com/a/64503207/806963

完整的 dokefile 示例:

FROM node:12

WORKDIR /usr/project

COPY yarn.lock package.json remove-all-dev-deps-from-all-package-jsons.js change-version.js ./

ARG package_path=packages/dancer-placing-manager

COPY $package_path/package.json ./$package_path/package.json

RUN node remove-all-dev-deps-from-all-package-jsons.js && rm remove-all-dev-deps-from-all-package-jsons.js

RUN yarn install --frozen-lockfile --production

COPY $package_path/dist/src ./$package_path/dist/src
COPY $package_path/src ./$package_path/src

CMD node --unhandled-rejections=strict ./packages/dancer-placing-manager/dist/src/index.js

remove-all-dev-deps-from-all-package-jsons.js:

const fs = require('fs')
const path = require('path')
const  execSync  = require('child_process')

async function deleteDevDeps(packageJsonPath) 
  const packageJson = require(packageJsonPath)
  delete packageJson.devDependencies
  await new Promise((res, rej) =>
    fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8', error => (error ? rej(error) : res())),
  )


function getSubPackagesPaths(repoPath) 
  const result = execSync(`yarn workspaces --json info`).toString()
  const workspacesInfo = JSON.parse(JSON.parse(result).data)
  return Object.values(workspacesInfo)
    .map(workspaceInfo => workspaceInfo.location)
    .map(packagePath => path.join(repoPath, packagePath, 'package.json'))


async function main() 
  const repoPath = __dirname
  const packageJsonPath = path.join(repoPath, 'package.json')
  await deleteDevDeps(packageJsonPath)
  await Promise.all(getSubPackagesPaths(repoPath).map(packageJsonPath => deleteDevDeps(packageJsonPath)))


if (require.main === module) 
  main()

【讨论】:

【参考方案2】:

看起来现在使用 Yarn 2 很容易做到这一点:https://yarnpkg.com/cli/workspaces/focus 但我自己没试过。

这是我对 Yarn 1 的解决方案:

# Install dependencies for the whole monorepo because
# 1. The --ignore-workspaces flag is not implemented https://github.com/yarnpkg/yarn/issues/4099
# 2. The --focus flag is broken https://github.com/yarnpkg/yarn/issues/6715

# Avoid the target workspace dependencies to land in the root node_modules.
sed -i 's|"dependencies":|"workspaces":  "nohoist": ["**"] , "dependencies":|g' apps/target-app/package.json

# Run `yarn install` twice to workaround https://github.com/yarnpkg/yarn/issues/6988
yarn || yarn
# Find all linked node_modules and dereference them so that there are no broken
# symlinks if the target-app is copied somewhere. (Don't use
# `cp -rL apps/target-app some/destination` because then it also dereferences 
# node_modules/.bin/* and thus breaks them.)
cd apps/target-app/node_modules
for f in $(find . -maxdepth 1 -type l)
do
  l=$(readlink -f $f) && rm $f && cp -rf $l $f
done

现在apps/target-app 可以复制并用作独立应用程序。

我不建议将它用于生产。它很慢(因为它为整个 monorepo 安装了依赖项)并且不是很可靠(因为符号链接可能存在其他问题)。

【讨论】:

【参考方案3】:

你可以试试

yarn workspace @my-monorepo/my-package-in-workspace install -- --prod

【讨论】:

以上是关于纱线安装工作区中单个包的生产依赖项的主要内容,如果未能解决你的问题,请参考以下文章

纱线安装同一个包的多个版本

解决纱线工作区中的 TypeScript 依赖项

纱线工作区——包别名

使用 SystemJS 和通过 CDN 托管的外部依赖项的生产工作流程

生产中的最小(轻量版)PyTorch 和 Numpy 包

在纱线工作区中,如何强制解决子项目的依赖关系?