diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
index faa6d0d..fcceaaa 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php
@@ -319,7 +319,7 @@ public function getPluginCollections() {
     $configurations = [];
     foreach ($this->getComponents() as $field_name => $configuration) {
       if (!empty($configuration['type']) && ($field_definition = $this->getFieldDefinition($field_name))) {
-        $configurations[$configuration['type']] = $configuration + [
+        $configurations[$field_name] = $configuration + [
           'field_definition' => $field_definition,
           'form_mode' => $this->mode,
         ];
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
index 74b15b6..88b6bba 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
@@ -290,7 +290,7 @@ public function getPluginCollections() {
     $configurations = [];
     foreach ($this->getComponents() as $field_name => $configuration) {
       if (!empty($configuration['type']) && ($field_definition = $this->getFieldDefinition($field_name))) {
-        $configurations[$configuration['type']] = $configuration + [
+        $configurations[$field_name] = $configuration + [
           'field_definition' => $field_definition,
           'view_mode' => $this->originalMode,
         ];
diff --git a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldFormatter/TestFieldDynamicDependenciesFormatter.php b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldFormatter/TestFieldDynamicDependenciesFormatter.php
new file mode 100644
index 0000000..da9e272
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldFormatter/TestFieldDynamicDependenciesFormatter.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Drupal\field_test\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Plugin implementation of the 'field_test_dynamic_dependencies' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "field_test_dynamic_dependencies",
+ *   label = @Translation("Dynamic dependencies test"),
+ *   field_types = {
+ *     "test_field",
+ *   },
+ *   weight = 0
+ * )
+ */
+class TestFieldDynamicDependenciesFormatter extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'dependent_module' => NULL,
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $element['dependent_module'] = [
+      '#title' => t('Module'),
+      '#type' => 'textfield',
+      '#default_value' => $this->getSetting('dependent_module'),
+    ];
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = [];
+    $summary[] = t('@setting: @value', ['@setting' => 'dependent_module', '@value' => $this->getSetting('dependent_module')]);
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = [];
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = ['#markup' => 'test'];
+    }
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    $dependencies = parent::calculateDependencies();
+    $dependencies['module'][] = $this->getSetting('dependent_module');
+    return $dependencies;
+  }
+
+}
diff --git a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidgetDynamicDependencies.php b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidgetDynamicDependencies.php
new file mode 100644
index 0000000..1aa216b
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidgetDynamicDependencies.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Drupal\field_test\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Form\FormStateInterface;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Plugin implementation of the 'test_field_widget' widget.
+ *
+ * @FieldWidget(
+ *   id = "test_field_widget_dynamic_dependencies",
+ *   label = @Translation("Test widget with dynamic dependencies"),
+ *   field_types = {
+ *     "test_field",
+ *   },
+ *   weight = 0
+ * )
+ */
+class TestFieldWidgetDynamicDependencies extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'dependent_module' => NULL,
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $element['dependent_module'] = [
+      '#title' => t('Module'),
+      '#type' => 'textfield',
+      '#default_value' => $this->getSetting('dependent_module'),
+    ];
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = [];
+    $summary[] = t('@setting: @value', ['@setting' => 'dependent_module', '@value' => $this->getSetting('dependent_module')]);
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    $element += [
+      '#type' => 'textfield',
+      '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : '',
+    ];
+    return ['value' => $element];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
+    return $element['value'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    $dependencies = parent::calculateDependencies();
+    $dependencies['module'][] = $this->getSetting('dependent_module');
+    return $dependencies;
+  }
+
+}
diff --git a/core/modules/field_ui/src/Tests/ManageDisplayTest.php b/core/modules/field_ui/src/Tests/ManageDisplayTest.php
index 7ba011e..3ce547c 100644
--- a/core/modules/field_ui/src/Tests/ManageDisplayTest.php
+++ b/core/modules/field_ui/src/Tests/ManageDisplayTest.php
@@ -92,6 +92,7 @@ public function testFormatterUI() {
       'field_no_settings',
       'field_empty_test',
       'field_empty_setting',
+      'field_test_dynamic_dependencies',
       'field_test_default',
       'field_test_multiple',
       'field_test_with_prepare_view',
@@ -252,6 +253,7 @@ public function testWidgetUI() {
     }, $result);
     $expected_options = [
       'test_field_widget',
+      'test_field_widget_dynamic_dependencies',
       'test_field_widget_multiple',
     ];
     $this->assertEqual($options, $expected_options, 'The expected widget ordering is respected.');
@@ -313,8 +315,17 @@ public function testWidgetUI() {
     $this->drupalGet($manage_display);
 
     // Checks if the select elements contain the specified options.
-    $this->assertFieldSelectOptions('fields[field_test][type]', ['test_field_widget', 'test_field_widget_multiple']);
-    $this->assertFieldSelectOptions('fields[field_onewidgetfield][type]', ['test_field_widget']);
+    $expected_options_multiple = [
+      'test_field_widget',
+      'test_field_widget_dynamic_dependencies',
+      'test_field_widget_multiple',
+    ];
+    $this->assertFieldSelectOptions('fields[field_test][type]', $expected_options_multiple);
+    $expected_options_single = [
+      'test_field_widget',
+      'test_field_widget_dynamic_dependencies',
+    ];
+    $this->assertFieldSelectOptions('fields[field_onewidgetfield][type]', $expected_options_single);
 
     // Ensure that fields can be hidden directly by changing the region.
     $this->assertFieldByName('fields[field_test][region]', 'content');
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
index 4a0e533..c07efae 100644
--- a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
+++ b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTest.php
@@ -11,10 +11,7 @@
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Entity\Entity\EntityViewMode;
-use Drupal\field\Entity\FieldConfig;
-use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\node\Entity\NodeType;
-use Drupal\KernelTests\KernelTestBase;
 use Drupal\user\Entity\Role;
 
 /**
@@ -22,7 +19,7 @@
  *
  * @group field_ui
  */
-class EntityDisplayTest extends KernelTestBase {
+class EntityDisplayTest extends EntityDisplayTestBase {
 
   /**
    * Modules to install.
@@ -39,14 +36,21 @@ protected function setUp() {
   }
 
   /**
-   * Tests basic CRUD operations on entity display objects.
+   * Return a commonly-used test display for a test entity.
    */
-  public function testEntityDisplayCRUD() {
-    $display = EntityViewDisplay::create([
+  protected function getDefaultTestDisplay() {
+    return EntityViewDisplay::create([
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
       'mode' => 'default',
     ]);
+  }
+
+  /**
+   * Tests basic CRUD operations on entity display objects.
+   */
+  public function testEntityDisplayCRUD() {
+    $display = $this->getDefaultTestDisplay();
 
     $expected = [];
 
@@ -118,11 +122,7 @@ public function testEntityDisplayCRUD() {
    * Test sorting of components by name on basic CRUD operations
    */
   public function testEntityDisplayCRUDSort() {
-    $display = EntityViewDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ]);
+    $display = $this->getDefaultTestDisplay();
     $display->setComponent('component_3');
     $display->setComponent('component_1');
     $display->setComponent('component_2');
@@ -210,24 +210,9 @@ public function testExtraFieldComponentInitialInvalidConfig() {
    */
   public function testFieldComponent() {
     $field_name = 'test_field';
-    // Create a field storage and a field.
-    $field_storage = FieldStorageConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'type' => 'test_field'
-    ]);
-    $field_storage->save();
-    $field = FieldConfig::create([
-      'field_storage' => $field_storage,
-      'bundle' => 'entity_test',
-    ]);
-    $field->save();
+    list($field_storage, ) = $this->createField($field_name);
 
-    $display = EntityViewDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ]);
+    $display = $this->getDefaultTestDisplay();
 
     // Check that providing no options results in default values being used.
     $display->setComponent($field_name);
@@ -270,6 +255,13 @@ public function testFieldComponent() {
   }
 
   /**
+   * Tests the dependencies of field components within an entity display object.
+   */
+  public function testMultipleFieldComponentDependencies() {
+    $this->multipleFieldComponentDependenciesHelper('field_test_dynamic_dependencies');
+  }
+
+  /**
    * Tests the behavior of a field component for a base field.
    */
   public function testBaseFieldComponent() {
@@ -356,26 +348,12 @@ public function testDeleteBundle() {
    */
   public function testDeleteField() {
     $field_name = 'test_field';
-    // Create a field storage and a field.
-    $field_storage = FieldStorageConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'type' => 'test_field'
-    ]);
-    $field_storage->save();
-    $field = FieldConfig::create([
-      'field_storage' => $field_storage,
-      'bundle' => 'entity_test',
-    ]);
-    $field->save();
+    list(, $field) = $this->createField($field_name);
 
     // Create default and teaser entity display.
     EntityViewMode::create(['id' => 'entity_test.teaser', 'targetEntityType' => 'entity_test'])->save();
-    EntityViewDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ])->setComponent($field_name)->save();
+    $this->getDefaultTestDisplay()
+      ->setComponent($field_name)->save();
     EntityViewDisplay::create([
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
@@ -405,24 +383,10 @@ public function testOnDependencyRemoval() {
     $this->enableModules(['field_plugins_test']);
 
     $field_name = 'test_field';
-    // Create a field.
-    $field_storage = FieldStorageConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'type' => 'text'
-    ]);
-    $field_storage->save();
-    $field = FieldConfig::create([
-      'field_storage' => $field_storage,
-      'bundle' => 'entity_test',
-    ]);
-    $field->save();
+    $this->createField($field_name, 'text');
 
-    EntityViewDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ])->setComponent($field_name, ['type' => 'field_plugins_test_text_formatter'])->save();
+    $this->getDefaultTestDisplay()
+      ->setComponent($field_name, ['type' => 'field_plugins_test_text_formatter'])->save();
 
     // Check the component exists and is of the correct type.
     $display = entity_get_display('entity_test', 'entity_test', 'default');
@@ -446,13 +410,9 @@ public function testOnDependencyRemoval() {
   public function testEntityDisplayInvalidateCacheTags() {
     $cache = \Drupal::cache();
     $cache->set('cid', 'kittens', Cache::PERMANENT, ['config:entity_view_display_list']);
-    $display = EntityViewDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ]);
-    $display->setComponent('kitten');
-    $display->save();
+    $this->getDefaultTestDisplay()
+      ->setComponent('kitten')
+      ->save();
     $this->assertFalse($cache->get('cid'));
   }
 
@@ -523,16 +483,7 @@ public function testComponentDependencies() {
 
     // Create a field of type 'test_field' attached to 'entity_test'.
     $field_name = Unicode::strtolower($this->randomMachineName());
-    FieldStorageConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'type' => 'test_field',
-    ])->save();
-    FieldConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'bundle' => 'entity_test',
-    ])->save();
+    $this->createField($field_name);
 
     // Create a new form display without components.
     /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityDisplayTestBase.php b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTestBase.php
new file mode 100644
index 0000000..78329ab
--- /dev/null
+++ b/core/modules/field_ui/tests/src/Kernel/EntityDisplayTestBase.php
@@ -0,0 +1,87 @@
+<?php
+
+namespace Drupal\Tests\field_ui\Kernel;
+
+use Drupal\Core\Entity\Display\EntityDisplayInterface;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Base class for testing the entity display configuration entities.
+ *
+ * @group field_ui
+ */
+abstract class EntityDisplayTestBase extends KernelTestBase {
+
+  /**
+   * Return a commonly-used test display for a test entity.
+   *
+   * @return EntityDisplayInterface
+   */
+  abstract protected function getDefaultTestDisplay();
+
+  /**
+   * Create a test field storage and field.
+   *
+   * @param string $field_name
+   *   The field name.
+   * @param string $type
+   *   The type of field to create. Defaults to 'test_field'.
+   *
+   * @return array
+   *   An array containing the field storage and field entities.
+   */
+  protected function createField($field_name, $type = 'test_field') {
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => $field_name,
+      'entity_type' => 'entity_test',
+      'type' => $type,
+    ]);
+    $field_storage->save();
+    $field = FieldConfig::create([
+      'field_storage' => $field_storage,
+      'bundle' => 'entity_test',
+    ]);
+    $field->save();
+
+    return [
+      $field_storage,
+      $field,
+    ];
+  }
+
+  /**
+   * Tests the dependencies of field components within an entity display object.
+   *
+   * @param $type
+   *   A formatter or widget ID to use that has dynamic dependencies.
+   */
+  protected function multipleFieldComponentDependenciesHelper($type) {
+    // Set up two field components, each dependent on different arbitrary
+    // modules that should not already be dependencies otherwise.
+    $dependent_fields = [
+      'test_field' => 'action',
+      'test_field_2' => 'aggregrator',
+    ];
+    foreach ($dependent_fields as $field_name => $dependency) {
+      $this->createField($field_name);
+    }
+
+    // Now that the fields exist, set up the display.
+    $display = $this->getDefaultTestDisplay();
+    foreach ($dependent_fields as $field_name => $dependency) {
+      $display->setComponent($field_name, [
+        'type' => $type,
+        'weight' => 0,
+        'settings' => [
+          'dependent_module' => $dependency,
+        ],
+      ]);
+    }
+
+    $dependencies = $display->calculateDependencies()->getDependencies();
+    $this->assertArraySubset(array_values($dependent_fields), $dependencies['module']);
+  }
+
+}
diff --git a/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php b/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
index 09d2a20..1f5bd44 100644
--- a/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
+++ b/core/modules/field_ui/tests/src/Kernel/EntityFormDisplayTest.php
@@ -4,16 +4,13 @@
 
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Entity\Entity\EntityFormMode;
-use Drupal\field\Entity\FieldConfig;
-use Drupal\field\Entity\FieldStorageConfig;
-use Drupal\KernelTests\KernelTestBase;
 
 /**
  * Tests the entity display configuration entities.
  *
  * @group field_ui
  */
-class EntityFormDisplayTest extends KernelTestBase {
+class EntityFormDisplayTest extends EntityDisplayTestBase {
 
   /**
    * Modules to install.
@@ -27,6 +24,17 @@ protected function setUp() {
   }
 
   /**
+   * Return a commonly-used test display for a test entity.
+   */
+  protected function getDefaultTestDisplay() {
+    return EntityFormDisplay::create([
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'mode' => 'default',
+    ]);
+  }
+
+  /**
    * Tests entity_get_form_display().
    */
   public function testEntityGetFromDisplay() {
@@ -50,25 +58,10 @@ public function testEntityGetFromDisplay() {
    * Tests the behavior of a field component within an EntityFormDisplay object.
    */
   public function testFieldComponent() {
-    // Create a field storage and a field.
     $field_name = 'test_field';
-    $field_storage = FieldStorageConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'type' => 'test_field'
-    ]);
-    $field_storage->save();
-    $field = FieldConfig::create([
-      'field_storage' => $field_storage,
-      'bundle' => 'entity_test',
-    ]);
-    $field->save();
+    list($field_storage, ) = $this->createField($field_name);
 
-    $form_display = EntityFormDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ]);
+    $form_display = $this->getDefaultTestDisplay();
 
     // Check that providing no options results in default values being used.
     $form_display->setComponent($field_name);
@@ -116,6 +109,13 @@ public function testFieldComponent() {
   }
 
   /**
+   * Tests the dependencies of field components within an entity display object.
+   */
+  public function testMultipleFieldComponentDependencies() {
+    $this->multipleFieldComponentDependenciesHelper('test_field_widget_dynamic_dependencies');
+  }
+
+  /**
    * Tests the behavior of a field component for a base field.
    */
   public function testBaseFieldComponent() {
@@ -181,26 +181,12 @@ public function testBaseFieldComponent() {
    */
   public function testDeleteField() {
     $field_name = 'test_field';
-    // Create a field storage and a field.
-    $field_storage = FieldStorageConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'type' => 'test_field'
-    ]);
-    $field_storage->save();
-    $field = FieldConfig::create([
-      'field_storage' => $field_storage,
-      'bundle' => 'entity_test',
-    ]);
-    $field->save();
+    list(, $field) = $this->createField($field_name);
 
     // Create default and compact entity display.
     EntityFormMode::create(['id' => 'entity_test.compact', 'targetEntityType' => 'entity_test'])->save();
-    EntityFormDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ])->setComponent($field_name)->save();
+    $this->getDefaultTestDisplay()
+      ->setComponent($field_name)->save();
     EntityFormDisplay::create([
       'targetEntityType' => 'entity_test',
       'bundle' => 'entity_test',
@@ -230,24 +216,10 @@ public function testOnDependencyRemoval() {
     $this->enableModules(['field_plugins_test']);
 
     $field_name = 'test_field';
-    // Create a field.
-    $field_storage = FieldStorageConfig::create([
-      'field_name' => $field_name,
-      'entity_type' => 'entity_test',
-      'type' => 'text'
-    ]);
-    $field_storage->save();
-    $field = FieldConfig::create([
-      'field_storage' => $field_storage,
-      'bundle' => 'entity_test',
-    ]);
-    $field->save();
+    $this->createField($field_name, 'text');
 
-    EntityFormDisplay::create([
-      'targetEntityType' => 'entity_test',
-      'bundle' => 'entity_test',
-      'mode' => 'default',
-    ])->setComponent($field_name, ['type' => 'field_plugins_test_text_widget'])->save();
+    $this->getDefaultTestDisplay()
+      ->setComponent($field_name, ['type' => 'field_plugins_test_text_widget'])->save();
 
     // Check the component exists and is of the correct type.
     $display = entity_get_form_display('entity_test', 'entity_test', 'default');
