Как я могу ввести номер сборки с веб-пакетом?
Я хотел бы добавить номер сборки и информацию о версии в мой проект, так как он собран с помощью веб-пакета. Например, чтобы мой код мог делать что-то вроде:
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 %> -->