В последние недели я работаю над программным обеспечением для частного бэк-офиса, построенным на React через create-react-app.

Один из запросов заказчика был:

«Поместите версию программного обеспечения в нижний колонтитул».

Итак, первый вопрос: что такое «версия»? или лучше: что значит «версия»?
Поскольку заказчик - это другая компания, занимающаяся разработкой программного обеспечения, и у него есть зеркало нашего репозитория git, и поскольку я развертываю новую версию программного обеспечения каждые один или два дня, я решил, что версия программного обеспечения - это ша фиксации.

Хорошо, в этот момент я подумал: «Хорошо, братан, мне нужно только поместить последний коммит ша (развернутый) в дурацкий нижний колонтитул, давайте сделаем это по-своему!».

После того, как он показал это решение боссу, он сказал что-то вроде:

Чертовски круто! Вы должны написать об этом сообщение на Medium!

Вот и все, первая запись на Medium.

Причудливое решение:
https://github.com/kentcdodds/babel-plugin-macros ❤️

Макросы Babel - это новая функция Babel, которая обеспечивает преобразование кода без конфигурации. Если вам интересно, вы можете прочитать больше здесь:



В частности, я использовал этот замечательный макрос Babel:



С помощью этого Babel marco вы можете предварительно оценить некоторый js-код узла во время сборки.
Попробуйте представить его как C #define, но в javascript.

Покажи мой код:

import preval from 'preval.macro'
// Get last commit sha (excluding merge)
const version = preval`
const { execSync } = require('child_process')
const rawLog = execSync('git log --no-decorate -n 1 --no-merges', {
  encoding: 'utf-8',
})
module.exports = /commit ([a-z0-9]+)/gi.exec(rawLog)[1]
`
export default version

Объяснение:

Сначала я запускаю команду git, чтобы получить информацию о последней фиксации без слияния:

git log --no-decorate -n 1 --no-merges

Вы можете попробовать это в своем терминале, если вам интересно.

Выбор использования execSync не случаен, потому что «ограничение» этого макроса состоит в том, что выполняемый код должен быть синхронным и честным.

Затем я использовал простое регулярное выражение для извлечения только фиксации sha, вы можете сделать лучше, эта версия вызывает ошибку компиляции, если что-то пойдет не так, не может прочитать что-то неопределенное или подобное дерьмо.

Преимущество этого подхода в том, что версия действительно жестко запрограммирована!
Когда вы создаете приложение, байты, отправляемые в браузер вашего пользователя, выглядят примерно так:

const version = '8ee7903ebe138b3360ca85d8c3cfb0b19629ac55'

Хорошо, на самом деле в реальном мире этот код был перенесен и уменьшен, но это не так серьезно.

Хорошо, теперь для полноты картины замечательный <Footer /> Компонент:

import React from 'react'
import VERSION from '../../version'
export default function Footer() {
 return (
  <div className='Footer'>
    {/* The Footer is not actually only this */}
    <small
      title={VERSION}
      style={{ fontFamily: 'monospace' }}>
      version {VERSION.substr(0, 7)}
    </small>
  </div>
  )
}

В своей настройке я использовал приложение create-response-app, но макросы Babel, и этот подход можно использовать во всех js-приложениях, которые использовали Babel и https://github.com/kentcdodds/babel-plugin-macros.

Это только одно простое решение для случая использования ma, но вы можете начать отсюда и делать другие вещи, например, захватить последний тег git, прочитать версию inpackage.json или что угодно!