npm package config 如何使用环境变量来生成新的环境变量
发布于 5 年前 作者 shynome 3899 次浏览 来自 问答

我在编写 docker 镜像的时候, 想要通过 npm version 来控制 docker 版本号

{
	"author": {
	  "name": "author"
	},
	"version": "0.0.1",
	"name": "name",
	"config": {
		"dockerimage": "$npm_package_author_name/$npm_package_name:$npm_package_version"
	},
	"scripts": {
		"build": "docker build . -t $npm_package_config_dockerimage"
	}
}

期望 $npm_package_config_dockerimage 返回解析好的字符串 author/name:0.0.1, 实际返回的却是未解析的字符串 $npm_package_author_name/$npm_package_name:$npm_package_version

请教各位大佬这个该怎么办


以上是原提问

这是暂时我找到的相对来说比较优雅的解决方案

{
	"config": {
		"dockerimage": "echo $npm_package_author_name/$npm_package_name:$npm_package_version"
	},
	"scripts": {
		"echo": "echo $(eval $npm_package_config_dockerimage)"
	}
}

相对于新建一个文件来获取变量解析后的字符串来说要好点. 但是使用 eavl 来解析字符串也是挺丑的, 不过只要把 $(eval $npm_package_config_dockerimage) 整体当做一个变量也还好, 毕竟变量名称已经挺长的, 再长一点影响也不是特别大

但这个方案不是很优雅, 所以还有没有优雅的解决方式呢

15 回复

为什么不把这段脚本放到 bin/build.js 里面

@atian25 感觉就一行命令占一个文件有点浪费

@atian25 现在暂时用的是新建一个文件 imagename

#!/bin/sh
echo $npm_package_author_name/$npm_package_name:$npm_package_version

然后通过 $(./imagename) 来获取名字. 虽然能用但是觉得不舒服

谷歌可是个好东西:

#!/bin/sh
PACKAGE_VERSION=$(cat package.json \
  | grep version \
  | head -1 \
  | awk -F: '{ print $2 }' \
  | sed 's/[",]//g' \
  | tr -d '[[:space:]]')

echo $PACKAGE_VERSION

@XiaozhongLiu 我问的明明不是这个东西呀, 是 config 中设置的变量不解析环境变量, 直接返回字符串常量

要调取版本号的话有如下两种快捷方式 :

  • PACKAGE_VERSION=$(node -pe “require(’’./package.json).version”)
  • $npm_package_version # 在 npm-script 中运行的话会有这个变量

没看清你原来的描述,在package里配docker image串比较奇怪。既然你要这么做,试试这样写: %npm_package_version%

没用的, scripts 是被放到 bash 里面执行,所以才会解析环境变量。而 config 字段只是一个参数而已。 这种事就应该放在单独脚本里面去做,不要硬塞到配置里面。 放到脚本还能写对应的测试来保障它的逻辑正确。

@atian25 所以我说了, 在package里配docker image串比较奇怪, 你就在脚本里拼不就好了. 脚本里面既然在做image构建了, 拼接放在一块不就好了, 干嘛放在package.json里.

@XiaozhongLiu 跟我啥关系… 我在一楼叫让他写脚本了。

正确的做法应该是:

{
  "scripts": {
    "echo": "node bin/echo.js"
  }
}

bin/echo.js 里面直接用 js 语法

#!/usr/bin/env node
console.log(process.env.npm_package_author_name);

但其实还可以更好一点,你无非是想传递参数给 npm scripts

#!/usr/bin/env node
console.log(process.argv);

然后 npm run echo -- --xx=aaaa

贴一个我java项目里面CICD的子脚本供参考, pom.xml是java的配置文件. node的没在手边就不贴了:

#!/bin/bash


# load variables from pom.xml
artifactId=`grep "^    <artifactId>" ./api/pom.xml | cut -c 17-19`
version=`grep "^    <version>" ./api/pom.xml | cut -c 14-27`


# init variables used behind
config="
    app_name="spring-api-seed"
    app_artifact_id=$artifactId
    app_version=$version
    app_prod_port="9105"
"

tmpl_docker_file=`cat ./tmpl/Dockerfile`
tmpl_start=`cat ./tmpl/start.sh`


# generate deploy related files
printf "
$config\n
cat << EOF
$tmpl_docker_file
EOF
" | bash > ./Dockerfile

printf "
$config\n
cat << EOF
$tmpl_start
EOF
" | bash > ./start.sh

我现在也是遇到和楼主一样的问题,那么,我想问一下各位大神命令行程序到底怎样写写,放在什么位置才更好。

回到顶部