【问题标题】:Add git information to create-react-app添加git信息到create-react-app
【发布时间】:2018-07-01 16:38:03
【问题描述】:

在开发中,我希望能够从网络上查看构建信息(git 提交哈希、作者、最后提交消息等)。我试过了:

  • 使用 child_process 执行 git 命令行,并读取结果(由于浏览器环境不工作)
  • npm build期间生成一个buildInfo.txt文件并从文件中读取(不起作用,因为fs在浏览器环境中也不可用)
  • 使用“git-rev”等外部库

唯一要做的似乎是做 npm run eject 和应用 https://www.npmjs.com/package/git-revision-webpack-plugin ,但我真的不想退出 create-react-app。有人有什么想法吗?

【问题讨论】:

    标签: node.js reactjs git create-react-app


    【解决方案1】:

    您可以使用CRACOcraco-interpolate-html-plugin 轻松地将您的git 信息(如提交哈希)注入您的index.html。这样您就不必使用yarn eject,它也适用于开发服务器环境以及生产版本。

    安装 CRACO 后,craco.config.js 中的以下配置对我有用:

    const interpolateHtml = require('craco-interpolate-html-plugin');
    
    module.exports = {
      plugins: [
        {
          plugin: interpolateHtml,
          // Enter the variable to be interpolated in the html file
          options: {
            BUILD_VERSION: require('child_process')
              .execSync('git rev-parse HEAD', { cwd: __dirname })
              .toString().trim(),
          },
        },
      ],
    };
    

    在您的index.html 中: <meta name="build-version" content="%BUILD_VERSION%" />

    以下是添加到package.json 中的代码行,以使其正常运行:

    "scripts": {
        "start": "craco start",
        "build": "craco build"
    }
    

    【讨论】:

      【解决方案2】:

      如果您的 package.json 脚本始终在 unix 环境中执行,您可以通过从 shell 脚本初始化您的 .env dotenv 文件来实现与 @NearHuscarl 答案中相同的效果,但代码行数更少。生成的.env 则在后续步骤中为picked up by the react-scripts

      "scripts": {
        "start": "sh ./env.sh && react-scripts start"
        "build": "sh ./env.sh && react-scripts build",
      }
      

      .env.sh 位于您的项目根目录中,其中包含类似于以下代码的代码,用于在每次构建或启动时覆盖您的 .env 文件内容。

      {
        echo BROWSER=none
        echo REACT_APP_FOO=bar
        echo REACT_APP_VERSION=$(git rev-parse --short HEAD)
        echo REACT_APP_APP_BUILD_DATE=$(date)
        # ...
      } > .env
      

      由于 .env 在每个构建中都会被覆盖,您可以考虑将其放在 .gitignore 列表中以避免在您的提交差异中产生过多的噪音。

      再次声明:此解决方案仅适用于存在 bourne shell 解释器或类似的环境,即 unix。

      【讨论】:

        【解决方案3】:

        稍微切线(无需弹出并在开发中工作), 这可能对其他希望将其当前 git commit SHA 作为元标记添加到 index.html 中的人有所帮助:

        REACT_APP_GIT_SHA=`git rev-parse --short HEAD`
        

        到 package.json 中的构建脚本,然后添加(注意它必须以 REACT_APP 开头...否则将被忽略):

        <meta name="ui-version" content="%REACT_APP_GIT_SHA%">
        

        进入公用文件夹中的 index.html。

        在 react 组件中,这样做:

        <Component>{process.env.REACT_APP_GIT_SHA}</Component>
        

        【讨论】:

        • 我喜欢它,尽管它在开发时在 localhost 上不起作用,只有在构建生产版本之后。
        • @BugsBunny 应该以同样的方式工作。只需将分配添加到start 脚本即可。 "start": "REACT_APP_GIT_SHA=`git rev-parse --short HEAD` react-scripts start"
        • @uidevthing 你怎么知道在 package.json 脚本中使用反引号来进行替换?在偶然发现您的解决方案之前,我只是吹了几个小时,试图让它发挥作用。顺便说一句,效果很好!
        • 这不是一个跨平台的解决方案。不能在带有 Powershell 或 cmd 的 Windows 上工作。
        • cross-env 不会为此工作,而无需更改您的 npm 配置;看这里:github.com/kentcdodds/cross-env/issues/…
        【解决方案4】:

        我的方法与@uidevthing 的回答略有不同。我不想用环境变量设置污染 package.json 文件。

        您只需运行另一个脚本,将这些环境变量保存到项目根目录的.env 文件中。就是这样。

        在下面的示例中,我将使用 typescript,但无论如何转换为 javascript 应该很简单。

        package.json

        如果您使用 javascript,则为 node scripts/start.js

          ...
          "start": "ts-node scripts/start.ts && react-scripts start",
        

        脚本/start.ts

        新建脚本文件scripts/start.ts

        const childProcess = require("child_process");
        const fs = require("fs");
        
        function writeToEnv(key: string = "", value: string = "") {
          const empty = key === "" && value === "";
        
          if (empty) {
            fs.writeFile(".env", "", () => {});
          } else {
            fs.appendFile(".env", `${key}='${value.trim()}'\n`, (err) => {
              if (err) console.log(err);
            });
          }
        }
        
        // reset .env file
        writeToEnv();
        
        childProcess.exec("git rev-parse --abbrev-ref HEAD", (err, stdout) => {
          writeToEnv("REACT_APP_GIT_BRANCH", stdout);
        });
        childProcess.exec("git rev-parse --short HEAD", (err, stdout) => {
          writeToEnv("REACT_APP_GIT_SHA", stdout);
        });
        
        // trick typescript to think it's a module
        // https://stackoverflow.com/a/56577324/9449426
        export {};
        

        上面的代码将设置环境变量并将它们保存到根文件夹的.env 文件中。它们必须以REACT_APP_ 开头。然后 React 脚本会在构建时自动读取 .env,然后在 process.env 中定义它们。

        App.tsx

        ...
        console.log('REACT_APP_GIT_BRANCH', process.env.REACT_APP_GIT_BRANCH)
        console.log('REACT_APP_GIT_SHA', process.env.REACT_APP_GIT_SHA)
        

        结果

        REACT_APP_GIT_BRANCH master
        REACT_APP_GIT_SHA 042bbc6
        

        更多参考资料:

        【讨论】:

        • 像魅力一样工作???
        【解决方案5】:

        如果没有 ejecting 就不可能做到这一点,直到 Create React App 2.0 (Release Notes) 带来了在编译时运行的 Babel 插件宏的自动配置。为了让每个人的工作更简单,我编写了其中一个宏并发布了一个 NPM 包,您可以将其导入以将 git 信息导入您的 React 页面:https://www.npmjs.com/package/react-git-info

        有了它,你可以这样做:

        import GitInfo from 'react-git-info/macro';
        
        const gitInfo = GitInfo();
        
        ...
        
        render() {
          return (
            <p>{gitInfo.commit.hash}</p>
          );
        }
        

        项目README 有更多信息。您还可以在here 看到该软件包的现场演示。

        【讨论】:

        • 虽然这确实添加了另一个包,但它是实现目标的超级干净且有用的方法。
        【解决方案6】:

        受 Yifei Xu 的回复启发,我创建了另一个选项,该选项将 es6 模块与 create-react-app 结合使用。此选项创建一个 javascript 文件并将其作为常量导入到构建文件中。虽然将其作为文本文件使其易于更新,但此选项可确保它是打包到 javascript 包中的 js 文件。这个文件的名字是_git_commit.js

        package.json 脚本:

        "git-info": "echo export default \"{\\\"logMessage\\\": \\\"$(git log -1 --oneline)\\\"}\"  > src/_git_commit.js",
        "precommit": "lint-staged",
        "start": "yarn git-info; react-scripts start",
        "build": "yarn git-info; react-scripts build",
        

        使用此提交消息的示例组件:

        import React from 'react';
        
        /**
         * This is the commit message of the last commit before building or running this project
         * @see ./package.json git-info for how to generate this commit
         */
        import GitCommit from './_git_commit';
        
        const VersionComponent = () => (
          <div>
            <h1>Git Log: {GitCommit.logMessage}</h1>
          </div>
        );
        
        export default VersionComponent;
        

        请注意,这会自动将您的提交消息放入 javascript 包中,因此请确保不会在提交消息中输入任何安全信息。我还将创建的 _git_commit.js 添加到 .gitignore,因此它不会被签入(并创建一个疯狂的 git 提交循环)。

        【讨论】:

          【解决方案7】:

          所以,事实证明没有弹出就没有办法实现这一点,所以我使用的解决方法是:

          1) 在package.json中,定义一个脚本"git-info": "git log -1 --oneline &gt; src/static/gitInfo.txt"

          2) 为启动和构建添加npm run git-info

          3) 在 config js 文件中(或者当你需要 git 信息时),我有

          const data = require('static/gitInfo.txt')
          fetch(data).then(result => {
              return result.text()
          })
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-05-21
            • 1970-01-01
            • 1970-01-01
            • 2018-07-06
            • 2018-06-12
            • 2019-02-16
            • 2018-09-22
            • 2017-03-03
            相关资源
            最近更新 更多