Прошло совсем немного времени после релиза 0.3.0, и вот снова минорный релиз - 0.4.0. Да, обратная совместимость снова сломана, но причина для этого, на мой взгляд, хорошая.
Я существенно переработал то, как в коде Rattus ORM используются атрибуты. Те самые, которые types и relations. Если в прошлом релизе все изменения были связаны с названием декораторов и методов, то в этом я сделал упор на то, что для frontend-разработчиков важно, пожалуй, больше всего - размер бандла.
Что было сделано
Я заметил, что даже если вы просто создадите базу данных и добавить всего одну модель, в которой не будет ни одного ключа, в ваш бандл заедут некоторые типы и даже relations. Это наследие Vuex ORM Next.
Так получилось потому, что для проведения некоторых
операций с полями модели нам нужно знать, что именно
перед нами: type, relation, а иногда даже конкретный
type или relation. В Vuex ORM Next это делалось с
помощью проверок instanceof
, а для этого, как известно,
нужно иметь код конкретного класса. В версии 0.4.0
@rattus-orm/core
это исправлено.
Однако это ещё не всё. Если вы не используете декораторы
для описания моделей, вы знаете, что каждый type или
relation - статический метод класса Model
:
export class User extends Model {
static entity = 'user'
static fields () {
return {
id: this.uidField(),
name: this.stringField(''),
age: this.numberField(0)
}
}
}
А это значит, что самый базовый класс всегда тянет в себе все types и relations!
В версии 0.4.0 это также переработано. Теперь для описания поля нужно вызывать не статический метод, а отдельную функцию:
export class User extends Model {
static entity = 'user'
static fields () {
return {
id: createUidField(this),
name: createStringField(this, ''),
age: createNumberField(this, 0)
}
}
}
Минус здесь незначительный: нам нужно передавать в функцию контекст конструктора класса. Во всех методах это всегда первый аргумент, остальные идут в том же порядке, что и раньше.
То же касается и relations - это отдельные функции, первый аргумент которых - контекст конструктора.
Всё это приводит к тому, что мы тянем в бандл только то, что реально используется вашим приложением.
Результаты
Взглянем на результаты. Для сборки файла в этом эксперименте я использую Bun v1.1.30.
Модель без полей
Сперва посмотрим, что мы имеем вот с таким исходным файлом:
import { Model } from '@rattus-orm/core'
class User extends Model {}
Давайте соберём его, используя версию 0.3.0:
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js
size-test-built.js 19.87 KB │ gzip: 5.17 KB │ brotli: 4.61 KB
Мы видим, что размер файла получился 19.87 KB без сжатия и минимальное 4.61 KB сжатый brotli.
Что же получается с версией 0.4.0:
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js
size-test-built.js 12.34 KB │ gzip: 3.77 KB │ brotli: 3.37 KB
Файл уменьшился на 37.8% в несжатом и примерно на 27% в сжатом виде. Выглядит неплохо!
Модель с единственным StringField
Теперь давайте добавим нашей модели свойство name
- это будет
строка.
import { Model } from '@rattus-orm/core'
// v0.3.0
import { StringField } from '@rattus-orm/core/decorators'
// v0.4.0
import { StringField } from '@rattus-orm/core/field-types'
class User extends Model {
@StringField('')
public name: string
}
Соберем с 0.3.0:
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js
size-test-built.js 20.38 KB │ gzip: 5.41 KB │ brotli: 4.82 KB
И с 0.4.0:
$ bun build size-test.ts --minify --outfile size-test-built.js > /dev/null \
$ && npx tiny-file-size --gzip --brotli ./size-test-built.js
size-test-built.js 13.51 KB │ gzip: 4.21 KB │ brotli: 3.77 KB
Файл меньше примерно на 33% в несжатом и на 22% в сжатом виде.
В итоге, грубо говоря, мы видим уменьшение бандла приблизительно на треть. Естественно, если вы используете все типы данных и все связи, вы получите бандл того же размера, что получится в версии 0.3.0. Однако цель этого релиза - позаботится о тех, кто использует не всё, а только определенные части Rattus ORM.