you can just create the new Class, with your object inside, and do all actions only with parent of the children, something like this: 
 fabric.RectWithRect = fabric.util.createClass(fabric.Rect, {
      type: 'rectWithRect',
      textOffsetLeft: 0,
      textOffsetTop: 0,
      _prevObjectStacking: null,
      _prevAngle: 0,
      minWidth: 50,
      minHeight: 50,   
      _currentScaleFactorX: 1,
      _currentScaleFactorY: 1,
      _lastLeft: 0,
      _lastTop: 0,
      recalcTextPosition: function () {
           //this.insideRect.setCoords();
           const sin = Math.sin(fabric.util.degreesToRadians(this.angle))
           const cos = Math.cos(fabric.util.degreesToRadians(this.angle))
           const newTop = sin * this.insideRectOffsetLeft + cos * this.insideRectOffsetTop
           const newLeft = cos * this.insideRectOffsetLeft - sin * this.insideRectOffsetTop
           const rectLeftTop = this.getPointByOrigin('left', 'top')
           this.insideRect.set('left', rectLeftTop.x + newLeft)
           this.insideRect.set('top', rectLeftTop.y + newTop)
           this.insideRect.set('width', this.width - 40)
           this.insideRect.set('height', this.height - 40)
           this.insideRect.set('scaleX', this.scaleX)
           this.insideRect.set('scaleY', this.scaleY)
      },
     initialize: function (textOptions, rectOptions) {
       this.callSuper('initialize', rectOptions)
       this.insideRect = new fabric.Rect({
         ...textOptions,
         dirty: false,
         objectCaching: false,
         selectable: false,
         evented: false,
         fragmentType: 'rectWidthRect'
       });
       canvas.bringToFront(this.insideRect);
       this.insideRect.width = this.width - 40;
       this.insideRect.height = this.height - 40;
       this.insideRect.left = this.left + 20;
       this.insideRect.top = this.top + 20;
       this.insideRectOffsetLeft = this.insideRect.left - this.left
       this.insideRectOffsetTop = this.insideRect.top - this.top
       this.on('moving', function(e){
         this.recalcTextPosition();
       })
       this.on('rotating',function(){
         this.insideRect.rotate(this.insideRect.angle + this.angle - this._prevAngle)
         this.recalcTextPosition()
         this._prevAngle = this.angle
       })
       this.on('scaling', function(fEvent){
           this.recalcTextPosition();
       });
       this.on('added', function(){
         this.canvas.add(this.insideRect)
       });
       this.on('removed', function(){
         this.canvas.remove(this.insideRect)
       });
       this.on('mousedown:before', function(){
         this._prevObjectStacking = this.canvas.preserveObjectStacking
         this.canvas.preserveObjectStacking = true
       });
       this.on('deselected', function(){
         this.canvas.preserveObjectStacking = this._prevObjectStacking
       });
     }
 });
and then just add your element to your canvas as usual: 
var rectWithRect = new fabric.RectWithRect(
            {
              fill: "red",
            }, // children rect options
           {
             left:100,
             top:100,
             width: 300,
             height: 100,
             dirty: false,
             objectCaching: false,
             strokeWidth: 0,
             fill: 'blue'
           } // parent rect options
      );
canvas.add(rectWithRect);
by the way, you can use method like this to create nested elements, text with background and other.
Codesandbox DEMO