【问题标题】:How can I inject a build number with webpack?如何使用 webpack 注入内部版本号?
【发布时间】:2014-08-31 00:56:40
【问题描述】:

我想将内部版本号和版本信息注入我的项目,因为它是使用 webpack 构建的。例如,以便我的代码可以执行以下操作:

var buildInfo = require("build-info");

在构建时生成 build-info 模块的最佳方法是什么?

【问题讨论】:

    标签: webpack


    【解决方案1】:

    您可以使用DefinePlugin,这将使您的构建信息与您的代码内联:

    配置

    new webpack.DefinePlugin({
       __VERSION__: JSON.stringify('12345')
    })
    

    应用代码

    console.log(__VERSION__);
    

    【讨论】:

    • 你从哪里得到版本号?是否需要从package.json读入NPM包版本?
    • @beerdev:您需要创建自己的号码。我使用了 git repo 中的提交次数:var __versionString__ = childProcess.execSync('git rev-list HEAD --count').toString();
    • @MichaelBushe childProcess 在构建时可用,如果你:var childProcess = require('child_process').@geon 很好的例子,它运行良好!我遇到了一个起初令人困惑的小问题。也许这很明显并且似乎不值得一提,但我必须同时修剪和引用 git 结果以避免我的构建中的语法错误(使用 webpack v. 1):new webpack.DefinePlugin({ __VERSION__: `"${__versionString__}"` })
    • 如果你想从package.json获取版本号,可以这样做:__VERSION__: JSON.stringify(require("./package.json").version),
    • 查看此解决方案以获取相同但更广泛的讨论github.com/webpack/webpack/issues/237#issuecomment-342129128
    【解决方案2】:

    我会做得更多更简单,只需使用npm version patch (npm-version) (无需插件)

    package.json(构建前的示例路径版本)

    {
      "version": "1.0.0",
      "scripts": {
        "build": "npm version patch && node build/build.js"
      }
    }
    

    因此,当您运行 npm run build 时,这将修补版本(您的 package.json 中的 1.0.01.0.1


    奖励:您也可以将其添加到您的配置(例如config/prod.env.js

    'use strict'
    const pkg = require('./package.json')
    module.exports = {
      NODE_ENV: '"production"',
      VERSION: pkg.version
    }
    

    那么你就可以在你的JS中的任何地方使用process.env.VERSION

    更新:just useprocess.env.npm_package_version,无需包含package.json

    【讨论】:

    • 请注意,npm version patch 也会影响 GIT; “如果在 git repo 中运行,它还会创建版本提交和标记。此行为由 git-tag-version 控制,并且可以在命令行上通过运行 npm --no-git-tag-version version 禁用. 如果工作目录不干净,它将失败,除非设置了 -f 或 --force 标志。来源:docs.npmjs.com/cli/version
    • VERSION: JSON.stringify(require('../package.json').version) 将在应用程序中包含完整的 package.json。我不确定这是不是好事。
    • 运行版本补丁会死循环
    【解决方案3】:

    有一个插件可以从package.json 自动注入版本。 它可以将其作为注释注入到 HTML、CSS、JS 中,也可以通过特殊标记 webpack-auto-inject-version 将其作为值。

    如何:

    首先,你必须将它添加到你的项目中:

    npm i webpack-auto-inject-version
    

    然后你需要设置你的 webpack 配置:

    var WebpackAutoInject = require('webpack-auto-inject-version');
    
    module.exports = {
        plugins: [
            new WebpackAutoInject()
        ]
    }
    

    由于你想将它注入到 javascript 中,你应该在你的 javascript 文件中添加一个标签(在 webpack 编译期间将更改为版本)

    var version = '[AIV]{version}[/AIV]';
    console.log(version);
    

    自动增加:

    您可以通过以下方式将其设置为直接从 webpack 自动增加版本:

    webpack --other-webpack-settings --major
    
    webpack --other-webpack-settings -- minor
    
    webpack --other-webpack-settings --patch
    

    其中--other-webpack-settings 等于您的自定义行参数。 简化 - 每当您想自动增加版本时,您都需要 --major--minor--patch

    【讨论】:

    • 此插件不再适用于 Webpack 2.0 - 不再接受自定义参数。您必须在每个前面加上“env”,这会破坏插件的自动增量功能。
    • 当前版本支持 Webpack 2。
    • 他的问题是关于版本号
    • 未维护的包。我正在使用它,但现在要删除它,因为它会导致弃用错误。
    • 将它与 Webpack 4+ 一起使用,它就像一个魅力。实现起来非常简单
    【解决方案4】:

    这是我的食谱,来自这个问题的其他答案。这利用了WebpackVersionFilePluginexeca,现在对我很有用。

    通过 npm 安装插件:

    npm install webpack-version-file-plugin --save-dev
    npm install execa --save-dev
    

    webpack.config.js:

    const WebpackVersionFilePlugin = require('webpack-version-file-plugin');
    const execa = require('execa');
    
    const gitHash = execa.sync('git', ['rev-parse', '--short', 'HEAD']).stdout;
    const gitNumCommits = Number(execa.sync('git', ['rev-list', 'HEAD', '--count']).stdout);
    const gitDirty = execa.sync('git', ['status', '-s', '-uall']).stdout.length > 0;
    
    module.exports = {
    // ... snip ...
    plugins: [
        new WebpackVersionFilePlugin({
            packageFile: path.join(__dirname, 'package.json'),
            template: path.join(__dirname, 'version.ejs'),
            outputFile: path.join('build/ts/', 'version.json'),
            extras: {
                'githash': gitHash,
                'gitNumCommits': gitNumCommits,
                'timestamp': Date.now(),
                'dirty': gitDirty
            }
        }),
    // ... snip ...
    

    version.ejs(在项目根目录中):

    {
        "name":       "<%= package.name %>",
        "buildDate":  <%= extras.timestamp %>,
        "version":    "<%= package.version %>",
        "numCommits": <%= extras.gitNumCommits %>,
        "hash":       "<%= extras.githash %>",
        "dirty":      <%= extras.dirty %>
    }
    

    到目前为止,运行它会在build/ts 中为我们获取一个带有以下内容的 version.json 文件:

    {
        "name":       "app name from package.json",
        "buildDate":  1518774257225,
        "version":    "2.0.1",
        "numCommits": 148,
        "hash":       "5a74b7a",
        "dirty":      false
    }
    

    dirty 标志指示构建是否包含未提交或未跟踪的更改。

    我使用 TypeScript,所以下面介绍如何将 JSON 文件获取到我的 TypeScript 代码中。如果您没有 TypeScript,我们仍然将问题简化为读取 JSON 文件。 :-)

    app.ts:

    import * as appVersionJson from './version.json';
    
    export const appVersion: AppVersion = <any>appVersionJson;
    
    export interface AppVersion {
        /** application name as specified in package.json */
        readonly name: string;
    
        /** build timestamp in milliseconds since the epoch */
        readonly buildDate: number;
    
        /** application version as specified in package.json */
        readonly version: string;
    
        /** number of commits in the Git repo */
        readonly numCommits: number;
    
        /** latest Git commit hash */
        readonly hash: string;
    
        /** flag is set when uncommitted or untracked changes are present in the workspace */
        readonly dirty: boolean;
    }
    
    // ...snip...
    // now just use it in methods, for example:
    appVersion.version + '.' + appVersion.numCommits + ' (' + appVersion.hash + ')'
    

    好的 - 希望这能为如何在代码中提供良好的内部版本号信息提供更多线索。顺便说一句,npm version 是提高版本号的好方法,当像这样工作时。

    【讨论】:

      【解决方案5】:

      从 git 和 npm (package.json) 的角度来看,我分发了两个具有内部版本号的文件。我仍然想将它拉到我的 index.template.html 中的元标记中,但还没有弄清楚(如何从文件内容或 cmd 输出中进行定义?)。

      对于 git,我使用 webpack-shell-plugin 用 git 信息制作一个文件:

      const WebpackVersionFilePlugin = require('webpack-version-file-plugin');
      plugins: [
      new WebpackShellPlugin({
            onBuildStart: [
              'git name-rev --name-only HEAD > dist/gitversion.txt',
              'git rev-list HEAD --count >> dist/gitversion.txt',
              'git rev-parse HEAD >> dist/gitversion.txt']
          }),
      

      对于 npm,我将 npm version 命令(“npm version patch/minor/major”)添加到 (1) 确保 git 中没有未完成的未提交更改 - 如果有任何未提交的更改,它会失败并且 (2) 更新包.json 版本并将其签入 git。

        "scripts": {
          "build": "npm run lint && npm run init && npm version patch && webpack --config webpack.config.js",
      

      然后,我使用文档不完善、可能有问题的 WebpackVersionFilePlugin 分发它。

      const WebpackVersionFilePlugin = require('webpack-version-file-plugin');
      new WebpackVersionFilePlugin({
            packageFile:path.join(__dirname, 'package.json'),
            outputFile: path.join('./dist/', 'version.json')
          }),
      

      在顶层目录中使用这个模板:

      {
        "version" : {
          "name":      "<% package.name %>",
          "buildDate": "<%= currentTime %>",
          "version":   "<%= package.version %>"
        }
      }
      

      “package.name”和“name”都不起作用。

      结果是我的 ./dist/目录中有两个文件。 gitversion.txt(分支、提交、从头开始计数):

      fmwk/feathers
      9cfe791a09d3d748e8120e0628
      51
      

      和version.json:

      {
        "version" : {
          "name":      "",
          "buildDate": "Fri Oct 21 2016 11:10:12 GMT+0800 (PHT)",
          "version":   "0.6.2"
        }
      }
      

      【讨论】:

      • @Micheal Bushe,重新“名称”不起作用,您的 package.json 中有名称吗?
      • 实在看不懂是回答还是提问?你说它不工作或有问题,但不确定你是否让它工作?
      • 名称不起作用的原因是缺少“=”。您的模板中需要有 "name": ""。
      【解决方案6】:

      我无法让它与 TypeScript 一起使用,所以我通过在每次编译时创建一个文件来帮助自己。

      webpack.config.js

      const fs = require('fs'); 
      const path = require('path'); 
      fs.writeFileSync(path.resolve(path.join(__dirname, 'src/version.ts')), 
      `// This file is auto-generated by the build system. 
      const BundleVersion = "${ new Date().toISOString().substr(0, 10) }"; 
      export default BundleVersion; 
      `); 
      

      那我就 import BundleVersion from './version'; 并确保它实际上在某处使用(console.log 或将其暴露在某处),因此它不会被树摇晃,就是这样,在编译时创建的包中的时间戳(或版本)(直接从这里开始)读取 package.json 并在需要时使用包版本)。

      【讨论】:

        【解决方案7】:

        我制作了一个 webpack 加载器,它将构建信息注入到一个自动生成的文件中。你可以找到它on npm

        安装后,您可以像这样使用它:

        import buildinfo from "!webpack-plugin-buildinfo?gitHashShort&time!";
        console.log(
            `MyCoolProject v${buildinfo.gitHashShort} compiled at ${new Date(
                buildinfo.time
            ).toISOString()}`
        );
        

        欲了解更多信息,请访问the github repo

        【讨论】:

          【解决方案8】:

          如果您可以使用 构建版本 而不是 代码版本,您可以在构建期间获取构建日期并将其用于您的版本:

          webpack.config.js

          const now = new Date()
          const buildDate = `${now.getFullYear()}-${now.getMonth()}-${now.getDate()}`
          
          
          module.exports = {
            ...
            plugins: [
              new webpack.EnvironmentPlugin({'BUILD_DATE': buildDate}),
            ]
            ...
          }
          

          然后您可以在代码中的任何地方进行操作

          console.log(process.env.BUILD_DATE)
          

          这可能就足够了,不需要类型定义、修改 CI 等...

          【讨论】:

            猜你喜欢
            • 2011-03-27
            • 2012-06-08
            • 1970-01-01
            • 2014-11-15
            • 1970-01-01
            • 2014-10-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多