- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个有助于固定依赖关系的 Node 脚本。
如何从 semver 版本中确定 NPM 服务器上存在的包的最大实现版本?
例如,我们有一个依赖“foo”,它在 package.json 中指定为 ~1.2.3
.
在 NPM 上,有发布版本 1.2.5
,这是与 ~1.2.3
兼容的最新发布版本.
我需要编写一个将“foo”和~1.2.3
作为输入的脚本,然后在服务器查询后,返回 1.2.5
.像这样的东西:
await fetchRealizedVersion('foo', '~1.2.3'); // resolves to 1.2.5
我知道我可以这样做
yarn upgrade
然后解析锁定文件,但我正在寻找一种更直接的方法来完成此操作。
最佳答案
"Hopefully there is a package that boils this down to an API call,"
get-latest-version
您可能想尝试的包:
Basic usage:
const getLatestVersion = require('get-latest-version')
getLatestVersion('some-other-module', {range: '^1.0.0'})
.then((version) => console.log(version)) // highest version matching ^1.0.0 range
.catch((err) => console.error(err))
npm view <pkg> versions --json
https
向公众请求npm registry在 https://registry.npmjs.org
检索给定包的所有可用版本。~1.2.3
)一起传递给 node-semver包的maxSatisfying()
方法。maxSatisfying()
方法在 docs 中描述作为:
maxSatisfying(versions, range)
: Return the highest version in the list that satisfies the range, ornull
if none of them do.
get-latest-version.js
中提供的自定义示例模块(下)基本上执行上述步骤。在这个例子中,我们使用
npm view
命令。
'use strict';
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const { exec } = require('child_process');
const { maxSatisfying } = require('semver');
//------------------------------------------------------------------------------
// Data
//------------------------------------------------------------------------------
const errorBadge = '\x1b[31;40mERR!\x1b[0m';
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Captures the data written to stdout from a given shell command.
*
* @param {String} command The shell command to execute.
* @return {Promise<string>} A Promise object whose fulfillment value holds the
* data written to stdout. When rejected an error message is returned.
* @private
*/
function shellExec(command) {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(new Error(`Failed executing command: '${command}'`));
return;
}
resolve(stdout.trim());
});
});
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
/**
* Retrieves the latest version that matches the given range for a package.
*
* @async
* @param {String} pkg The package name.
* @param {String} range The semver range.
* @returns {Promise<string>} A Promise object that when fulfilled returns the
* latest version that matches. When rejected an error message is returned.
*/
async fetchRealizedVersion(pkg, range) {
try {
const response = await shellExec(`npm view ${pkg} versions --json`);
const versions = JSON.parse(response);
return maxSatisfying(versions, range);
} catch ({ message: errorMssg }) {
throw Error([
`${errorBadge} ${errorMssg}`,
`${errorBadge} '${pkg}' is probably not in the npm registry.`
].join('\n'));
}
}
};
index.js
演示使用上述模块。
'use strict';
const { fetchRealizedVersion } = require('./get-latest-version.js');
(async function() {
try {
const latest = await fetchRealizedVersion('eslint', '~5.15.0');
console.log(latest); // --> 5.15.3
} catch ({ message: errMssg }) {
console.error(errMssg);
}
})();
如您所见,在该示例中,我们获得了
eslint 的最新发布版本。与 semver 波浪号范围兼容的软件包
~5.15.0
.
~5.15.0
的最新/最大版本打印到控制台:
$ node ./index.js
5.15.3
node-semver
包裹。
index.js
演示使用上述模块获取多个包和不同范围的最新/最大版本。
'use strict';
const { fetchRealizedVersion } = require('./get-latest-version.js');
const criteria = [
{
pkg: 'eslint',
range: '^4.9.0'
},
{
pkg: 'eslint',
range: '~5.0.0'
},
{
pkg: 'lighthouse',
range: '~1.0.0'
},
{
pkg: 'lighthouse',
range: '^1.0.4'
},
{
pkg: 'yarn',
range: '~1.3.0'
},
{
pkg: 'yarn',
range: '^1.3.0'
},
{
pkg: 'yarn',
range: '^20.3.0'
},
{
pkg: 'quuxbarfoo',
range: '~1.3.0'
}
];
(async function () {
// Each request is sent and read in parallel.
const promises = criteria.map(async ({ pkg, range }) => {
try {
return await fetchRealizedVersion(pkg, range);
} catch ({ message: errMssg }) {
return errMssg;
}
});
// Log each 'latest' semver in sequence.
for (const latest of promises) {
console.log(await latest);
}
})();
最后一个示例的结果如下:
$ node ./index.js
4.19.1
5.0.1
1.0.6
1.6.5
1.3.2
1.22.4
null
ERR! Failed executing command: 'npm view quuxbarfoo versions --json'
ERR! 'quuxbarfoo' is probably not in the npm registry.
shellExec
get-latest-version.js
中的辅助函数目前 promise
child_process
模块的
exec()
脱壳
npm view
的方法命令。但是,由于 node.js 版本 12,内置的
util.promisify
提供另一种方式来 promise
exec()
方法(如
exec
的文档中所示),因此您可能更喜欢这样做。
npm view
命令,您可以考虑直接向
https://registry.npmjs.org
发出请求端点(与
npm view
命令发送 https
GET
请求的端点相同)。
get-latest-version.js
的修改版(下)基本上使用了内置
https.get
的 promise 版本.
'use strict';
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const https = require('https');
const { maxSatisfying } = require('semver');
//------------------------------------------------------------------------------
// Data
//------------------------------------------------------------------------------
const endPoint = 'https://registry.npmjs.org';
const errorBadge = '\x1b[31;40mERR!\x1b[0m';
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Requests JSON for a given package from the npm registry.
*
* @param {String} pkg The package name.
* @return {Promise<json>} A Promise object that when fulfilled returns the JSON
* metadata for the specific package. When rejected an error message is returned.
* @private
*/
function fetchPackageInfo(pkg) {
return new Promise((resolve, reject) => {
https.get(`${endPoint}/${pkg}/`, response => {
const { statusCode, headers: { 'content-type': contentType } } = response;
if (statusCode !== 200) {
reject(new Error(`Request to ${endPoint} failed. ${statusCode}`));
return;
}
if (!/^application\/json/.test(contentType)) {
reject(new Error(`Expected application/json but received ${contentType}`));
return;
}
let data = '';
response.on('data', chunk => {
data += chunk;
});
response.on('end', () => {
resolve(data);
});
}).on('error', error => {
reject(new Error(`Cannot find ${endPoint}`));
});
});
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
/**
* Retrieves the latest version that matches the given range for a package.
*
* @async
* @param {String} pkg The package name.
* @param {String} range The semver range.
* @returns {Promise<string>} A Promise object that when fulfilled returns the
* latest version that matches. When rejected an error message is returned.
*/
async fetchRealizedVersion(pkg, range) {
try {
const response = await fetchPackageInfo(pkg);
const { versions: allVersionInfo } = JSON.parse(response);
// The response includes all metadata for all versions of a package.
// Let's create an Array holding just the `version` info.
const versions = [];
Object.keys(allVersionInfo).forEach(key => {
versions.push(allVersionInfo[key].version)
});
return maxSatisfying(versions, range);
} catch ({ message: errorMssg }) {
throw Error([
`${errorBadge} ${errorMssg}`,
`${errorBadge} '${pkg}' is probably not in the npm registry.`
].join('\n'));
}
}
};
7.3.2
)。版本
^5.7.1
而是使用了 - 这与
npm cli 使用的版本相同工具。
关于node.js - 从 semver 版本中确定 NPM 服务器上存在的依赖项的最大匹配版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63022138/
我的理解是,使用 X.Y.Z,我们只更改 X 以进行重大更改。 Y 用于向后兼容的功能更改。 所以我假设即使我的更新是对功能的绝对巨大的补充——没有破坏性的变化,因为它只是一个补充,我仍然不会改变 X
昨天,这个错误在两个项目中开始出现,哪个解决方案可行? node_modules/yo Output: /Users/mac/.config/yarn/global/node_modules/semv
我有一个使用 ubuntu/trusty64 box 创建的 Vagrant 虚拟机(它运行 Ubuntu 14.04.3 LTS(GNU/Linux 3.13.0-66-generic x86_64
在微服务产品中应用 SemVer 是否有最佳实践/模式?每个微服务是否应该有 SemVer,整个产品是否应该有 SemVer? 示例 - 我有一个名为 SuperDatabase 的产品,其中包含 3
我注意到 JavaScript 世界中有些东西随着时间的推移而发生了变化。以前,后端和前端在对库或应用程序进行版本控制时使用 semver 方法。现在,在 JS 世界中,我看到越来越多的库或框架遵循每
根据semver "PATCH version when you make backwards-compatible bug fixes." 和 "A bug fix is defined as an
我们正在为我们的 CSS 库使用 semver,确保遵循官方 guidelines关于如何对它们进行版本控制。 然而,每当我们让一个类(或者在 JS 的情况下——一个属性或参数)过时——我们应该怎么做
我们正在为我们的 Java 库引入语义版本控制 ( http://semver.org/)。 我们应该如何处理添加新的枚举值?我们的情况如下: annotations.jar 包含一个注解,其属性类型
假设我发布了一个新库 Foo v1.0.0,它需要 php 5.6 作为依赖项。 现在我想在一些方法实现中内部使用 php 7.0 中的一些较新的语言结构。但是,我的整个公共(public) API(
你好,我正在测试 GitVersion,我添加了一个 Commit Message +semver:minor,现在版本的次要编号增加了。如果我做错了,如何回滚推荐什么? -> 我尝试使用恢复但它没有
我正在制作一个 npm 包并将其发布为 1.0.0 版,因为我对公共(public) API 很满意。但是现在,我正在添加一个“示例”子项目来展示如何使用该库。显然,我不会将示例项目作为库的一部分发布
假设我在 MongoDB 中有一些文档,带有 version属性(semver 版本),例如类似 { ..., version: { major: 1, minor: 2, patch: 13 } }
我当前的Git版本是3.2.1,但之前是误操作的。 如何将版本减少到 2.2.1? 如果重要的话我会使用 TeamCity。 最佳答案 这是一个有趣的问题...... 归根结底,版本是如何被断言的。例
有标准的 npm semver 版本比较库,但我有一些简单的逻辑来比较 semver 版本: const versionA = '14.8.3'; const versionB = '15.1.1';
我正在考虑采用 semver对于另一个也遵循 semver 的库的包装器。最初我以为我会保持包装器的版本与原始库相同,因为理想情况下它们会一直完全匹配。 然而,这并不是那么简单,因为包装器本身可能存在
所以“myLibrary”引用“anotherLibrary”。两个库都遵循 http://semver.org/ 如果我发布 myLibrary 的新版本,强制消费者更新到 anotherLibra
我正在尝试使用解析器组合器在 Scala 中编写一个 SemVer ( http://semver.org) 解析器,作为对它们的一种熟悉。 这是我当前的代码: case class SemVer(m
考虑使用这些版本的库(例如 NPM 包): 1.0.0 1.0.2 1.1.0-预发布 如果我指定 ^1.0.0在我的依赖项中,将安装什么版本? 1.1.0-prerelease是最新版本,但我认为没
我正在尝试使用 GitVersion 来增加我的补丁版本号的 +semver:patch 命令,但它没有按我期望的方式工作。 我的 上有一个标签“2.2.0”大师分支。我在 上做了以下提交开发 分支:
我正在使用 ubuntu 19.04。 尝试使用 npm 执行任何操作时出现以下错误 internal/modules/cjs/loader.js:638 throw err; ^ E
我是一名优秀的程序员,十分优秀!