How to modify an UI component by an extension

Unfortunately, you can not modify an UI component XML declaration by the standard way.
So, what are the other methods?

Method 1

You can plug in to the \Magento\Framework\View\Element\UiComponent\Config\FileCollectorInterface::collectFiles() method:

The interface is implemented by the \Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector class

The method returns an array of UI components’ XML files contents.
By default, there is only the single UI compoment XML file: Magento/Ui/view/base/ui_component/etc/definition.xml.

So you can plug in after the method and modify the XML contents, for example:

/**
 * @see \Magento\Framework\View\Element\UiComponent\Config\FileCollectorInterface::collectFiles()
 * https://github.com/magento/magento2/blob/c58d2d/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollectorInterface.php#L19
 * @see \Magento\Framework\View\Element\UiComponent\Config\FileCollector\AggregatedFileCollector::collectFiles()
 * https://github.com/magento/magento2/blob/c58d2d/lib/internal/Magento/Framework/View/Element/UiComponent/Config/FileCollector/AggregatedFileCollector.php#L67-L85
 * @param _FileCollectorInterface $subject
 * @param mixed[] $result
 * @return string
 */
public function afterCollectFiles(_FileCollectorInterface $subject, array $result) {
	return !Settings::s()->enable() ? $result : array_map(function($contents) {
		return str_replace(
			$this->pattern(\Magento\Ui\Component\Form\Element\Wysiwyg::class)
			,$this->pattern(\Dfe\Markdown\UiComponent::class)
			, $contents
		);
	}, $result);
}

Method 2

You can plug in to the \Magento\Framework\View\Element\UiComponent\Processor::register() method and modify the component:

Method 3

You can plug in to the \Magento\Ui\Component\AbstractComponent::prepare() method and modify the component ($this):

An example:

<?php
namespace Dfe\Markdown\Plugin\Ui\Component\Form\Element;
use Dfe\Markdown\Settings;
use Magento\Ui\Component\Form\Element\Wysiwyg as _Wysiwyg;
class Wysiwyg {
	/**
	 * @see \Magento\Ui\Component\Form\Element\Wysiwyg::prepare()
	 * https://github.com/magento/magento2/blob/c58d2d/app/code/Magento/Ui/Component/AbstractComponent.php#L83-L113
	 * @param _Wysiwyg $subject
	 * @return void
	 */
	public function beforePrepare(_Wysiwyg $subject) {
		if (Settings::s()->enable()) {
			/**
			 * 1) https://github.com/magento/magento2/blob/c58d2d/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php#L50
			 * $data['config']['content'] = $editorElement->getElementHtml();
			 * 2) https://github.com/magento/magento2/blob/c58d2d/app/code/Magento/Ui/Component/AbstractComponent.php#L60
			 * $this->_data = array_replace_recursive($this->_data, $data);
			 */
			/** @var array(string => mixed)|null $config */
			$subject['config'] = ['content' => __FILE__] + df_nta($subject['config']);
		}
	}
}

Method 4

You can modify an UI component data here:

$this->wrappedComponent->getData('config') can be:

$this->getData('config') can be:

See also: