读取命令行传入的参数

394 阅读7分钟

在powershell和cmd中运行npm run 命令 对--处理的区别

在 Windows 系统中,cmdPowerShellnpm run 命令中 -- 参数的处理方式存在一些差异。这些差异主要源于 cmdPowerShell 对命令行参数的解析规则不同。


1. cmd-- 的处理

cmd 是 Windows 的传统命令行工具,它对参数的处理相对简单:

  • -- 之后的参数会被原封不动地传递给 npm
  • npm 再将这些参数传递给脚本。

示例

npm run start -- --arg1 value1 --arg2 value2

cmd 中:

  • -- 之后的 --arg1 value1 --arg2 value2 会被作为一个整体传递给 npm

  • 脚本中的 process.argv 会得到:

    ['--arg1', 'value1', '--arg2', 'value2']
    

2. PowerShell-- 的处理

PowerShell 是 Windows 的现代脚本环境,它对参数的处理更加复杂:

  • PowerShell 会先解析命令行参数,然后将解析后的结果传递给 npm
  • 如果参数中包含特殊字符(如 ---),PowerShell 可能会对其进行额外的处理。

示例

npm run start -- --arg1 value1 --arg2 value2

PowerShell 中:

  • PowerShell 会将 -- 之后的参数解析为 --arg1 value1 --arg2 value2

  • 但由于 PowerShell 的解析规则,可能会将 --arg1--arg2 视为 npm 的选项,而不是脚本的参数。

  • 脚本中的 process.argv 可能得到:

    ['value1', 'value2']
    

3. 关键区别

特性cmdPowerShell
参数解析规则简单,原封不动传递复杂,可能会对参数进行额外解析
-- 的处理-- 之后的参数直接传递给 npm-- 之后的参数可能被解析为选项
参数传递一致性一致可能不一致

4. 总结

使用这两种方式来传递参数

npm run script --foo=bar
​
console.log(process.env.npm_config_foo); // 输出: bar
// 如果要兼容 cmd和powershell,命令行中就不要使用 -- 或 - 
​
npm run script arg1=123 flag value
​
const args = process.argv.slice(2);
console.log(args); // 输出 [ 'arg1=123', 'flag', 'value' ] 

node中读取命令行传入的参数(cmd和powershell表现一致)

在 Node.js 中,可以通过 process.argv 来读取命令行传入的参数。process.argv 是一个数组,包含了启动 Node.js 进程时传入的所有命令行参数。


1. process.argv 的结构

process.argv 数组的结构如下:

  • process.argv[0]:Node.js 可执行文件的路径。
  • process.argv[1]:当前执行的 JavaScript 文件的路径。
  • process.argv[2] 及之后的元素:命令行传入的参数。

例如,运行以下命令:

node script.js arg1 arg2 --flag value

process.argv 的值将是:

[
  '/path/to/node',       // Node.js 可执行文件路径
  '/path/to/script.js',  // 当前脚本文件路径
  'arg1',                // 第一个参数
  'arg2',                // 第二个参数
  '--flag',              // 第三个参数
  'value'                // 第四个参数
]

2. 读取命令行参数

可以通过遍历 process.argv 或直接访问索引来获取参数。

示例 1:简单读取参数

// script.js
const args = process.argv.slice(2); // 去掉前两个元素
console.log('传入的参数:', args);

运行:

node script.js arg1 arg2 --flag value

输出:

传入的参数: [ 'arg1', 'arg2', '--flag', 'value' ]

示例 2:解析键值对参数

如果需要解析类似 --flag value 的参数,可以手动处理:

const args = process.argv.slice(2);
const params = {};
​
for (let i = 0; i < args.length; i++) {
  if (args[i].startsWith('--')) {
    const key = args[i].slice(2); // 去掉 '--'
    const value = args[i + 1];    // 下一个元素是值
    params[key] = value;
    i++; // 跳过下一个元素
  }
}
​
console.log('解析后的参数:', params);

运行:

node script.js --name Alice --age 25

输出:

解析后的参数: { name: 'Alice', age: '25' }

3. 使用第三方库解析参数

手动解析参数可能比较繁琐,推荐使用第三方库来简化操作。常用的库有:

  • minimist:轻量级命令行参数解析库。
  • yargs:功能强大的命令行参数解析库。

使用 minimist 示例

安装:

npm install minimist

代码:

const minimist = require('minimist');
​
const args = minimist(process.argv.slice(2));
console.log('解析后的参数:', args);

运行:

node script.js --name Alice --age 25

输出:

解析后的参数: { _: [], name: 'Alice', age: 25 }

使用 yargs 示例

安装:

npm install yargs

代码:

const yargs = require('yargs/yargs');
const { argv } = yargs(process.argv.slice(2));
​
console.log('解析后的参数:', argv);

运行:

node script.js --name Alice --age 25

输出:

解析后的参数: { _: [], name: 'Alice', age: 25, '$0': 'script.js' }

4. 总结

  • 使用 process.argv 可以读取命令行传入的参数。
  • 手动解析参数适用于简单场景。
  • 推荐使用第三方库(如 minimistyargs)来简化参数解析,尤其是需要处理复杂参数时。

node中读取在命令行传给npm的参数

在 Node.js 中,如果你想读取通过 npm 命令传递的参数(例如 npm run script -- --arg1 value1 --arg2 value2),需要注意以下几点:


1. npm 传递参数的特殊性

当通过 npm run 运行脚本时,npm 会将 -- 之后的所有参数传递给脚本。例如:

npm run script -- --arg1 value1 --arg2 value2

这里的 --npm 的语法,表示后面的参数是传递给脚本的,而不是 npm 本身的参数。


2. 使用 process.argv(cmd运行,才是下面的效果)

在 Node.js 脚本中,仍然可以通过 process.argv 来读取这些参数。npm 会将 -- 之后的参数添加到 process.argv 中。

示例代码

// script.js
const args = process.argv.slice(2); // 去掉前两个元素(Node.js 路径和脚本路径)
console.log('传入的参数:', args);

运行:

npm run script -- --arg1 value1 --arg2 value2

输出:

// 在cmd中运行的结果
传入的参数: [ '--arg1', 'value1', '--arg2', 'value2' ]// 在powershell运行的结果,powershell认为-- 或 - 是powershell自己的参数,所以就不会将 --、--flag传过去
传入的参数: [ 'value1', 'value2' ]

最佳实践

如果要兼容 cmd和powershell,命令行中就不要使用 -- 或 -

npm run script arg1=123 flag value
​
const args = process.argv.slice(2);
console.log(args); // 输出 [ 'arg1=123', 'flag', 'value' ] 

解析参数

如果需要解析参数(例如将 --arg1 value1 转换为键值对),可以使用以下方法:

方法 1:手动解析
const args = process.argv.slice(2);
const params = {};
​
for (let i = 0; i < args.length; i++) {
  if (args[i].startsWith('--')) {
    const key = args[i].slice(2); // 去掉 '--'
    const value = args[i + 1];    // 下一个元素是值
    params[key] = value;
    i++; // 跳过下一个元素
  }
}
​
console.log('解析后的参数:', params);

运行:

npm run script -- --name Alice --age 25

输出:

解析后的参数: { name: 'Alice', age: '25' }
方法 2:使用第三方库(推荐)

推荐使用第三方库(如 minimistyargs)来解析参数。

使用 minimist

安装:

npm install minimist

代码:

const minimist = require('minimist');
​
const args = minimist(process.argv.slice(2));
console.log('解析后的参数:', args);

运行:

npm run script -- --name Alice --age 25

输出:

解析后的参数: { _: [], name: 'Alice', age: 25 }
使用 yargs

安装:

npm install yargs

代码:

const yargs = require('yargs/yargs');
const { argv } = yargs(process.argv.slice(2));
​
console.log('解析后的参数:', argv);

运行:

npm run script -- --name Alice --age 25

输出:

解析后的参数: { _: [], name: 'Alice', age: 25, '$0': 'script.js' }

3. 使用环境变量 npm_config_* (cmd和powershell表现一样)

npm 会将传递给脚本的参数作为环境变量存储在 npm_config_* 中。例如,参数 --foo=bar 会变成环境变量 npm_config_foo=bar

示例:

在命令行运行以下命令:

npm run script --foo=bar

script.js 中读取环境变量:

console.log(process.env.npm_config_foo); // 输出: bar
// 第一种传参
npm run temp --name Alice --age 25 --tt=1234 -> 
​
process.env.npm_config_age true
process.env.npm_config_name true
process.env.npm_config_argv undefined
​
// 第二种传参
npm run temp --name=Alice --age=25 --tt=1234 ->
​
process.env.npm_config_argv undefined
process.env.npm_config_age 25
process.env.npm_config_name Alice

4. 总结

  • 使用 process.argv.slice(2) 可以直接读取命令行传递给 npm 的参数。
  • 使用 npm_config_* 环境变量可以读取 npm 的配置参数。
  • 使用 -- 可以明确分隔 npm 参数和脚本参数。
  • 使用 minimist 等第三方库可以更方便地解析参数。

vue中读取在命令行传给npm的参数

1. 通过 DefinePlugin Webpack插件

// vue.config.js
module.exports = {
    configureWebpack: config => {
        config.plugins.push(
        new webpack.DefinePlugin({
           // process.env.npm_config_argv 在npm6及以下才支持,npm7+已经被废弃了
          'process.env.STAGE': process.env.npm_config_argv || process.env.npm_config_foo ||                 process.argv.slice(2)
         })
        )
    }
}
// 业务代码->http.js
if (process.env.STAGE == 'test') {
    // 
} else if (process.env.STAGE == 'foo') {
    //
}

2. 通过 process.env.VUE_APP_* 使用

只有以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中

// vue.config.js
process.env.VUE_APP_URL = process.env.npm_config.url
// 业务代码-> App.vue
console.log( { process.env.VUE_APP_URL: process.env.VUE_APP_URL } )

vue读取命令行参数的所有方式

1. .env文件

官网

2. cross-env

设置

// package.json
{
  "scripts": {
    "serve": "cross-env VUE_APP_ENV=production VUE_APP_PORT=8080 vue-cli-service serve"
  }
}

使用

// main.js
console.log("Environment:", process.env.VUE_APP_ENV);
console.log("Port:", process.env.VUE_APP_PORT);
​

3. 通过命令行传入

传入

npm run serve -url=abc 或者 npm run serve --url=abc
console.log( process.env?.npm_config_url ) // abc
            
npm run serve -url abc 或者 npm run serve --url abc
console.log( process.env?.npm_config_url ) // true

使用

// vue.config.js
process.env.VUE_APP_URL = process.env?.npm_config_url || ''
// 不建议使用, process.env.npm_config_argv 和 process.argv 来获取命令行传入的参数
// http.js
console.log(process.env.VUE_APP_URL)

process.env.npm_config_argv的使用

process.env.npm_config_argv 是一个非官方的环境变量,其可用性和行为在不同的 npm 版本中可能有所不同。以下是一些关键信息:


npm_config_argv 的历史

  1. 早期版本(v6 及之前)

    • npm_config_argv 在早期版本的 npm 中是可用的,并且被广泛使用。
    • 它的值是一个 JSON 字符串,包含传递给 npm 和脚本的参数。
  2. npm@7 及更高版本

    • npm@7 中,npm_config_argv 被弃用(deprecated)。
    • 取而代之的是更现代的机制,例如 process.argvnpm 的内置参数解析。

npm_config_argv 的现状

npm@7 开始,npm_config_argv 不再被推荐使用,因为它是一个非官方的 API,可能在不同版本中表现不一致。如果你在项目中使用了 npm@7 或更高版本,建议避免依赖 npm_config_argv

替代方案

npm run script --foo=bar
​
console.log(process.env.npm_config_foo); // 输出: bar
​
或者
npm run script arg1=123 flag value
​
const args = process.argv.slice(2);
console.log(args); // 输出 [ 'arg1=123', 'flag', 'value' ] 

npm config读取

config

文件中的 config 字段用于定义项目的配置参数,这些参数可以在 npm 脚本中通过环境变量访问。它提供了一种在package.json 中存储和管理配置的方式。

示例

以下是一个 config 字段的示例:

{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "start": "node server.js",
    "build": "node build.js"
  },
  "config": {
    "port": "8080",
    "env": "production"
  }
}

使用 config 字段

在 npm 脚本中,可以通过 npm_package_config_<key> 环境变量访问 config 字段中的值。例如:

{
  "scripts": {
    "start": "node server.js",
    "build": "node build.js",
    "serve": "node server.js --port=$npm_package_config_port --env=$npm_package_config_env"
  },
  "config": {
    "port": "8080",
    "env": "production"
  }
}

在这个示例中,serve 脚本将会使用 config 字段中的 portenv 值:

node server.js --port=8080 --env=production

访问 config 字段

Node.js使用

在 Node.js 脚本中,你也可以通过 process.env 访问这些配置:

const port = process.env.npm_package_config_port;
const env = process.env.npm_package_config_env;
​
console.log(`Server running on port ${port} in ${env} mode`);
vue.config.js中使用

在 vue.config.js文件中也能获取到,在业务代码中无法获取

// vue.config.js
const port = process.env.npm_package_config_port;
const env = process.env.npm_package_config_env;
​
console.log(`--------------------- Server running on port ${port} in ${env} mode --------`);
业务代码中使用
// vue.config.js
const port = process.env.npm_package_config_port;
const env = process.env.npm_package_config_env;
​
console.log(`--------------------- Server running on port ${port} in ${env} mode --------`);
​
process.env.VUE_APP_DXPORT = process.env.npm_package_config_port
process.env.VUE_APP_DXENV = process.env.npm_package_config_env
// main.js
const port = process.env.VUE_APP_DXPORT;
const env = process.env.VUE_APP_DXENV;
​
console.log('%cmain', 'padding:8px;background:green;font-weight: bold;');
console.log(`Server running on port ${port} in ${env} mode`);

作用

  • 集中管理配置:将配置集中存储在 package.json 中,便于管理和维护。

通过使用 config 字段,你可以在 package.json 中集中管理项目的配置,并在 npm 脚本和 Node.js 代码中方便地访问这些配置