66

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

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

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

4

9 回答 9

76

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

配置

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

应用代码

console.log(__VERSION__);
于 2015-03-25T09:54:22.150 回答
44

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

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

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

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


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

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

然后你可以process.env.VERSION在我们的 JS 中的任何地方使用

更新:或者只是使用 process.env.npm_package_version而不需要包含 package.json

于 2018-06-08T11:03:20.477 回答
22

有一个插件可以从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

where--other-webpack-settings等于您的自定义行参数。简化 - 你需要 att --major--minor或者--patch当你想自动增加一个版本时。

于 2016-10-24T07:19:02.587 回答
15

这是我的食谱,来自这个问题的其他答案。这利用了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 文件。:-)

应用程序.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是增加版本号的好方法。

于 2018-02-16T10:13:02.567 回答
4

从 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) 更新 package.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"
  }
}
于 2016-10-21T03:37:05.620 回答
2

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

webpack.config.js

const now = new Date()
const buildDate = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}`


module.exports = {
  ...
  plugins: [
    new webpack.EnvironmentPlugin({'BUILD_DATE': buildDate}),
  ]
  ...
}

然后在你的代码中的任何地方你都可以做

console.log(process.env.BUILD_DATE)

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

于 2021-12-21T01:34:36.753 回答
1

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

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

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

有关更多信息,请访问github 存储库

于 2020-11-22T01:56:09.657 回答
1

我无法让它与 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 并在需要时使用包版本)。

于 2019-05-11T20:27:54.010 回答
0

If you're okay with inserting the build information as a global variable directly in your index.html page, then the simplest approach may be to leverage the HtmlWebpackPlugin you're probably already using in your webpack config.

This article explains how to inject data into the index.html file at build time. You can add arbitrary data to the plugin in your webpack.config.js file like this:

plugins: [
    ...
    new HtmlWebpackPlugin({
        template: "./src/index.html",
        filename: "index.html",
        info: {
            foo: "bar",
            time: new Date().toLocaleString()
        },
    })
]

In the index.html template file, you can add an escape sequence to access that data and insert it (the JSON.stringify() outputs the data as an object literal that will be evaluated as part of the script):

<script type="text/javascript">
    window.BUILD_INFO = <%= JSON.stringify(htmlWebpackPlugin.options.info, null, 2) %>;
</script>

You can then access that global variable from wherever you want in your code, like console.log("Built at ", BUILD_INFO.time);

For my use case, I just wanted to include a build timestamp as a comment in the HTML file. So I added the timestamp to the plugin object and set minify: false to prevent comments from being stripped (and which also prevents the HTML from being output on a single line).

plugins: [
    ...
    new HtmlWebpackPlugin({
        ...
        minify: false,
        buildTime: new Date().toLocaleString()
    })
]

This timestamp was then injected into an HTML comment like this:

<!-- Built at <%= htmlWebpackPlugin.options.buildTime %> -->
于 2022-02-12T08:09:53.077 回答