在powershell和cmd中运行npm run 命令 对--处理的区别
在 Windows 系统中,cmd 和 PowerShell 对 npm run 命令中 -- 参数的处理方式存在一些差异。这些差异主要源于 cmd 和 PowerShell 对命令行参数的解析规则不同。
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. 关键区别
| 特性 | cmd | PowerShell |
|---|---|---|
| 参数解析规则 | 简单,原封不动传递 | 复杂,可能会对参数进行额外解析 |
-- 的处理 | -- 之后的参数直接传递给 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 示例
安装:
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可以读取命令行传入的参数。 - 手动解析参数适用于简单场景。
- 推荐使用第三方库(如
minimist或yargs)来简化参数解析,尤其是需要处理复杂参数时。
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:使用第三方库(推荐)
推荐使用第三方库(如 minimist 或 yargs)来解析参数。
使用 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 的历史
-
早期版本(v6 及之前) :
npm_config_argv在早期版本的npm中是可用的,并且被广泛使用。- 它的值是一个 JSON 字符串,包含传递给
npm和脚本的参数。
-
npm@7及更高版本:- 在
npm@7中,npm_config_argv被弃用(deprecated)。 - 取而代之的是更现代的机制,例如
process.argv和npm的内置参数解析。
- 在
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 字段中的 port 和 env 值:
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 代码中方便地访问这些配置