从React Redux(create-react-app)的package.json文件中获取版本号

162

OP编辑:如果有其他人遇到类似问题:该应用程序是使用create-react-app创建的,该工具限制了只能在src文件夹内进行导入。但是,如果升级react-scripts至v1.0.11,则可以访问package.json。

我正在尝试从我的应用程序中获取package.json中的版本号。

我已经尝试过这些建议,但由于我无法从src文件夹外部访问package.json(可能是由于React,我对此很陌生),所以它们都没有起作用。将package.json移动到src中意味着我无法从根文件夹运行npm installnpm version minornpm run build。我尝试使用process.env.npm_package_version,但结果是未定义的。

我正在使用Jenkins,但我还没有设置好推送提交的操作,我唯一的想法就是从GitLab的标签中获取版本号,但我不知道如何做到这一点,而且这会给存储库添加不必要的依赖项,因此我真的很想找到另一种替代方法。

编辑: 我的文件结构如下:

--> RootAppFolder
    |--> build
    |--> node_modules
    |--> public
    |--> src
         |--> Components
              |--> Root.js
    |
    |--> package.json

所以要从Root.js访问package.json,我必须这样做:import packageJson from './../../package.json'然后我得到以下错误:

./src/components/Root.js

模块未找到:您尝试导入 ./../../ package.json,它位于项目src / 目录之外。 src /之外的相对导入不受支持。 您可以将其移动到src /内,或者从项目的node_modules /中添加符号链接。


你也试过ES6版本了吗? - kenfire
1
我无法从src文件夹外部访问package.json,请您解释一下吗?如果可以访问package.json,那么版本号就可以轻松获取。 - shaochuancs
@shaochuancs 我已经编辑过了以解释。将 package.json 移动到 src 文件夹中可以获取版本,但是我无法运行任何 npm 命令来实际构建和运行应用程序。 - Baldeep
在ES6中,导入的语法与以前不同:import {version} from './package.json'; 取代了 var data = require('./package.json'); - kenfire
1
@shaochuancs 是的,结果发现该应用程序是使用react-create-app创建的,这通过webpack设置了限制。 - Baldeep
显示剩余4条评论
6个回答

326

不使用导入和公开package.json来解决这个问题,

需要:create-react-app版本1.1.0或更高版本

.env

REACT_APP_VERSION=$npm_package_version
REACT_APP_NAME=$npm_package_name

index.js

console.log(`${process.env.REACT_APP_NAME} ${process.env.REACT_APP_VERSION}`)

注意:版本号(以及许多其他npm配置参数)可以被访问。

注意2:仅在您重新启动开发服务器后,对.env文件所做的更改才会生效。


11
我需要在代码库的根目录下创建.env文件(作为纯文本文件),才能使其正常工作。就像这样。 - Breaker222
11
这是个不错的解决方案,但使用 import { name, version } from "../package.json"; 引用 package.json 文件会更加清晰易懂,并且不需要创建 .env 文件。 - Chunky Chunk
2
@TheDarkIn1978 但是它不能与Create React App一起使用,因为它不允许引用src/之外的内容。 - Onkeltem
10
在修改了.env文件后,不要忘记再次运行npm start - ZYinMD
7
刚刚发现在.env文件中使用NEXT_PUBLIC_APP_VERSION=$npm_package_version可以在next.js(我正在使用9.5.3)中工作,尽管我没有在任何地方看到它被记录。 - stephent
显示剩余5条评论

73

根据您的编辑,我建议尝试:

import packageJson from '/package.json';

你也可以尝试创建符号链接:

# From the project root.
cd src; ln -s ../package.json package.alias.json

列出src目录的内容,你会看到符号链接。

ls
#=> package.alias.json -> ../package.json

在这里添加.alias可以帮助其他人和未来的自己更容易地阅读代码,避免出现难以理解的情况。此外,它还可以帮助文本编辑器将它们分开。在使用时请确保将JS代码更新为从./package.alias.json导入而不是./package.json。以后你会感谢我的。

另外,请查看这个问题:The create-react-app imports restriction outside of src directory


虽然导入仍然无法正常工作,但我没有意识到该应用程序是使用create-react-app创建的,这就是问题出现的原因。所以我想解决方案就是研究webpack并自己进行配置,摆脱这个限制。 - Baldeep
1
正如 OP 在编辑问题时提到的那样,这已经不再必要。较新版本的 react-scripts 允许您从 src 之外导入。 - Joshua Pinter
10
将package.json添加到您的捆绑包中并不是一个好主意。这样做会将所有依赖项暴露给潜在攻击者,而且它是一个相当大的对象,而你只需要少数几个字节的数据。 - Joe Maffei
4
如果有人反编译应用程序并发现它使用了某个库,那又有什么关系呢?这为什么会是安全问题?防止人们反编译你的代码的唯一方法是首先不发布二进制文件。 - Andrew Koster
2
package.json 怎么会是一个“相当大的对象”,太大而无法导入?它只是几行 JSON 代码。 - Andrew Koster
显示剩余4条评论

65

试试这个。

// in package.json
"version": "1.0.0"

// in index.js
import packageJson from '../package.json';
console.log(packageJson.version); // "1.0.0"

使用Expo,这对我来说非常有效。我称之为appJson,所以它是console.log(appJson.expo.version);。谢谢! - MC10
16
这将在您的捆绑包中导入整个 package.json。 - acidernt
30
你可以使用import { version } from '../package.json';来导入版本号。 - Stephen Saucier
12
不安全!你不想将你的package.json文件暴露给用户和黑客。 - Alina_Lapina
1
@TeodorCiuraru,是的,它确实有。看一下这个链接:https://create-react-app.dev/docs/adding-custom-environment-variables/#adding-development-environment-variables-in-env React库有一个机制来实现这一点。定义REACT_APP_<SOMETHING>环境变量以公开选定的设置数据,但不包括设置本身。 - Alina_Lapina
显示剩余2条评论

40

我认为通过“import”或“require”包获取版本不正确。你可以在你的package.json中添加一个脚本。

"start": "REACT_APP_VERSION=$npm_package_version react-app-script start",

您可以在任何js文件中使用"process.env.REACT_APP_VERSION"获取它。

它也适用于构建脚本,例如:

"build": "REACT_APP_VERSION=$npm_package_version react-app-script build",

28

导入 package.json

一般来说,导入 package.json 不是个好主意。原因在于安全和捆绑包大小的问题。

是的,最新版的 webpack(默认配置)+ ES6 的 import 可以进行摇树优化(即仅包含 "version" 值而不是整个 package.json),适用于 import packageJson from '../package.json'import { version } from '../package.json'。但如果你使用 CommonJS (require()),或已更改了你的 webpack 配置,或使用其他捆绑器/转译器,则不能保证这一点。依赖于捆绑器的摇树优化来隐藏敏感数据是很奇怪的。如果坚持要导入 package.json 但不想暴露整个 package.json,则可以添加一些后构建检查来确保删除 package.json 中的其他值。

然而,对于公开的开源项目,这里的安全问题仍然是理论上的。如果安全和捆绑包大小都不是问题,或者,非保证的摇树优化对你来说足够好,那么就继续吧)

.env

.env 方法,如果可行,那就很好,但如果你不使用 create-react-app,则可能需要安装 dotenv 并进行一些额外的配置。还有一个小问题:不建议提交 .env 文件(这里这里),但如果你使用 .env 方法,似乎必须提交该文件,因为它可能成为程序工作所必需的。

最佳实践(有争议)

(这不仅适用于 create-react-app,但你仍然可以使用 react-app-rewiredeject cra 来配置 cra 中的 webpack

如果你使用 webpack,那么可以使用 DefinePlugin

plugins: [
  new webpack.DefinePlugin({
    'process.env.VERSION': JSON.stringify(
      process.env.npm_package_version,
    ),
  }),
]

现在你可以在前端程序(开发或生产)中使用console.log(process.env.VERSION)

(你也可以简单地使用VERSION代替process.env.VERSION,但通常需要额外的配置来满足代码检查工具的要求:在.eslintrc中添加globals: {VERSION: 'readonly'}doc),或者在TypeScript的.d.ts文件中添加declare var VERSION: string;

尽管它是“npm_package_version”,但它也适用于yarn。这里是npm公开环境变量的列表

其他打包工具可能有类似的插件,例如@rollup/plugin-replace


1
这是一个详细且非常有帮助的答案,谢谢! :) 假设我已经将package.json与我的应用程序捆绑在一起,那么会有哪些安全问题? - Nikita Malyschkin
@NikitaMalyschkin 如果您已经在生产代码中包含了整个package.json,则在导入版本号时不需要额外担心。但是您可能需要重新考虑首次包含整个package.json的决定。 - Tom Chen
1
每个人都在他们的 package.json 中包含什么“敏感信息”?我见过的每个 package.json 都只是一个无聊的依赖项和版本号列表。如果有人通过反编译应用程序看到它,谁会在意呢?我不认为只是导入 package.json 存在安全问题。没有人解释这个所谓的安全问题是什么,每个人都只是说它存在。 - Andrew Koster
1
@AndrewKoster 如果这是一个开源项目,那就没有这样的顾虑。如果是私有项目,则依赖列表和其他配置可能会揭示项目所有者不想公开的内容。例如,如果发现某个依赖项的漏洞,则黑客更容易发起所谓的零日攻击。 - Tom Chen
@AndrewKoster 黑客也有可能找到一种方法来更改已知的上游依赖项,以便攻击下游依赖项和应用程序。例如,您知道一个大型网站正在使用库A,您可以“社交工程”库A的维护者并获得访问权限并在代码中添加比特币矿工,然后所有大型网站的观众都将为您挖掘比特币...这可能不完全像我说的那样,但它确实发生过,您可以在Google上搜索。 - Tom Chen
@AndrewKoster并不是说前端不需要担心安全问题,还有SQL注入和跨站点相关的问题需要担心。如果你的前端和后端分离得很好,并且后端API端点编写得很好,那么前端需要处理的安全问题就会更少,但这些问题确实存在。此外,如果一个(不称职的)开发人员在后端使用node并使用相同的package.json或者至少将一些后端依赖项和配置放在package.json中,那么package.json有时可能会泄露后端依赖项和配置。 - Tom Chen

-3

打开你的 package.json 文件并更改这一行

问题是:

// in package.json

"scripts": {
    "dev": "REACT_APP_VERSION=local REACT_APP_VERSION_NUMBER=$npm_package_version react-scripts start",
...
}

解决方案是:

// in package.json

"scripts": {
    "dev": "react-scripts start",
...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接