Skip to content

Refactor of Dispatcher Plan of Success

This is a followup issue to https://gitlab.com/gitlab-org/gitlab-ce/issues/37792. Thanks @mikegreiling, @okoghenun, @ClemMakesApps and @iamphill for the idea.

The plan is to refactor the dispatcher.js file with the following steps which will allow us to merge incrementally and not create a huge MR.

  1. The end goal is to have a file structure which is javascripts/pages/route/to/file. In order to achieve this we have webpack dynamically route us to the right place based on the entry point. But as a first step we need the right file structure. So we will move the files.
  2. Using the user profile as an example: The user profile has the route: users:show. Create app/assets/javascripts/pages/users/show.
  3. In that directory you will create an index.js.
  4. Figure out what imports were needed for the users:show... Check the switch statement. You can see three imports were needed. https://gitlab.com/gitlab-org/gitlab-ce/issues/41341
  5. Cookies UserTabs, and UserCallout. In the dispatcher at the top of the file is where the imports are located. See if they are being used for anything else in this file. If not, remove them from here. If yes, leave them alone.
  6. Move your files from the root of the javascript directory to the new directory.
  7. Something like $ mv app/assets/javascripts/users/* app/assets/javascripts/pages/users/show.
  8. In your index.js, add imports for the files. You will need to update the import statement. Something like '~/user_callout'.
  9. At this point your directory structure will look something like this: https://imgur.com/a/SMT45.
  10. Create an export default () => { to call anything that was normally happening in that switch statement.
  11. Add the rest of the file in the index.js.
  12. In the original switch statement you can now import the index. import('./pages/users/show').then(m => m.default()).catch(fail);
  13. The dispatcher will have a fail somewhere in there. Something like: const fail = () => Flash('failed to load dynamic module');
  14. The previous step will move all the files to the right location and everything should still work as expected. That way you can take one route at a time and refactor and submit an MR. Once this step is in place, we will take the step to create entry points in webpack based on the route and we can remove the dispatcher completely.

The following is a list of routes we need to refactor. Please put your name next to the route to claim it. Check it off once an MR is merged and list the MR next to the item once an MR is available.

cc @mikegreiling (feel free to edit this as needed to make it more accurate).

Assignees

admin:*: @iamphill https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/16315
ci:*: @okoghenun
dashboard:*: @ClemMakesApps
explore:*: @jschatz1
groups:* (! milestones): @psimyn
groups:milestones:*: @iamphill
help:*: @okoghenun
import:fogbugz:new_user_map: @iamphill
profiles:*: @okoghenun
projects:a*: @jschatz1
projects:b*: @ClemMakesApps
projects:c*: @psimyn
projects:(e*, f*, i*): @psimyn
projects:l* : @jschatz1
projects:merge_requests:* : @ClemMakesApps
projects:milestones:* : @iamphill
projects:(n*, p*): @okoghenun
projects:(r*, s): @jschatz1
search:*: @ClemMakesApps
sessions:*: @ClemMakesApps
snippets:*: @jschatz1
users:show: @iamphill


EE Dispatcher


For the following templates:

  1. Remove the bundle tag.
  2. If it's common_* leave it in for now. e.g common_vue or common_d3
  3. Go into the dispatcher see if there is a route already. If so find the index.js file in the pages directory and import that bundle.
  4. Make a MR for CE and EE.
app/views/dashboard/groups/index.html.haml
    4  = render 'dashboard/groups_head'
    5  
    6: = webpack_bundle_tag 'common_vue'
    7: = webpack_bundle_tag 'groups'
    8  
    9  - if params[:filter].blank? && @groups.empty?
app/views/explore/groups/index.html.haml
    3  - header_title  "Groups", dashboard_groups_path
    4  
    5: = webpack_bundle_tag 'common_vue'
    6: = webpack_bundle_tag 'groups'
    7  
    8  - if current_user

app/views/groups/_children.html.haml: @iamphill 
    1: = webpack_bundle_tag 'common_vue'
    2: = webpack_bundle_tag 'groups'
    3  
    4  .js-groups-list-holder
app/views/groups/issues.html.haml: @okoghenun  
    5  
    6  - content_for :page_specific_javascripts do
    7:   = webpack_bundle_tag 'common_vue'
    8:   = webpack_bundle_tag 'filtered_search'
    9  
   10  - if group_issues_exists
app/views/groups/merge_requests.html.haml: @okoghenun 
    2  
    3  - content_for :page_specific_javascripts do
    4:   = webpack_bundle_tag 'common_vue'
    5:   = webpack_bundle_tag 'filtered_search'
    6  
    7  - if @group_merge_requests.empty?
app/views/help/index.html.haml: @jschatz1 
    1: = webpack_bundle_tag 'docs'
    2  
    3  %div
app/views/help/show.html.haml: @jschatz1 
    1  - content_for :page_specific_javascripts do
    2:   = webpack_bundle_tag 'help'
    3  - page_title @path.split("/").reverse.map(&:humanize)
    4  .documentation.wiki.prepend-top-default
app/views/help/ui.html.haml: @jschatz1 
    2  - lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fermentum nisi sapien, non consequat lectus aliquam ultrices. Suspendisse sodales est euismod nunc condimentum, a consectetur diam ornare."
    3  - content_for :page_specific_javascripts do
    4:   = webpack_bundle_tag('ui_development_kit')
    5  
    6  .gitlab-ui-dev-kit
app/views/ide/index.html.haml: @mikegreiling  ~blocked 
    3  
    4  - content_for :page_specific_javascripts do
    5:   = webpack_bundle_tag 'common_vue'
    6:   = webpack_bundle_tag 'ide', force_same_domain: true
    7  
    8  #ide.ide-loading{ data: {"empty-state-svg-path" => image_path('illustrations/multi_file_editor_empty.svg')} }
app/views/import/gitlab_projects/new.html.haml: @jschatz1   
    2  - header_title "Projects", root_path
    3  - content_for :page_specific_javascripts do
    4:   = webpack_bundle_tag 'project_import_gl'
    5  
    6  %h3.page-title
app/views/profiles/accounts/show.html.haml: @jschatz1 
  105  
  106  - content_for :page_specific_javascripts do
  107:   = webpack_bundle_tag('account')
  108  
app/views/projects/blob/show.html.haml: @jschatz1 
    5  
    6  - content_for :page_specific_javascripts do
    7:   = webpack_bundle_tag 'blob'
    8  
    9  = render 'projects/last_push'
app/views/projects/environments/metrics.html.haml: @psimyn 
    2  - page_title "Metrics for environment", @environment.name
    3  - content_for :page_specific_javascripts do
    4:   = webpack_bundle_tag 'common_vue'
    5:   = webpack_bundle_tag 'common_d3'
    6:   = webpack_bundle_tag 'monitoring'
    7  
    8  .prometheus-container{ class: container_class }
app/views/projects/graphs/charts.html.haml: @jschatz1 
    2  - page_title "Charts"
    3  - content_for :page_specific_javascripts do
    4:   = webpack_bundle_tag('common_d3')
    5:   = webpack_bundle_tag('graphs')
    6:   = webpack_bundle_tag('graphs_charts')
    7  
    8  .repo-charts{ class: container_class }
app/views/projects/graphs/show.html.haml: @jschatz1 
    2  - page_title _('Contributors')
    3  - content_for :page_specific_javascripts do
    4:   = webpack_bundle_tag('common_d3')
    5:   = webpack_bundle_tag('graphs')
    6:   = webpack_bundle_tag('graphs_show')
    7  
    8  .js-graphs-show{ class: container_class, 'data-project-graph-path': project_graph_path(@project, current_ref, format: :json) }
app/views/projects/issues/index.html.haml: @okoghenun  
    6  
    7  - content_for :page_specific_javascripts do
    8:   = webpack_bundle_tag 'common_vue'
    9:   = webpack_bundle_tag 'filtered_search'
   10  
   11  = content_for :meta_tags do
app/views/projects/issues/show.html.haml: @jschatz1 
    7  
    8  - content_for :page_specific_javascripts do
    9:   = webpack_bundle_tag 'common_vue'
   10:   = webpack_bundle_tag 'notes'
   11  
   12  - can_update_issue = can?(current_user, :update_issue, @issue)
app/views/projects/jobs/show.html.haml: @ClemMakesApps  
  109  
  110  - content_for :page_specific_javascripts do
  111:   = webpack_bundle_tag('common_vue')
  112:   = webpack_bundle_tag('job_details')
  113  
app/views/projects/merge_requests/_how_to_merge.html.haml: @ClemMakesApps  
    1  - content_for :page_specific_javascripts do
    2:   = webpack_bundle_tag('how_to_merge')
    3  
    4  #modal_merge_info.modal
app/views/projects/merge_requests/index.html.haml: @okoghenun  
    8  
    9  - content_for :page_specific_javascripts do
   10:   = webpack_bundle_tag 'common_vue'
   11:   = webpack_bundle_tag 'filtered_search'
   12  
   13  = render 'projects/last_push'
app/views/projects/merge_requests/show.html.haml: @ClemMakesApps  
    6  - page_card_attributes @merge_request.card_attributes
    7  - content_for :page_specific_javascripts do
    8:   = webpack_bundle_tag('common_vue')
    9:   = webpack_bundle_tag('diff_notes')
   10  
   11  .merge-request{ data: { mr_action: j(params[:tab].presence || 'show'), url: merge_request_path(@merge_request, format: :json), project_path: project_path(@merge_request.project) } }
   ..
   26  
   27      - content_for :page_specific_javascripts do
   28:       = webpack_bundle_tag 'vue_merge_request_widget'
   29  
   30      .content-block.content-block-small.emoji-list-container
app/views/projects/pipeline_schedules/_form.html.haml: @iamphill  
    1  - content_for :page_specific_javascripts do
    2:   = webpack_bundle_tag 'common_vue'
    3:   = webpack_bundle_tag 'schedule_form'
    4  
    5  = form_for [@project.namespace.becomes(Namespace), @project, @schedule], as: :schedule, html: { id: "new-pipeline-schedule-form", class: "form-horizontal js-pipeline-schedule-form" } do |f|
app/views/projects/pipeline_schedules/index.html.haml: @iamphill  
    2  
    3  - content_for :page_specific_javascripts do
    4:   = webpack_bundle_tag 'common_vue'
    5:   = webpack_bundle_tag 'schedules_index'
    6  
    7  - @no_container = true
app/views/projects/pipelines/charts/_pipeline_times.haml: @jschatz1 
    1  - content_for :page_specific_javascripts do
    2:   = webpack_bundle_tag('pipelines_times')
    3  
    4  %div
app/views/projects/pipelines/charts/_pipelines.haml: @jschatz1 
    1  - content_for :page_specific_javascripts do
    2:   = webpack_bundle_tag('pipelines_charts')
    3  
    4  %h4= _("Pipelines charts")
app/views/projects/pipelines/show.html.haml: @jschatz1 
   13  
   14  - content_for :page_specific_javascripts do
   15:   = webpack_bundle_tag('common_vue')
   16:   = webpack_bundle_tag('pipelines_details')
   17  
app/views/projects/services/_form.html.haml: @okoghenun  
    1  - content_for :page_specific_javascripts do
    2:   = webpack_bundle_tag('integrations')
    3  
    4  .row.prepend-top-default.append-bottom-default
app/views/projects/services/prometheus/_show.html.haml: @okoghenun  
    1  - content_for :page_specific_javascripts do
    2:   = webpack_bundle_tag('prometheus_metrics')
    3  
    4  .row.prepend-top-default.append-bottom-default.prometheus-metrics-monitoring.js-prometheus-metrics-monitoring
app/views/shared/boards/_show.html.haml: @okoghenun  
    6  
    7  - content_for :page_specific_javascripts do
    8:   = webpack_bundle_tag 'common_vue'
    9:   = webpack_bundle_tag 'filtered_search'
   10:   = webpack_bundle_tag 'boards'
   11  
   12    %script#js-board-template{ type: "text/x-template" }= render "shared/boards/components/board"
app/views/users/show.html.haml: @okoghenun   
    6  - @no_container = true
    7  - content_for :page_specific_javascripts do
    8:   = webpack_bundle_tag 'common_d3'
    9:   = webpack_bundle_tag 'users'
   10  
   11  = content_for :meta_tags do
Edited by Constance Okoghenun