We use this way even in 3.x because Sprite’s can be batched. This is probably not important for cocos2d-js canvas rendering. We add a 1x1 pixel texture (with any 2x for hd, etc) that gets packed with our other textures. Wrap it up in a nice little createSpriteRect(color, size) function and then set position/opacity and add as child like you must with any node.
EDIT2:
The DrawNode is still supported in the CocosCreator API, but strangely, it isn’t listed in the API. (I almost used raw bitmap data to implement my own draw node, creating a cc.Texture2D and using initWithData( , , , ), but that was insane)
What happens is that our cc.Node is a logical node and not a renderer node, which is a _ccsg.Node (the old cocos2d-JS cc.Node), there is some information about those preserved objects.
So the trick is just to access the _sgNode object (the renderer node) inside your logical node object (the new Cocos Creator Node).
this.rectangle = new cc.DrawNode();
this.rectangle.drawRect(cc.p(50,50), cc.p(200,300), cc.color(255,0,0,255), 3, cc.color(0,255,0,255));
this.node._sgNode.addChild(this.rectangle);