Commit 9f59101f authored by Jacob Schatz's avatar Jacob Schatz

Merge branch 'commons-chunk-plugin' into 'master'

Use CommonsChunkPlugin to place vendor libraries in cacheable bundles

Closes #25550

See merge request !9647
parents 2d006b46 982dd504
import 'jquery';
// bootstrap jQuery plugins
import 'bootstrap-sass/assets/javascripts/bootstrap/affix';
import 'bootstrap-sass/assets/javascripts/bootstrap/alert';
import 'bootstrap-sass/assets/javascripts/bootstrap/dropdown';
import 'bootstrap-sass/assets/javascripts/bootstrap/modal';
import 'bootstrap-sass/assets/javascripts/bootstrap/tab';
import 'bootstrap-sass/assets/javascripts/bootstrap/transition';
import 'bootstrap-sass/assets/javascripts/bootstrap/tooltip';
import './jquery';
import './bootstrap';
import 'jquery';
// common jQuery plugins
import 'jquery-ujs';
import 'vendor/jquery.endless-scroll';
import 'vendor/jquery.caret';
import 'vendor/jquery.atwho';
import 'vendor/jquery.scrollTo';
import 'vendor/jquery.nicescroll';
import 'vendor/jquery.waitforimages';
import 'select2/select2';
import Chart from 'vendor/Chart';
import ContributorsStatGraph from './stat_graph_contributors'; import ContributorsStatGraph from './stat_graph_contributors';
// export to global scope // export to global scope
window.Chart = Chart;
window.ContributorsStatGraph = ContributorsStatGraph; window.ContributorsStatGraph = ContributorsStatGraph;
/* global Vue */ /* global Vue */
window.Vue = require('vue');
window.Vue.use(require('vue-resource'));
require('./components/time_tracker'); require('./components/time_tracker');
require('../../smart_interval'); require('../../smart_interval');
require('../../subbable_resource'); require('../../subbable_resource');
......
/* eslint-disable func-names, space-before-function-paren */
window.Chart = require('vendor/Chart');
/* eslint-disable func-names, space-before-function-paren */
/*= require cropper */
(function() {
}).call(window);
/* eslint-disable func-names, space-before-function-paren */
window.d3 = require('d3');
window.Vue = require('vue');
window.Vue.use(require('vue-resource'));
...@@ -6,35 +6,34 @@ ...@@ -6,35 +6,34 @@
/* global AwardsHandler */ /* global AwardsHandler */
/* global Aside */ /* global Aside */
window.$ = window.jQuery = require('jquery'); import jQuery from 'jquery';
require('jquery-ujs'); import _ from 'underscore';
require('vendor/jquery.endless-scroll'); import Cookies from 'js-cookie';
require('vendor/jquery.waitforimages'); import Pikaday from 'pikaday';
require('vendor/jquery.caret'); import Dropzone from 'dropzone';
require('vendor/jquery.atwho'); import Sortable from 'vendor/Sortable';
require('vendor/jquery.scrollTo');
window.Cookies = require('js-cookie'); // libraries with import side-effects
require('./autosave');
require('bootstrap/js/affix');
require('bootstrap/js/alert');
require('bootstrap/js/dropdown');
require('bootstrap/js/modal');
require('bootstrap/js/tab');
require('bootstrap/js/transition');
require('bootstrap/js/tooltip');
require('select2/select2.js');
window.Pikaday = require('pikaday');
window._ = require('underscore');
window.Dropzone = require('dropzone');
window.Sortable = require('vendor/Sortable');
require('mousetrap'); require('mousetrap');
require('mousetrap/plugins/pause/mousetrap-pause'); require('mousetrap/plugins/pause/mousetrap-pause');
require('vendor/fuzzaldrin-plus');
require('es6-promise').polyfill();
// expose common libraries as globals (TODO: remove these)
window.jQuery = jQuery;
window.$ = jQuery;
window._ = _;
window.Cookies = Cookies;
window.Pikaday = Pikaday;
window.Dropzone = Dropzone;
window.Sortable = Sortable;
// shortcuts
require('./shortcuts'); require('./shortcuts');
require('./shortcuts_navigation'); require('./shortcuts_navigation');
require('./shortcuts_dashboard_navigation'); require('./shortcuts_dashboard_navigation');
require('./shortcuts_issuable'); require('./shortcuts_issuable');
require('./shortcuts_network'); require('./shortcuts_network');
require('vendor/jquery.nicescroll');
// behaviors // behaviors
require('./behaviors/autosize'); require('./behaviors/autosize');
...@@ -205,9 +204,6 @@ require('./visibility_select'); ...@@ -205,9 +204,6 @@ require('./visibility_select');
require('./wikis'); require('./wikis');
require('./zen_mode'); require('./zen_mode');
require('vendor/fuzzaldrin-plus');
require('es6-promise').polyfill();
(function () { (function () {
document.addEventListener('beforeunload', function () { document.addEventListener('beforeunload', function () {
// Unbind scroll events // Unbind scroll events
...@@ -285,7 +281,7 @@ require('es6-promise').polyfill(); ...@@ -285,7 +281,7 @@ require('es6-promise').polyfill();
$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover'; $.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover';
$body.tooltip({ $body.tooltip({
selector: '.has-tooltip, [data-toggle="tooltip"]', selector: '.has-tooltip, [data-toggle="tooltip"]',
placement: function (_, el) { placement: function (tip, el) {
return $(el).data('placement') || 'bottom'; return $(el).data('placement') || 'bottom';
} }
}); });
......
/* eslint-disable no-useless-escape, max-len, quotes, no-var, no-underscore-dangle, func-names, space-before-function-paren, no-unused-vars, no-return-assign, object-shorthand, one-var, one-var-declaration-per-line, comma-dangle, consistent-return, class-methods-use-this, new-parens */ /* eslint-disable no-useless-escape, max-len, quotes, no-var, no-underscore-dangle, func-names, space-before-function-paren, no-unused-vars, no-return-assign, object-shorthand, one-var, one-var-declaration-per-line, comma-dangle, consistent-return, class-methods-use-this, new-parens */
import 'vendor/cropper';
((global) => { ((global) => {
// Matches everything but the file name // Matches everything but the file name
const FILENAMEREGEX = /^.*[\\\/]/; const FILENAMEREGEX = /^.*[\\\/]/;
......
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, camelcase, vars-on-top, object-shorthand, comma-dangle, eqeqeq, no-mixed-operators, no-return-assign, newline-per-chained-call, prefer-arrow-callback, consistent-return, one-var, one-var-declaration-per-line, prefer-template, quotes, no-unused-vars, no-else-return, max-len */ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, camelcase, vars-on-top, object-shorthand, comma-dangle, eqeqeq, no-mixed-operators, no-return-assign, newline-per-chained-call, prefer-arrow-callback, consistent-return, one-var, one-var-declaration-per-line, prefer-template, quotes, no-unused-vars, no-else-return, max-len */
/* global d3 */
import d3 from 'd3';
(function() { (function() {
var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; }; var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; };
......
...@@ -28,7 +28,9 @@ ...@@ -28,7 +28,9 @@
= stylesheet_link_tag "application", media: "all" = stylesheet_link_tag "application", media: "all"
= stylesheet_link_tag "print", media: "print" = stylesheet_link_tag "print", media: "print"
= javascript_include_tag(*webpack_asset_paths("application")) = javascript_include_tag(*webpack_asset_paths("runtime"))
= javascript_include_tag(*webpack_asset_paths("common"))
= javascript_include_tag(*webpack_asset_paths("main"))
- if content_for?(:page_specific_javascripts) - if content_for?(:page_specific_javascripts)
= yield :page_specific_javascripts = yield :page_specific_javascripts
......
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/cropper.js')
= page_specific_javascript_bundle_tag('profile') = page_specific_javascript_bundle_tag('profile')
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
- page_title "Boards" - page_title "Boards"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('boards') = page_specific_javascript_bundle_tag('boards')
= page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test? = page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
......
...@@ -4,4 +4,5 @@ ...@@ -4,4 +4,5 @@
} } } }
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('commit_pipelines') = page_specific_javascript_bundle_tag('commit_pipelines')
- @no_container = true - @no_container = true
- page_title "Cycle Analytics" - page_title "Cycle Analytics"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('cycle_analytics') = page_specific_javascript_bundle_tag('cycle_analytics')
= render "projects/head" = render "projects/head"
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
= render "projects/pipelines/head" = render "projects/pipelines/head"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag("environments_folder") = page_specific_javascript_bundle_tag("environments_folder")
#environments-folder-list-view{ data: { "can-create-deployment" => can?(current_user, :create_deployment, @project).to_s, #environments-folder-list-view{ data: { "can-create-deployment" => can?(current_user, :create_deployment, @project).to_s,
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
= render "projects/pipelines/head" = render "projects/pipelines/head"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag("environments") = page_specific_javascript_bundle_tag("environments")
#environments-list-view{ data: { environments_data: environments_list_data, #environments-list-view{ data: { environments_data: environments_list_data,
......
- @no_container = true - @no_container = true
- page_title "Charts" - page_title "Charts"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('lib_chart') = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('graphs') = page_specific_javascript_bundle_tag('graphs')
= render "projects/commits/head" = render "projects/commits/head"
......
- @no_container = true - @no_container = true
- page_title "Contributors" - page_title "Contributors"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('lib_chart') = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('graphs') = page_specific_javascript_bundle_tag('graphs')
= render 'projects/commits/head' = render 'projects/commits/head'
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
- page_title "#{@issue.title} (#{@issue.to_reference})", "Issues" - page_title "#{@issue.title} (#{@issue.to_reference})", "Issues"
- page_description @issue.description - page_description @issue.description
- page_card_attributes @issue.card_attributes - page_card_attributes @issue.card_attributes
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('lib_vue')
.clearfix.detail-page-header .clearfix.detail-page-header
.issuable-header .issuable-header
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
- page_description @merge_request.description - page_description @merge_request.description
- page_card_attributes @merge_request.card_attributes - page_card_attributes @merge_request.card_attributes
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('diff_notes') = page_specific_javascript_bundle_tag('diff_notes')
.merge-request{ 'data-url' => merge_request_path(@merge_request), 'data-project-path' => project_path(@merge_request.project) } .merge-request{ 'data-url' => merge_request_path(@merge_request), 'data-project-path' => project_path(@merge_request.project) }
......
- page_title "Merge Conflicts", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests" - page_title "Merge Conflicts", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('lib_vue') = page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('merge_conflicts') = page_specific_javascript_bundle_tag('merge_conflicts')
= page_specific_javascript_tag('lib/ace.js') = page_specific_javascript_tag('lib/ace.js')
= render "projects/merge_requests/show/mr_title" = render "projects/merge_requests/show/mr_title"
......
- @no_container = true - @no_container = true
- page_title "Charts", "Pipelines" - page_title "Charts", "Pipelines"
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('lib_chart') = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('graphs') = page_specific_javascript_bundle_tag('graphs')
= render 'head' = render 'head'
......
...@@ -50,4 +50,5 @@ ...@@ -50,4 +50,5 @@
.content-list.pipelines{ data: { url: namespace_project_pipelines_path(@project.namespace, @project, format: :json) } } .content-list.pipelines{ data: { url: namespace_project_pipelines_path(@project.namespace, @project, format: :json) } }
.vue-pipelines-index .vue-pipelines-index
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('vue_pipelines') = page_specific_javascript_bundle_tag('vue_pipelines')
- todo = issuable_todo(issuable) - todo = issuable_todo(issuable)
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('issuable') = page_specific_javascript_bundle_tag('issuable')
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => "101", "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' } %aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => "101", "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
......
- page_title @user.name - page_title @user.name
- page_description @user.bio - page_description @user.bio
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('lib_d3') = page_specific_javascript_bundle_tag('common_d3')
= page_specific_javascript_bundle_tag('users') = page_specific_javascript_bundle_tag('users')
- header_title @user.name, user_path(@user) - header_title @user.name, user_path(@user)
- @no_container = true - @no_container = true
......
---
title: Use webpack CommonsChunkPlugin to place common javascript libraries in their
own bundles
merge_request: 9647
author:
...@@ -100,7 +100,6 @@ module Gitlab ...@@ -100,7 +100,6 @@ module Gitlab
config.assets.precompile << "katex.js" config.assets.precompile << "katex.js"
config.assets.precompile << "xterm/xterm.css" config.assets.precompile << "xterm/xterm.css"
config.assets.precompile << "lib/ace.js" config.assets.precompile << "lib/ace.js"
config.assets.precompile << "lib/cropper.js"
config.assets.precompile << "lib/raphael.js" config.assets.precompile << "lib/raphael.js"
config.assets.precompile << "u2f.js" config.assets.precompile << "u2f.js"
config.assets.precompile << "vendor/assets/fonts/*" config.assets.precompile << "vendor/assets/fonts/*"
......
var path = require('path'); var path = require('path');
var webpack = require('webpack');
var webpackConfig = require('./webpack.config.js'); var webpackConfig = require('./webpack.config.js');
var ROOT_PATH = path.resolve(__dirname, '..'); var ROOT_PATH = path.resolve(__dirname, '..');
// add coverage instrumentation to babel config // add coverage instrumentation to babel config
if (webpackConfig && webpackConfig.module && webpackConfig.module.rules) { if (webpackConfig.module && webpackConfig.module.rules) {
var babelConfig = webpackConfig.module.rules.find(function (rule) { var babelConfig = webpackConfig.module.rules.find(function (rule) {
return rule.loader === 'babel-loader'; return rule.loader === 'babel-loader';
}); });
...@@ -13,6 +14,16 @@ if (webpackConfig && webpackConfig.module && webpackConfig.module.rules) { ...@@ -13,6 +14,16 @@ if (webpackConfig && webpackConfig.module && webpackConfig.module.rules) {
babelConfig.options.plugins.push('istanbul'); babelConfig.options.plugins.push('istanbul');
} }
// remove problematic plugins
if (webpackConfig.plugins) {
webpackConfig.plugins = webpackConfig.plugins.filter(function (plugin) {
return !(
plugin instanceof webpack.optimize.CommonsChunkPlugin ||
plugin instanceof webpack.DefinePlugin
);
});
}
// Karma configuration // Karma configuration
module.exports = function(config) { module.exports = function(config) {
var progressReporter = process.env.CI ? 'mocha' : 'progress'; var progressReporter = process.env.CI ? 'mocha' : 'progress';
......
...@@ -17,7 +17,10 @@ var WEBPACK_REPORT = process.env.WEBPACK_REPORT; ...@@ -17,7 +17,10 @@ var WEBPACK_REPORT = process.env.WEBPACK_REPORT;
var config = { var config = {
context: path.join(ROOT_PATH, 'app/assets/javascripts'), context: path.join(ROOT_PATH, 'app/assets/javascripts'),
entry: { entry: {
application: './application.js', common: './commons/index.js',
common_vue: ['vue', 'vue-resource'],
common_d3: ['d3'],
main: './main.js',
blob_edit: './blob_edit/blob_edit_bundle.js', blob_edit: './blob_edit/blob_edit_bundle.js',
boards: './boards/boards_bundle.js', boards: './boards/boards_bundle.js',
simulate_drag: './test_utils/simulate_drag.js', simulate_drag: './test_utils/simulate_drag.js',
...@@ -38,16 +41,13 @@ var config = { ...@@ -38,16 +41,13 @@ var config = {
snippet: './snippet/snippet_bundle.js', snippet: './snippet/snippet_bundle.js',
terminal: './terminal/terminal_bundle.js', terminal: './terminal/terminal_bundle.js',
users: './users/users_bundle.js', users: './users/users_bundle.js',
lib_chart: './lib/chart.js',
lib_d3: './lib/d3.js',
lib_vue: './lib/vue_resource.js',
vue_pipelines: './vue_pipelines_index/index.js', vue_pipelines: './vue_pipelines_index/index.js',
}, },
output: { output: {
path: path.join(ROOT_PATH, 'public/assets/webpack'), path: path.join(ROOT_PATH, 'public/assets/webpack'),
publicPath: '/assets/webpack/', publicPath: '/assets/webpack/',
filename: IS_PRODUCTION ? '[name]-[chunkhash].js' : '[name].js' filename: IS_PRODUCTION ? '[name].[chunkhash].bundle.js' : '[name].bundle.js'
}, },
devtool: 'inline-source-map', devtool: 'inline-source-map',
...@@ -82,14 +82,56 @@ var config = { ...@@ -82,14 +82,56 @@ var config = {
modules: false, modules: false,
assets: true assets: true
}), }),
// prevent pikaday from including moment.js
new webpack.IgnorePlugin(/moment/, /pikaday/), new webpack.IgnorePlugin(/moment/, /pikaday/),
// fix legacy jQuery plugins which depend on globals
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
// use deterministic module ids in all environments
IS_PRODUCTION ?
new webpack.HashedModuleIdsPlugin() :
new webpack.NamedModulesPlugin(),
// create cacheable common library bundle for all vue chunks
new webpack.optimize.CommonsChunkPlugin({
name: 'common_vue',
chunks: [
'boards',
'commit_pipelines',
'cycle_analytics',
'diff_notes',
'environments',
'environments_folder',
'issuable',
'merge_conflicts',
'vue_pipelines',
],
minChunks: function(module, count) {
return module.resource && (/vue_shared/).test(module.resource);
},
}),
// create cacheable common library bundle for all d3 chunks
new webpack.optimize.CommonsChunkPlugin({
name: 'common_d3',
chunks: ['graphs', 'users'],
}),
// create cacheable common library bundles
new webpack.optimize.CommonsChunkPlugin({
names: ['main', 'common', 'runtime'],
}),
], ],
resolve: { resolve: {
extensions: ['.js', '.es6', '.js.es6'], extensions: ['.js', '.es6', '.js.es6'],
alias: { alias: {
'~': path.join(ROOT_PATH, 'app/assets/javascripts'), '~': path.join(ROOT_PATH, 'app/assets/javascripts'),
'bootstrap/js': 'bootstrap-sass/assets/javascripts/bootstrap',
'emoji-aliases$': path.join(ROOT_PATH, 'fixtures/emojis/aliases.json'), 'emoji-aliases$': path.join(ROOT_PATH, 'fixtures/emojis/aliases.json'),
'icons': path.join(ROOT_PATH, 'app/views/shared/icons'), 'icons': path.join(ROOT_PATH, 'app/views/shared/icons'),
'vendor': path.join(ROOT_PATH, 'vendor/assets/javascripts'), 'vendor': path.join(ROOT_PATH, 'vendor/assets/javascripts'),
......
...@@ -5,23 +5,12 @@ jasmine.getFixtures().fixturesPath = 'base/spec/javascripts/fixtures'; ...@@ -5,23 +5,12 @@ jasmine.getFixtures().fixturesPath = 'base/spec/javascripts/fixtures';
jasmine.getJSONFixtures().fixturesPath = 'base/spec/javascripts/fixtures'; jasmine.getJSONFixtures().fixturesPath = 'base/spec/javascripts/fixtures';
// include common libraries // include common libraries
require('~/commons/index.js');
window.$ = window.jQuery = require('jquery'); window.$ = window.jQuery = require('jquery');
window._ = require('underscore'); window._ = require('underscore');
window.Cookies = require('js-cookie'); window.Cookies = require('js-cookie');
window.Vue = require('vue'); window.Vue = require('vue');
window.Vue.use(require('vue-resource')); window.Vue.use(require('vue-resource'));
require('jquery-ujs');
require('bootstrap/js/affix');
require('bootstrap/js/alert');
require('bootstrap/js/button');
require('bootstrap/js/collapse');
require('bootstrap/js/dropdown');
require('bootstrap/js/modal');
require('bootstrap/js/scrollspy');
require('bootstrap/js/tab');
require('bootstrap/js/transition');
require('bootstrap/js/tooltip');
require('bootstrap/js/popover');
// stub expected globals // stub expected globals
window.gl = window.gl || {}; window.gl = window.gl || {};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment