Как я могу ввести номер сборки с веб-пакетом?

Я хотел бы добавить номер сборки и информацию о версии в мой проект, так как он собран с помощью веб-пакета. Например, чтобы мой код мог делать что-то вроде:

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

Каков был бы лучший способ произвести это build-info модуль во время сборки?

10 ответов

Вы можете использовать DefinePlugin, который сделает вашу информацию о сборке встроенной в ваш код:

конфиг

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

Код приложения

console.log(__VERSION__);

Я бы сделал проще, просто используйте npm version patch (npm-версия) (плагин не требуется)

package.json (пример версии пути перед сборкой)

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

Поэтому, когда вы бежите npm run build это исправит версию (1.0.0 в 1.0.1 в вашем package.json)


Бонус: вы также можете добавить это в свой конфиг (пример config/prod.env.js)

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

Тогда вы можете использовать process.env.VERSION где-нибудь в вашем нашем JS

Есть плагин для автоматической вставки версии из package.json. Он может вставлять его в html,css,js как комментарий, но также как значение по специальному тегу https://www.npmjs.com/package/webpack-auto-inject-version

Как:

Прежде всего, вы должны добавить его в свой проект:

npm i webpack-auto-inject-version

Затем вам нужно настроить конфигурацию вашего веб-пакета:

var WebpackAutoInject = require('webpack-auto-inject-version');

module.exports = {
    plugins: [
        new WebpackAutoInject()
    ]
}

Поскольку вы хотите внедрить его в javascript, вы должны добавить тег в свой файл javascript (который будет изменен на версию во время компиляции веб-пакета)

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

Авто увеличение:

Вы можете настроить его на автоматическое увеличение версии прямо из веб-пакета:

webpack --other-webpack-settings --major

webpack --other-webpack-settings -- minor

webpack --other-webpack-settings --patch

Где --other-webpack-settings соответствует вашим пользовательским аргументам строки. Упрощение - вам нужно указывать --major, --minor или --patch всякий раз, когда вы хотите автоматически увеличить версию.

Вот мой рецепт, полученный из других ответов на этот вопрос. Это использует WebpackVersionFilePlugin и execa и отлично работает для меня прямо сейчас.

Установите плагины через 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 %>
}

До сих пор, запустив это, мы получаем файл version.json в build/ts с этим содержанием:

{
    "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 - это хороший способ увеличить номера версий при такой работе.

У меня есть два файла, которые я распространяю с номером сборки с точки зрения git и npm (package.json). Я все еще хотел бы вставить это в свой index.template.html в метатеге, но пока не понял этого (как я могу сделать DEFINE из содержимого файла или из вывода 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 ("патч версии npm /minor/major"), чтобы (1) убедиться, что в git нет незавершенных изменений - она ​​завершится неудачей, если есть, и (2) обновить версию package.json. и проверить это в мерзавце.

  "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/directory. 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"
  }
}

Если вы можете обойтись версией сборки , а не версией кода , вы можете получить дату сборки во время сборки и использовать ее для своей версии:

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 и т.д.

Если вы хотите использовать текущую дату и время, вот самый простой способ сделать это.

      const VERSION = "1";
const autoIncrementedVersion = `${VERSION}.${new Date().getTime()}`;

module.exports = {
    plugins: [
        new webpack.BannerPlugin({
            banner: `Author: Your Name
Date: ${new Date().toLocaleDateString()}
Project: Your Project Name
Version: ${autoIncrementedVersion}
License: (c) ${new Date().getFullYear()} Your Name
Description: Your project description
`
        }),
    ],
};

Вот увидишь:

      /*!
 * Author: Your Name
 * Date: 5/3/2023
 * Project: Your Project Name
 * Version: 1.1683179722396
 * License: (c) 2023 Your Name
 * Description: Your project description
 *
 */

Я сделал загрузчик веб-пакетов, который вставляет информацию о сборке в автоматически сгенерированный файл. Вы можете найти его на npm.

После установки вы можете использовать его так:

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

Для получения дополнительной информации посетите репозиторий github.

Мне не удалось заставить это работать с 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 и при необходимости использовать версию пакета).

Если вы не против вставить информацию о сборке в виде глобальной переменной прямо на страницу, то самым простым подходом может быть использование HtmlWebpackPluginвы, вероятно, уже используете в своей конфигурации веб-пакета.

В этой статье объясняется, как вводить данные в файл во время сборки. Вы можете добавить произвольные данные в плагин в вашем webpack.config.jsтакой файл:

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

в index.htmlфайл шаблона, вы можете добавить escape-последовательность для доступа к этим данным и вставить их ( JSON.stringify()выводит данные как литерал объекта, который будет оцениваться как часть скрипта):

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

Затем вы можете получить доступ к этой глобальной переменной из любого места в своем коде, например console.log("Built at ", BUILD_INFO.time);

В моем случае я просто хотел включить временную метку сборки в качестве комментария в файл HTML. Поэтому я добавил метку времени к объекту плагина и установил minify: falseчтобы предотвратить удаление комментариев (и это также предотвращает вывод HTML в одну строку).

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

Затем эта метка времени была введена в HTML-комментарий следующим образом:

      <!-- Built at <%= htmlWebpackPlugin.options.buildTime %> -->
Другие вопросы по тегам