diff options
author | Jacob Schatz <jschatz@gitlab.com> | 2018-02-02 19:21:52 +0000 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2018-02-02 19:21:52 +0000 |
commit | ee600a84d29d1ecbfdb3e9cb1a55c610ed65ab10 (patch) | |
tree | cd5bf2cd2d26a610d12d5fcf4d607e9528684344 | |
parent | a58f8c32c62bcf5824d1fe1d0de53e9bda974d65 (diff) | |
parent | 65407c3878159add9113010046b55068261fec10 (diff) | |
download | gitlab-ce-ee600a84d29d1ecbfdb3e9cb1a55c610ed65ab10.tar.gz |
Merge branch 'webpack-auto-config' into 'master'
Automatically Generate Webpack Entry Points
See merge request gitlab-org/gitlab-ce!16865
-rw-r--r-- | app/assets/javascripts/dispatcher.js | 52 | ||||
-rw-r--r-- | app/assets/javascripts/main.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/pages/dashboard/milestones/index/index.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/pages/groups/show/index.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/pages/projects/boards/index.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/pages/projects/issues/index/index.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/pages/projects/issues/show/index.js | 6 | ||||
-rw-r--r-- | app/assets/javascripts/pages/projects/merge_requests/index/index.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/pages/projects/show/index.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/pages/sessions/new/index.js | 4 | ||||
-rw-r--r-- | app/helpers/webpack_helper.rb | 18 | ||||
-rw-r--r-- | app/views/layouts/_head.html.haml | 2 | ||||
-rw-r--r-- | config/webpack.config.js | 23 | ||||
-rw-r--r-- | package.json | 3 | ||||
-rw-r--r-- | yarn.lock | 2 |
15 files changed, 73 insertions, 63 deletions
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 262ed3783fb..ab28b7d8d44 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -12,9 +12,9 @@ import ShortcutsIssuable from './shortcuts_issuable'; import Diff from './diff'; import SearchAutocomplete from './search_autocomplete'; -(function() { - var Dispatcher; +var Dispatcher; +(function() { Dispatcher = (function() { function Dispatcher() { this.initSearch(); @@ -49,46 +49,16 @@ import SearchAutocomplete from './search_autocomplete'; }); switch (page) { - case 'sessions:new': - import('./pages/sessions/new') - .then(callDefault) - .catch(fail); - break; - case 'projects:boards:show': - case 'projects:boards:index': - import('./pages/projects/boards/index') - .then(callDefault) - .catch(fail); - shortcut_handler = true; - break; case 'projects:environments:metrics': import('./pages/projects/environments/metrics') .then(callDefault) .catch(fail); break; case 'projects:merge_requests:index': - import('./pages/projects/merge_requests/index') - .then(callDefault) - .catch(fail); - shortcut_handler = true; - break; case 'projects:issues:index': - import('./pages/projects/issues/index') - .then(callDefault) - .catch(fail); - shortcut_handler = true; - break; case 'projects:issues:show': - import('./pages/projects/issues/show') - .then(callDefault) - .catch(fail); shortcut_handler = true; break; - case 'dashboard:milestones:index': - import('./pages/dashboard/milestones/index') - .then(callDefault) - .catch(fail); - break; case 'projects:milestones:index': import('./pages/projects/milestones/index') .then(callDefault) @@ -318,9 +288,6 @@ import SearchAutocomplete from './search_autocomplete'; shortcut_handler = true; break; case 'projects:show': - import('./pages/projects/show') - .then(callDefault) - .catch(fail); shortcut_handler = true; break; case 'projects:edit': @@ -352,9 +319,6 @@ import SearchAutocomplete from './search_autocomplete'; .catch(fail); break; case 'groups:show': - import('./pages/groups/show') - .then(callDefault) - .catch(fail); shortcut_handler = true; break; case 'groups:group_members:index': @@ -363,7 +327,7 @@ import SearchAutocomplete from './search_autocomplete'; .catch(fail); break; case 'projects:project_members:index': - import('./pages/projects/project_members/') + import('./pages/projects/project_members') .then(callDefault) .catch(fail); break; @@ -605,7 +569,7 @@ import SearchAutocomplete from './search_autocomplete'; } break; case 'profiles': - import('./pages/profiles/index/') + import('./pages/profiles/index') .then(callDefault) .catch(fail); break; @@ -662,8 +626,8 @@ import SearchAutocomplete from './search_autocomplete'; return Dispatcher; })(); +})(); - $(window).on('load', function() { - new Dispatcher(); - }); -}).call(window); +export default function initDispatcher() { + return new Dispatcher(); +} diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index d8b881a8fac..39445a85c77 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -33,7 +33,7 @@ import './projects_dropdown'; import './render_gfm'; import initBreadcrumbs from './breadcrumb'; -import './dispatcher'; +import initDispatcher from './dispatcher'; // eslint-disable-next-line global-require, import/no-commonjs if (process.env.NODE_ENV !== 'production') require('./test_utils/'); @@ -265,4 +265,6 @@ $(() => { removeFlashClickListener(flashEl); }); } + + initDispatcher(); }); diff --git a/app/assets/javascripts/pages/dashboard/milestones/index/index.js b/app/assets/javascripts/pages/dashboard/milestones/index/index.js index 0f2f1bd4a25..38ddebe30d9 100644 --- a/app/assets/javascripts/pages/dashboard/milestones/index/index.js +++ b/app/assets/javascripts/pages/dashboard/milestones/index/index.js @@ -1,3 +1,3 @@ import projectSelect from '~/project_select'; -export default projectSelect; +document.addEventListener('DOMContentLoaded', projectSelect); diff --git a/app/assets/javascripts/pages/groups/show/index.js b/app/assets/javascripts/pages/groups/show/index.js index 6ed0f010f15..5c763986da3 100644 --- a/app/assets/javascripts/pages/groups/show/index.js +++ b/app/assets/javascripts/pages/groups/show/index.js @@ -7,7 +7,7 @@ import ProjectsList from '~/projects_list'; import ShortcutsNavigation from '~/shortcuts_navigation'; import initGroupsList from '../../../groups'; -export default () => { +document.addEventListener('DOMContentLoaded', () => { const newGroupChildWrapper = document.querySelector('.js-new-project-subgroup'); new ShortcutsNavigation(); new NotificationsForm(); @@ -19,4 +19,4 @@ export default () => { } initGroupsList(); -}; +}); diff --git a/app/assets/javascripts/pages/projects/boards/index.js b/app/assets/javascripts/pages/projects/boards/index.js index 42c9bb5ec99..3aeeedbb45d 100644 --- a/app/assets/javascripts/pages/projects/boards/index.js +++ b/app/assets/javascripts/pages/projects/boards/index.js @@ -1,7 +1,7 @@ import UsersSelect from '~/users_select'; import ShortcutsNavigation from '~/shortcuts_navigation'; -export default () => { +document.addEventListener('DOMContentLoaded', () => { new UsersSelect(); // eslint-disable-line no-new new ShortcutsNavigation(); // eslint-disable-line no-new -}; +}); diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js index 0d3f35f044d..39c043edc38 100644 --- a/app/assets/javascripts/pages/projects/issues/index/index.js +++ b/app/assets/javascripts/pages/projects/issues/index/index.js @@ -7,10 +7,10 @@ import initFilteredSearch from '~/pages/search/init_filtered_search'; import { FILTERED_SEARCH } from '~/pages/constants'; import { ISSUABLE_INDEX } from '~/pages/projects/constants'; -export default () => { +document.addEventListener('DOMContentLoaded', () => { initFilteredSearch(FILTERED_SEARCH.ISSUES); new IssuableIndex(ISSUABLE_INDEX.ISSUE); new ShortcutsNavigation(); new UsersSelect(); -}; +}); diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js index 48ed8fb2243..da312c1f1b7 100644 --- a/app/assets/javascripts/pages/projects/issues/show/index.js +++ b/app/assets/javascripts/pages/projects/issues/show/index.js @@ -1,13 +1,13 @@ - /* eslint-disable no-new */ + import initIssuableSidebar from '~/init_issuable_sidebar'; import Issue from '~/issue'; import ShortcutsIssuable from '~/shortcuts_issuable'; import ZenMode from '~/zen_mode'; -export default () => { +document.addEventListener('DOMContentLoaded', () => { new Issue(); new ShortcutsIssuable(); new ZenMode(); initIssuableSidebar(); -}; +}); diff --git a/app/assets/javascripts/pages/projects/merge_requests/index/index.js b/app/assets/javascripts/pages/projects/merge_requests/index/index.js index b386e8fb48d..adadbf28e49 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/index/index.js +++ b/app/assets/javascripts/pages/projects/merge_requests/index/index.js @@ -5,9 +5,9 @@ import initFilteredSearch from '~/pages/search/init_filtered_search'; import { FILTERED_SEARCH } from '~/pages/constants'; import { ISSUABLE_INDEX } from '~/pages/projects/constants'; -export default () => { +document.addEventListener('DOMContentLoaded', () => { initFilteredSearch(FILTERED_SEARCH.MERGE_REQUESTS); new IssuableIndex(ISSUABLE_INDEX.MERGE_REQUEST); // eslint-disable-line no-new new ShortcutsNavigation(); // eslint-disable-line no-new new UsersSelect(); // eslint-disable-line no-new -}; +}); diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js index 55154cdddcb..9b87f249f09 100644 --- a/app/assets/javascripts/pages/projects/show/index.js +++ b/app/assets/javascripts/pages/projects/show/index.js @@ -8,7 +8,7 @@ import { ajaxGet } from '~/lib/utils/common_utils'; import Star from '../../../star'; import notificationsDropdown from '../../../notifications_dropdown'; -export default () => { +document.addEventListener('DOMContentLoaded', () => { new Star(); // eslint-disable-line no-new notificationsDropdown(); new ShortcutsNavigation(); // eslint-disable-line no-new @@ -24,4 +24,4 @@ export default () => { $('#tree-slider').waitForImages(() => { ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath); }); -}; +}); diff --git a/app/assets/javascripts/pages/sessions/new/index.js b/app/assets/javascripts/pages/sessions/new/index.js index f163557babc..a0aa0499776 100644 --- a/app/assets/javascripts/pages/sessions/new/index.js +++ b/app/assets/javascripts/pages/sessions/new/index.js @@ -2,10 +2,10 @@ import UsernameValidator from './username_validator'; import SigninTabsMemoizer from './signin_tabs_memoizer'; import OAuthRememberMe from './oauth_remember_me'; -export default () => { +document.addEventListener('DOMContentLoaded', () => { new UsernameValidator(); // eslint-disable-line no-new new SigninTabsMemoizer(); // eslint-disable-line no-new new OAuthRememberMe({ // eslint-disable-line no-new container: $('.omniauth-container'), }).bindEvents(); -}; +}); diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb index 77433acb92a..9d071f2d59a 100644 --- a/app/helpers/webpack_helper.rb +++ b/app/helpers/webpack_helper.rb @@ -5,6 +5,24 @@ module WebpackHelper javascript_include_tag(*gitlab_webpack_asset_paths(bundle, force_same_domain: force_same_domain)) end + def webpack_controller_bundle_tags + bundles = [] + segments = [*controller.controller_path.split('/'), controller.action_name].compact + + until segments.empty? + begin + asset_paths = gitlab_webpack_asset_paths("pages.#{segments.join('.')}", extension: 'js') + bundles.unshift(*asset_paths) + rescue Webpack::Rails::Manifest::EntryPointMissingError + # no bundle exists for this path + end + + segments.pop + end + + javascript_include_tag(*bundles) + end + # override webpack-rails gem helper until changes can make it upstream def gitlab_webpack_asset_paths(source, extension: nil, force_same_domain: false) return "" unless source.present? diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 488b706e6a6..0c979109b3f 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -47,6 +47,8 @@ - if content_for?(:page_specific_javascripts) = yield :page_specific_javascripts + = webpack_controller_bundle_tags + = yield :project_javascripts = csrf_meta_tags diff --git a/config/webpack.config.js b/config/webpack.config.js index 783677b5b8d..7f3fe551a03 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -3,6 +3,7 @@ var crypto = require('crypto'); var fs = require('fs'); var path = require('path'); +var glob = require('glob'); var webpack = require('webpack'); var StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin; var CopyWebpackPlugin = require('copy-webpack-plugin'); @@ -20,6 +21,26 @@ var DEV_SERVER_LIVERELOAD = process.env.DEV_SERVER_LIVERELOAD !== 'false'; var WEBPACK_REPORT = process.env.WEBPACK_REPORT; var NO_COMPRESSION = process.env.NO_COMPRESSION; +// generate automatic entry points +var autoEntries = {}; +var pageEntries = glob.sync('pages/**/index.js', { cwd: path.join(ROOT_PATH, 'app/assets/javascripts') }); + +// filter out entries currently imported dynamically in dispatcher.js +var dispatcher = fs.readFileSync(path.join(ROOT_PATH, 'app/assets/javascripts/dispatcher.js')).toString(); +var dispatcherChunks = dispatcher.match(/(?!import\('.\/)pages\/[^']+/g); + +pageEntries.forEach(( path ) => { + let chunkPath = path.replace(/\/index\.js$/, ''); + if (!dispatcherChunks.includes(chunkPath)) { + let chunkName = chunkPath.replace(/\//g, '.'); + autoEntries[chunkName] = './' + path; + } +}); + +// report our auto-generated bundle count +var autoEntriesCount = Object.keys(autoEntries).length; +console.log(`${autoEntriesCount} entries from '/pages' automatically added to webpack output.`); + var config = { // because sqljs requires fs. node: { @@ -301,6 +322,8 @@ var config = { } } +config.entry = Object.assign({}, autoEntries, config.entry); + if (IS_PRODUCTION) { config.devtool = 'source-map'; config.plugins.push( diff --git a/package.json b/package.json index c68cf648932..26908e9f905 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "scripts": { - "dev-server": "nodemon --watch config/webpack.config.js -- ./node_modules/.bin/webpack-dev-server --config config/webpack.config.js", + "dev-server": "nodemon -w 'config/webpack.config.js' -w 'app/assets/javascripts/dispatcher.js' -w 'app/assets/javascripts/pages/**/index.js' --exec 'webpack-dev-server --config config/webpack.config.js'", "eslint": "eslint --max-warnings 0 --ext .js,.vue .", "eslint-fix": "eslint --max-warnings 0 --ext .js,.vue --fix .", "eslint-report": "eslint --max-warnings 0 --ext .js,.vue --format html --output-file ./eslint-report.html .", @@ -47,6 +47,7 @@ "exports-loader": "^0.6.4", "file-loader": "^0.11.1", "fuzzaldrin-plus": "^0.5.0", + "glob": "^7.1.2", "imports-loader": "^0.7.1", "jed": "^1.1.1", "jquery": "^2.2.4", diff --git a/yarn.lock b/yarn.lock index d10a4372a40..e6d5f239d83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3322,7 +3322,7 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.0, glob@~7.1.2: +glob@^7.1.0, glob@^7.1.2, glob@~7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: |