简体   繁体   English

在 package.json 中运行另一个 yarn/npm 任务,不指定 yarn 或 npm

[英]Run another yarn/npm task within a package.json, without specifying yarn or npm

I have a task in my package.json "deploy", which needs to first call "build".我的 package.json 中有一个任务“deploy”,需要先调用“build”。 I have specified it like this:我已经这样指定了:

"deploy": "yarn run build; ./deploy.sh", "deploy": "纱线运行构建;./deploy.sh",

The problem is that this hard codes yarn as the package manager.问题是这个硬编码yarn作为包管理器。 So if someone doesn't use yarn , it doesn't work.所以如果有人不使用yarn ,它就行不通。 Switching to npm causes a similar issue.切换到npm会导致类似的问题。

What's a good way to achieve this while remaining agnostic to the choice of npm or yarn ?在不npmyarn的选择的同时实现这一目标的好方法是什么?

One simple approach is to use the npm-run-all package, whose documentation states:一种简单的方法是使用npm-run-all包,其文档说明:

Yarn Compatibility 纱线相容性

If a script is invoked with Yarn, npm-run-all will correctly use Yarn to execute the plan's child scripts.如果使用 Yarn 调用脚本,npm-run-all 将正确使用 Yarn 执行计划的子脚本。

So you can do this:所以你可以这样做:

"predeploy": "run-s build",
"deploy": "./deploy.sh",

And the predeploy step will use either npm or yarn depending on how you invoked the deploy task. predeploy步骤将使用 npm 或 yarn,具体取决于您调用deploy任务的方式。

I think it is good to have the runs in package.json remain package manager agnostic so that they aren't tied to a specific package manager, but within a project, it is probably prudent to agree on the use of a single package manager so that you're not dealing with conflicting lockfiles.我认为让 package.json 中的运行保持与包管理器无关是很好的,这样它们就不会绑定到特定的包管理器,但在一个项目中,同意使用单个包管理器可能是谨慎的,所以你没有处理冲突的锁文件。

It's probably not ideal, but you could run a .js file at your project root to make these checks...这可能并不理想,但您可以在项目根目录下运行.js文件来进行这些检查...

You could create a file at your project root called yarnpm.js (or whatever), and call said file in your package.json deploy command..您可以在您的项目根目录创建一个名为yarnpm.js (或其他)的文件,并在您的package.json deploy命令中调用该文件。

// package.json (trimmed)
"scripts": {
  "deploy": "node yarnpm",
  "build": "whatever build command you use"
},
// yarnpm.js
const fs = require('fs');

const FILE_NAME = process.argv[1].replace(/^.*[\\\/]/, '');

// Command you wish to run with `{{}}` in place of `npm` or `yarn'
// This would allow you to easily run multiple `npm`/`yarn` commands without much work
// For example, `{{}} run one && {{}} run two
const COMMAND_TO_RUN = '{{}} run build; ./deploy.sh';

try {
  if (fs.existsSync('./package-lock.json')) {  // Check for `npm`
    execute(COMMAND_TO_RUN.replace('{{}}', 'npm'));
  } else if (fs.existsSync('./yarn.lock')) {   // Check for `yarn`
    execute(COMMAND_TO_RUN.replace('{{}}', 'yarn'));
  } else {
    console.log('\x1b[33m', `[${FILE_NAME}] Unable to locate either npm or yarn!`, '\033[0m');
  }
} catch (err) {
  console.log('\x1b[31m', `[${FILE_NAME}] Unable to deploy!`, '\033[0m');
}

function execute(command) { // Helper function, to make running `exec` easier
  require('child_process').exec(command,
    (error, stdout, stderr) => {
      if (error) {
        console.log(`error: ${error.message}`);
        return;
      }
      if (stderr) {
        console.log(`stderr: ${stderr}`);
        return;
      }
      console.log(stdout);
    });
}

Hope this helps in some way!希望这在某种程度上有所帮助! Cheers.干杯。


EDIT:编辑:

...or if you wanted to parameterize the yarnpm.js script, to make it easily reusable, and to keep all "commands" inside the package.json file, you could do something like this.. ...或者如果你想参数化yarnpm.js脚本,使其易于重用,并将所有“命令”保存在package.json文件中,你可以做这样的事情..

// package.json (trimmed, parameterized)
"scripts": {
    "deploy": "node yarnpm '{{}} run build; ./deploy.sh'",
    "build": "node build.js"
},
// yarnpm.js (parameterized)
const COMMAND_TO_RUN = process.argv[2]; // Technically, the first 'parameter' is the third index
const FILE_NAME = process.argv[1].replace(/^.*[\\\/]/, '');

if (COMMAND_TO_RUN) {
  const fs = require('fs');

  try {
    if (fs.existsSync('./package-lock.json')) {  // Check for `npm`
      execute(COMMAND_TO_RUN.replace('{{}}', 'npm'));
    } else if (fs.existsSync('./yarn.lock')) {   // Check for `yarn`
      execute(COMMAND_TO_RUN.replace('{{}}', 'yarn'));
    } else {
      console.log('\x1b[33m', `[${FILE_NAME}] Unable to locate either npm or yarn!`, '\033[0m');
    }
  } catch (err) {
    console.log('\x1b[31m', `[${FILE_NAME}] Unable to deploy!`, '\033[0m');
  }

  function execute(command) { // Helper function, to make running `exec` easier
    require('child_process').exec(command,
      (error, stdout, stderr) => {
        if (error) {
          console.log(`error: ${error.message}`);
          return;
        }
        if (stderr) {
          console.log(`stderr: ${stderr}`);
          return;
        }
        console.log(stdout);
      });
  }
} else {
  console.log('\x1b[31m', `[${FILE_NAME}] Requires a single argument!`, '\033[0m')
}

What if check before run?如果在运行前检查怎么办?

You can create a new file called build.sh , and it's content below:您可以创建一个名为build.sh的新文件,其内容如下:

# check if current user installed node environment, if not, auto install it.
if command -v node >/dev/null 2>&1; then
    echo "version of node: $(node -v)"
    echo "version of npm: $(npm -v)"
else
    # auto install node environment, suppose platform is centos, 
    # need change this part to apply other platform.
    curl --silent --location https://rpm.nodesource.com/setup_12.x | sudo bash -
    yum -y install nodejs
fi

npm run build

Then your script will be:那么你的脚本将是:

{
  "deploy": "./build.sh && ./deploy.sh"
}

So I think I have a much simpler solution:所以我想我有一个更简单的解决方案:

"deploy": "yarn run build || npm run build; ./deploy.sh",

Its only real downside is in the case where yarn exists, but the build fails, then npm run build will also take place.它唯一真正的缺点是在存在纱线的情况下,但构建失败,然后npm run build也会发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在没有 yarn/npm 命令的情况下使用 package.json 脚本 - Use package.json script without yarn/npm command 使用npm和yarn的package.json脚本? - package.json scripts that work with npm and yarn? npm 和 yarn:package.json 是否比 lockfile 有优先级? - npm and yarn: does package.json have the priority over lockfile? 如何仅从package.json创建npm / yarn依赖树; 不创建node_modules文件夹 - How to create npm/yarn dependency tree from just package.json; without creating node_modules folder 如何在docker构建期间的yarn / npm安装期间缓存node_modules以获取未更改的package.json - How to cache node_modules for unchanged package.json during yarn / npm install during docker build? 当package.json具有不正确的版本时,从npm迁移到yarn - Migrating from npm to yarn when package.json has incorrect versions 如何通过使用npm install或yarn安装仅具有自己版本的package.json依赖项 - how to install only package.json dependencies with their own versions by using npm install or yarn 在 package.json 脚本键:npm 运行与否? - In package.json scripts key: npm run or not? 使用 npm 而不是 yarn 安装包时出错 - Error installing package using npm instead of yarn 如何查找通过YARN或npm全局安装的软件包 - How to find package installed globally with YARN or npm
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM