Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
73fd426d
Commit
73fd426d
authored
May 07, 2018
by
Mike Greiling
Committed by
Clement Ho
May 07, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upgrade to Webpack 4
parent
52df6f78
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1416 additions
and
585 deletions
+1416
-585
app/assets/javascripts/ide/index.js
app/assets/javascripts/ide/index.js
+12
-6
app/assets/javascripts/main.js
app/assets/javascripts/main.js
+39
-24
app/assets/javascripts/pages/ide/index.js
app/assets/javascripts/pages/ide/index.js
+9
-0
app/helpers/webpack_helper.rb
app/helpers/webpack_helper.rb
+26
-19
app/views/ide/index.html.haml
app/views/ide/index.html.haml
+0
-3
app/views/layouts/_head.html.haml
app/views/layouts/_head.html.haml
+0
-3
config/initializers/static_files.rb
config/initializers/static_files.rb
+1
-1
config/karma.config.js
config/karma.config.js
+8
-13
config/webpack.config.js
config/webpack.config.js
+82
-103
ee/app/assets/javascripts/pages/projects/issues/service_desk/index.js
...s/javascripts/pages/projects/issues/service_desk/index.js
+2
-2
lib/gitlab/webpack/dev_server_middleware.rb
lib/gitlab/webpack/dev_server_middleware.rb
+2
-2
lib/gitlab/webpack/manifest.rb
lib/gitlab/webpack/manifest.rb
+27
-0
package.json
package.json
+15
-16
spec/features/raven_js_spec.rb
spec/features/raven_js_spec.rb
+1
-1
spec/javascripts/pipelines/graph/linked_pipeline_spec.js
spec/javascripts/pipelines/graph/linked_pipeline_spec.js
+7
-3
spec/javascripts/pipelines/graph/linked_pipelines_column_spec.js
...vascripts/pipelines/graph/linked_pipelines_column_spec.js
+7
-4
spec/javascripts/sidebar/ee_sidebar_mediator_spec.js
spec/javascripts/sidebar/ee_sidebar_mediator_spec.js
+3
-2
spec/javascripts/vue_shared/components/linked_pipelines_mini_list_spec.js
.../vue_shared/components/linked_pipelines_mini_list_spec.js
+14
-4
yarn.lock
yarn.lock
+1161
-379
No files found.
app/assets/javascripts/ide/index.js
View file @
73fd426d
...
...
@@ -4,7 +4,9 @@ import ide from './components/ide.vue';
import
store
from
'
./stores
'
;
import
router
from
'
./ide_router
'
;
function
initIde
(
el
)
{
Vue
.
use
(
Translate
);
export
function
initIde
(
el
)
{
if
(
!
el
)
return
null
;
return
new
Vue
({
...
...
@@ -26,8 +28,12 @@ function initIde(el) {
});
}
const
ideElement
=
document
.
getElementById
(
'
ide
'
);
Vue
.
use
(
Translate
);
initIde
(
ideElement
);
// tell webpack to load assets from origin so that web workers don't break
export
function
resetServiceWorkersPublicPath
()
{
// __webpack_public_path__ is a global variable that can be used to adjust
// the webpack publicPath setting at runtime.
// see: https://webpack.js.org/guides/public-path/
const
relativeRootPath
=
(
gon
&&
gon
.
relative_url_root
)
||
''
;
const
webpackAssetPath
=
`
${
relativeRootPath
}
/assets/webpack/`
;
__webpack_public_path__
=
webpackAssetPath
;
// eslint-disable-line camelcase
}
app/assets/javascripts/main.js
View file @
73fd426d
/* eslint-disable import/first */
/* global $ */
import
jQuery
from
'
jquery
'
;
import
Cookies
from
'
js-cookie
'
;
import
svg4everybody
from
'
svg4everybody
'
;
// expose common libraries as globals (TODO: remove these)
window
.
jQuery
=
jQuery
;
window
.
$
=
jQuery
;
// bootstrap webpack, common libs, polyfills, and behaviors
import
'
./webpack
'
;
import
'
./commons
'
;
import
'
./behaviors
'
;
// lib/utils
import
{
handleLocationHash
,
addSelectOnFocusBehaviour
}
from
'
./lib/utils/common_utils
'
;
import
{
localTimeAgo
}
from
'
./lib/utils/datetime_utility
'
;
import
{
getLocationHash
,
visitUrl
}
from
'
./lib/utils/url_utility
'
;
// behaviors
import
'
./behaviors/
'
;
// everything else
import
loadAwardsHandler
from
'
./awards_handler
'
;
import
bp
from
'
./breakpoints
'
;
...
...
@@ -31,11 +28,14 @@ import initLogoAnimation from './logo';
import
'
./milestone_select
'
;
import
'
./projects_dropdown
'
;
import
initBreadcrumbs
from
'
./breadcrumb
'
;
import
initDispatcher
from
'
./dispatcher
'
;
// EE-only scripts
import
'
ee/main
'
;
import
'
ee/main
'
;
// eslint-disable-line import/first
import
initDispatcher
from
'
./dispatcher
'
;
// expose jQuery as global (TODO: remove these)
window
.
jQuery
=
jQuery
;
window
.
$
=
jQuery
;
// inject test utilities if necessary
if
(
process
.
env
.
NODE_ENV
!==
'
production
'
&&
gon
&&
gon
.
test_env
)
{
...
...
@@ -55,10 +55,14 @@ document.addEventListener('beforeunload', () => {
});
window
.
addEventListener
(
'
hashchange
'
,
handleLocationHash
);
window
.
addEventListener
(
'
load
'
,
function
onLoad
()
{
window
.
removeEventListener
(
'
load
'
,
onLoad
,
false
);
handleLocationHash
();
},
false
);
window
.
addEventListener
(
'
load
'
,
function
onLoad
()
{
window
.
removeEventListener
(
'
load
'
,
onLoad
,
false
);
handleLocationHash
();
},
false
,
);
gl
.
lazyLoader
=
new
LazyLoader
({
scrollContainer
:
window
,
...
...
@@ -92,9 +96,7 @@ document.addEventListener('DOMContentLoaded', () => {
if
(
bootstrapBreakpoint
===
'
xs
'
)
{
const
$rightSidebar
=
$
(
'
aside.right-sidebar, .layout-page
'
);
$rightSidebar
.
removeClass
(
'
right-sidebar-expanded
'
)
.
addClass
(
'
right-sidebar-collapsed
'
);
$rightSidebar
.
removeClass
(
'
right-sidebar-expanded
'
).
addClass
(
'
right-sidebar-collapsed
'
);
}
// prevent default action for disabled buttons
...
...
@@ -111,7 +113,8 @@ document.addEventListener('DOMContentLoaded', () => {
addSelectOnFocusBehaviour
(
'
.js-select-on-focus
'
);
$
(
'
.remove-row
'
).
on
(
'
ajax:success
'
,
function
removeRowAjaxSuccessCallback
()
{
$
(
this
).
tooltip
(
'
destroy
'
)
$
(
this
)
.
tooltip
(
'
destroy
'
)
.
closest
(
'
li
'
)
.
fadeOut
();
});
...
...
@@ -121,7 +124,9 @@ document.addEventListener('DOMContentLoaded', () => {
});
$
(
'
.js-remove-tr
'
).
on
(
'
ajax:success
'
,
function
removeTRAjaxSuccessCallback
()
{
$
(
this
).
closest
(
'
tr
'
).
fadeOut
();
$
(
this
)
.
closest
(
'
tr
'
)
.
fadeOut
();
});
// Initialize select2 selects
...
...
@@ -158,7 +163,9 @@ document.addEventListener('DOMContentLoaded', () => {
// Form submitter
$
(
'
.trigger-submit
'
).
on
(
'
change
'
,
function
triggerSubmitCallback
()
{
$
(
this
).
parents
(
'
form
'
).
submit
();
$
(
this
)
.
parents
(
'
form
'
)
.
submit
();
});
localTimeAgo
(
$
(
'
abbr.timeago, .js-timeago
'
),
true
);
...
...
@@ -207,9 +214,15 @@ document.addEventListener('DOMContentLoaded', () => {
$this
.
toggleClass
(
'
active
'
);
if
(
$this
.
hasClass
(
'
active
'
))
{
notesHolders
.
show
().
find
(
'
.hide, .content
'
).
show
();
notesHolders
.
show
()
.
find
(
'
.hide, .content
'
)
.
show
();
}
else
{
notesHolders
.
hide
().
find
(
'
.content
'
).
hide
();
notesHolders
.
hide
()
.
find
(
'
.content
'
)
.
hide
();
}
$
(
document
).
trigger
(
'
toggle.comments
'
);
...
...
@@ -250,9 +263,11 @@ document.addEventListener('DOMContentLoaded', () => {
const
flashContainer
=
document
.
querySelector
(
'
.flash-container
'
);
if
(
flashContainer
&&
flashContainer
.
children
.
length
)
{
flashContainer
.
querySelectorAll
(
'
.flash-alert, .flash-notice, .flash-success
'
).
forEach
((
flashEl
)
=>
{
removeFlashClickListener
(
flashEl
);
});
flashContainer
.
querySelectorAll
(
'
.flash-alert, .flash-notice, .flash-success
'
)
.
forEach
(
flashEl
=>
{
removeFlashClickListener
(
flashEl
);
});
}
initDispatcher
();
...
...
app/assets/javascripts/pages/ide/index.js
0 → 100644
View file @
73fd426d
import
{
initIde
,
resetServiceWorkersPublicPath
}
from
'
~/ide/index
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
ideElement
=
document
.
getElementById
(
'
ide
'
);
if
(
ideElement
)
{
resetServiceWorkersPublicPath
();
initIde
(
ideElement
);
}
});
app/helpers/webpack_helper.rb
View file @
73fd426d
require
'
webpack/rails
/manifest'
require
'
gitlab/webpack
/manifest'
module
WebpackHelper
def
webpack_bundle_tag
(
bundle
,
force_same_domain:
false
)
javascript_include_tag
(
*
gitlab_webpack_asset_paths
(
bundle
,
force_same_domain:
force_same_domain
))
def
webpack_bundle_tag
(
bundle
)
javascript_include_tag
(
*
webpack_entrypoint_paths
(
bundle
))
end
def
webpack_controller_bundle_tags
bundle
s
=
[]
chunk
s
=
[]
action
=
case
controller
.
action_name
when
'create'
then
'new'
...
...
@@ -16,37 +16,44 @@ module WebpackHelper
route
=
[
*
controller
.
controller_path
.
split
(
'/'
),
action
].
compact
until
route
.
empty?
until
chunks
.
any?
||
route
.
empty?
entrypoint
=
"pages.
#{
route
.
join
(
'.'
)
}
"
begin
asset_paths
=
gitlab_webpack_asset_paths
(
"pages.
#{
route
.
join
(
'.'
)
}
"
,
extension:
'js'
)
bundles
.
unshift
(
*
asset_paths
)
rescue
Webpack
::
Rails
::
Manifest
::
EntryPointMissingError
chunks
=
webpack_entrypoint_paths
(
entrypoint
,
extension:
'js'
)
rescue
Gitlab
::
Webpack
::
Manifest
::
AssetMissingError
# no bundle exists for this path
end
route
.
pop
end
javascript_include_tag
(
*
bundles
)
if
chunks
.
empty?
chunks
=
webpack_entrypoint_paths
(
"default"
,
extension:
'js'
)
end
javascript_include_tag
(
*
chunks
)
end
# override webpack-rails gem helper until changes can make it upstream
def
gitlab_webpack_asset_paths
(
source
,
extension:
nil
,
force_same_domain:
false
)
def
webpack_entrypoint_paths
(
source
,
extension:
nil
,
exclude_duplicates:
true
)
return
""
unless
source
.
present?
paths
=
Webpack
::
Rails
::
Manifest
.
asse
t_paths
(
source
)
paths
=
Gitlab
::
Webpack
::
Manifest
.
entrypoin
t_paths
(
source
)
if
extension
paths
.
select!
{
|
p
|
p
.
ends_with?
".
#{
extension
}
"
}
end
unless
force_same_domain
force_host
=
webpack_public_host
if
force_host
paths
.
map!
{
|
p
|
"
#{
force_host
}#{
p
}
"
}
end
force_host
=
webpack_public_host
if
force_host
paths
.
map!
{
|
p
|
"
#{
force_host
}#{
p
}
"
}
end
paths
if
exclude_duplicates
@used_paths
||=
[]
new_paths
=
paths
-
@used_paths
@used_paths
+=
new_paths
new_paths
else
paths
end
end
def
webpack_public_host
...
...
app/views/ide/index.html.haml
View file @
73fd426d
-
@body_class
=
'ide'
-
page_title
'IDE'
-
content_for
:page_specific_javascripts
do
=
webpack_bundle_tag
'ide'
,
force_same_domain:
true
#ide
.ide-loading
{
data:
{
"empty-state-svg-path"
=>
image_path
(
'illustrations/multi_file_editor_empty.svg'
),
"no-changes-state-svg-path"
=>
image_path
(
'illustrations/multi-editor_no_changes_empty.svg'
),
"committed-state-svg-path"
=>
image_path
(
'illustrations/multi-editor_all_changes_committed_empty.svg'
)
}
}
...
...
app/views/layouts/_head.html.haml
View file @
73fd426d
...
...
@@ -38,9 +38,6 @@
=
yield
:library_javascripts
=
javascript_include_tag
locale_path
unless
I18n
.
locale
==
:en
=
webpack_bundle_tag
"webpack_runtime"
=
webpack_bundle_tag
"common"
=
webpack_bundle_tag
"main"
=
webpack_bundle_tag
"raven"
if
Gitlab
::
CurrentSettings
.
clientside_sentry_enabled
-
if
content_for?
(
:page_specific_javascripts
)
...
...
config/initializers/static_files.rb
View file @
73fd426d
...
...
@@ -34,7 +34,7 @@ if app.config.serve_static_files
)
app
.
config
.
middleware
.
insert_before
(
Gitlab
::
Middleware
::
Static
,
Gitlab
::
Middleware
::
WebpackProxy
,
Gitlab
::
Webpack
::
DevServerMiddleware
,
proxy_path:
app
.
config
.
webpack
.
public_path
,
proxy_host:
dev_server
.
host
,
proxy_port:
dev_server
.
port
...
...
config/karma.config.js
View file @
73fd426d
...
...
@@ -12,16 +12,14 @@ function fatalError(message) {
process
.
exit
(
1
);
}
// remove problematic plugins
if
(
webpackConfig
.
plugins
)
{
webpackConfig
.
plugins
=
webpackConfig
.
plugins
.
filter
(
function
(
plugin
)
{
return
!
(
plugin
instanceof
webpack
.
optimize
.
CommonsChunkPlugin
||
plugin
instanceof
webpack
.
optimize
.
ModuleConcatenationPlugin
||
plugin
instanceof
webpack
.
DefinePlugin
);
});
}
// disable problematic options
webpackConfig
.
entry
=
undefined
;
webpackConfig
.
mode
=
'
development
'
;
webpackConfig
.
optimization
.
runtimeChunk
=
false
;
webpackConfig
.
optimization
.
splitChunks
=
false
;
// use quicker sourcemap option
webpackConfig
.
devtool
=
'
cheap-inline-source-map
'
;
const
specFilters
=
argumentsParser
.
option
(
...
...
@@ -77,9 +75,6 @@ if (specFilters.length) {
);
}
webpackConfig
.
entry
=
undefined
;
webpackConfig
.
devtool
=
'
cheap-inline-source-map
'
;
// Karma configuration
module
.
exports
=
function
(
config
)
{
process
.
env
.
TZ
=
'
Etc/UTC
'
;
...
...
config/webpack.config.js
View file @
73fd426d
const
crypto
=
require
(
'
crypto
'
);
const
fs
=
require
(
'
fs
'
);
const
path
=
require
(
'
path
'
);
const
glob
=
require
(
'
glob
'
);
...
...
@@ -6,9 +5,7 @@ const webpack = require('webpack');
const
StatsWriterPlugin
=
require
(
'
webpack-stats-plugin
'
).
StatsWriterPlugin
;
const
CopyWebpackPlugin
=
require
(
'
copy-webpack-plugin
'
);
const
CompressionPlugin
=
require
(
'
compression-webpack-plugin
'
);
const
NameAllModulesPlugin
=
require
(
'
name-all-modules-plugin
'
);
const
BundleAnalyzerPlugin
=
require
(
'
webpack-bundle-analyzer
'
).
BundleAnalyzerPlugin
;
const
WatchMissingNodeModulesPlugin
=
require
(
'
react-dev-utils/WatchMissingNodeModulesPlugin
'
);
const
ROOT_PATH
=
path
.
resolve
(
__dirname
,
'
..
'
);
const
IS_PRODUCTION
=
process
.
env
.
NODE_ENV
===
'
production
'
;
...
...
@@ -21,10 +18,12 @@ const NO_COMPRESSION = process.env.NO_COMPRESSION;
let
autoEntriesCount
=
0
;
let
watchAutoEntries
=
[];
const
defaultEntries
=
[
'
./main
'
];
function
generateEntries
()
{
// generate automatic entry points
const
autoEntries
=
{};
const
autoEntriesMap
=
{};
const
pageEntries
=
glob
.
sync
(
'
pages/**/index.js
'
,
{
cwd
:
path
.
join
(
ROOT_PATH
,
'
app/assets/javascripts
'
),
});
...
...
@@ -33,7 +32,7 @@ function generateEntries() {
function
generateAutoEntries
(
path
,
prefix
=
'
.
'
)
{
const
chunkPath
=
path
.
replace
(
/
\/
index
\.
js$/
,
''
);
const
chunkName
=
chunkPath
.
replace
(
/
\/
/g
,
'
.
'
);
autoEntries
[
chunkName
]
=
`
${
prefix
}
/
${
path
}
`
;
autoEntries
Map
[
chunkName
]
=
`
${
prefix
}
/
${
path
}
`
;
}
pageEntries
.
forEach
(
path
=>
generateAutoEntries
(
path
));
...
...
@@ -43,22 +42,35 @@ function generateEntries() {
cwd
:
path
.
join
(
ROOT_PATH
,
'
ee/app/assets/javascripts
'
),
});
eePageEntries
.
forEach
(
path
=>
generateAutoEntries
(
path
,
'
ee
'
));
watchAutoEntries
.
concat
(
path
.
join
(
ROOT_PATH
,
'
ee/app/assets/javascripts/pages/
'
));
autoEntriesCount
=
Object
.
keys
(
autoEntries
).
length
;
watchAutoEntries
.
push
(
path
.
join
(
ROOT_PATH
,
'
ee/app/assets/javascripts/pages/
'
));
const
autoEntryKeys
=
Object
.
keys
(
autoEntriesMap
);
autoEntriesCount
=
autoEntryKeys
.
length
;
// import ancestor entrypoints within their children
autoEntryKeys
.
forEach
(
entry
=>
{
const
entryPaths
=
[
autoEntriesMap
[
entry
]];
const
segments
=
entry
.
split
(
'
.
'
);
while
(
segments
.
pop
())
{
const
ancestor
=
segments
.
join
(
'
.
'
);
if
(
autoEntryKeys
.
includes
(
ancestor
))
{
entryPaths
.
unshift
(
autoEntriesMap
[
ancestor
]);
}
}
autoEntries
[
entry
]
=
defaultEntries
.
concat
(
entryPaths
);
});
const
manualEntries
=
{
common
:
'
./commons/index.js
'
,
main
:
'
./main.js
'
,
default
:
defaultEntries
,
raven
:
'
./raven/index.js
'
,
webpack_runtime
:
'
./webpack.js
'
,
ide
:
'
./ide/index.js
'
,
};
return
Object
.
assign
(
manualEntries
,
autoEntries
);
}
const
config
=
{
mode
:
IS_PRODUCTION
?
'
production
'
:
'
development
'
,
context
:
path
.
join
(
ROOT_PATH
,
'
app/assets/javascripts
'
),
entry
:
generateEntries
,
...
...
@@ -66,8 +78,36 @@ const config = {
output
:
{
path
:
path
.
join
(
ROOT_PATH
,
'
public/assets/webpack
'
),
publicPath
:
'
/assets/webpack/
'
,
filename
:
IS_PRODUCTION
?
'
[name].[chunkhash].bundle.js
'
:
'
[name].bundle.js
'
,
chunkFilename
:
IS_PRODUCTION
?
'
[name].[chunkhash].chunk.js
'
:
'
[name].chunk.js
'
,
filename
:
IS_PRODUCTION
?
'
[name].[chunkhash:8].bundle.js
'
:
'
[name].bundle.js
'
,
chunkFilename
:
IS_PRODUCTION
?
'
[name].[chunkhash:8].chunk.js
'
:
'
[name].chunk.js
'
,
globalObject
:
'
this
'
,
// allow HMR and web workers to play nice
},
optimization
:
{
nodeEnv
:
false
,
runtimeChunk
:
'
single
'
,
splitChunks
:
{
maxInitialRequests
:
4
,
cacheGroups
:
{
default
:
false
,
common
:
()
=>
({
priority
:
20
,
name
:
'
main
'
,
chunks
:
'
initial
'
,
minChunks
:
autoEntriesCount
*
0.9
,
}),
vendors
:
{
priority
:
10
,
chunks
:
'
async
'
,
test
:
/
[\\/](
node_modules|vendor
[\\/]
assets
[\\/]
javascripts
)[\\/]
/
,
},
commons
:
{
chunks
:
'
all
'
,
minChunks
:
2
,
reuseExistingChunk
:
true
,
},
},
},
},
module
:
{
...
...
@@ -99,10 +139,10 @@ const config = {
{
loader
:
'
worker-loader
'
,
options
:
{
inline
:
true
,
name
:
'
[name].[hash:8].worker.js
'
,
},
},
{
loader
:
'
babel-loader
'
}
,
'
babel-loader
'
,
],
},
{
...
...
@@ -110,7 +150,7 @@ const config = {
exclude
:
/node_modules/
,
loader
:
'
file-loader
'
,
options
:
{
name
:
'
[name].[hash].[ext]
'
,
name
:
'
[name].[hash
:8
].[ext]
'
,
},
},
{
...
...
@@ -121,7 +161,7 @@ const config = {
{
loader
:
'
css-loader
'
,
options
:
{
name
:
'
[name].[hash].[ext]
'
,
name
:
'
[name].[hash
:8
].[ext]
'
,
},
},
],
...
...
@@ -131,7 +171,7 @@ const config = {
include
:
/node_modules
\/
katex
\/
dist
\/
fonts/
,
loader
:
'
file-loader
'
,
options
:
{
name
:
'
[name].[hash].[ext]
'
,
name
:
'
[name].[hash
:8
].[ext]
'
,
},
},
{
...
...
@@ -173,54 +213,6 @@ const config = {
jQuery
:
'
jquery
'
,
}),
// assign deterministic module ids
new
webpack
.
NamedModulesPlugin
(),
new
NameAllModulesPlugin
(),
// assign deterministic chunk ids
new
webpack
.
NamedChunksPlugin
(
chunk
=>
{
if
(
chunk
.
name
)
{
return
chunk
.
name
;
}
const
moduleNames
=
[];
function
collectModuleNames
(
m
)
{
// handle ConcatenatedModule which does not have resource nor context set
if
(
m
.
modules
)
{
m
.
modules
.
forEach
(
collectModuleNames
);
return
;
}
const
pagesBase
=
path
.
join
(
ROOT_PATH
,
'
app/assets/javascripts/pages
'
);
if
(
m
.
resource
.
indexOf
(
pagesBase
)
===
0
)
{
moduleNames
.
push
(
path
.
relative
(
pagesBase
,
m
.
resource
)
.
replace
(
/
\/
index
\.[
a-z
]
+$/
,
''
)
.
replace
(
/
\/
/g
,
'
__
'
)
);
}
else
{
moduleNames
.
push
(
path
.
relative
(
m
.
context
,
m
.
resource
));
}
}
chunk
.
forEachModule
(
collectModuleNames
);
const
hash
=
crypto
.
createHash
(
'
sha256
'
)
.
update
(
moduleNames
.
join
(
'
_
'
))
.
digest
(
'
hex
'
);
return
`
${
moduleNames
[
0
]}
-
${
hash
.
substr
(
0
,
6
)}
`
;
}),
// create cacheable common library bundles
new
webpack
.
optimize
.
CommonsChunkPlugin
({
names
:
[
'
main
'
,
'
common
'
,
'
webpack_runtime
'
],
}),
// copy pre-compiled vendor libraries verbatim
new
CopyWebpackPlugin
([
{
...
...
@@ -273,20 +265,6 @@ const config = {
if
(
IS_PRODUCTION
)
{
config
.
devtool
=
'
source-map
'
;
config
.
plugins
.
push
(
new
webpack
.
NoEmitOnErrorsPlugin
(),
new
webpack
.
LoaderOptionsPlugin
({
minimize
:
true
,
debug
:
false
,
}),
new
webpack
.
optimize
.
ModuleConcatenationPlugin
(),
new
webpack
.
optimize
.
UglifyJsPlugin
({
sourceMap
:
true
,
}),
new
webpack
.
DefinePlugin
({
'
process.env
'
:
{
NODE_ENV
:
JSON
.
stringify
(
'
production
'
)
},
})
);
// compression can require a lot of compute time and is disabled in CI
if
(
!
NO_COMPRESSION
)
{
...
...
@@ -305,29 +283,30 @@ if (IS_DEV_SERVER) {
hot
:
DEV_SERVER_LIVERELOAD
,
inline
:
DEV_SERVER_LIVERELOAD
,
};
config
.
plugins
.
push
(
// watch node_modules for changes if we encounter a missing module compile error
new
WatchMissingNodeModulesPlugin
(
path
.
join
(
ROOT_PATH
,
'
node_modules
'
)),
// watch for changes to our automatic entry point modules
{
apply
(
compiler
)
{
compiler
.
plugin
(
'
emit
'
,
(
compilation
,
callback
)
=>
{
compilation
.
contextDependencies
=
[
...
compilation
.
contextDependencies
,
...
watchAutoEntries
,
];
// report our auto-generated bundle count
console
.
log
(
`
${
autoEntriesCount
}
entries from '/pages' automatically added to webpack output.`
);
callback
();
});
},
}
);
config
.
plugins
.
push
({
apply
(
compiler
)
{
compiler
.
hooks
.
emit
.
tapAsync
(
'
WatchForChangesPlugin
'
,
(
compilation
,
callback
)
=>
{
const
missingDeps
=
Array
.
from
(
compilation
.
missingDependencies
);
const
nodeModulesPath
=
path
.
join
(
ROOT_PATH
,
'
node_modules
'
);
const
hasMissingNodeModules
=
missingDeps
.
some
(
file
=>
file
.
indexOf
(
nodeModulesPath
)
!==
-
1
);
// watch for changes to missing node_modules
if
(
hasMissingNodeModules
)
compilation
.
contextDependencies
.
add
(
nodeModulesPath
);
// watch for changes to automatic entrypoints
watchAutoEntries
.
forEach
(
watchPath
=>
compilation
.
contextDependencies
.
add
(
watchPath
));
// report our auto-generated bundle count
console
.
log
(
`
${
autoEntriesCount
}
entries from '/pages' automatically added to webpack output.`
);
callback
();
});
},
});
if
(
DEV_SERVER_LIVERELOAD
)
{
config
.
plugins
.
push
(
new
webpack
.
HotModuleReplacementPlugin
());
}
...
...
ee/app/assets/javascripts/pages/projects/issues/service_desk/index.js
View file @
73fd426d
...
...
@@ -5,7 +5,7 @@ document.addEventListener('DOMContentLoaded', () => {
document
.
querySelector
(
'
.js-service-desk-issues
'
).
dataset
.
supportBot
,
);
this
.
filteredSearchManager
=
new
FilteredSearchServiceDesk
(
supportBotData
);
const
filteredSearchManager
=
new
FilteredSearchServiceDesk
(
supportBotData
);
this
.
filteredSearchManager
.
setup
();
filteredSearchManager
.
setup
();
});
lib/gitlab/
middleware/webpack_proxy
.rb
→
lib/gitlab/
webpack/dev_server_middleware
.rb
View file @
73fd426d
...
...
@@ -3,8 +3,8 @@
# :nocov:
module
Gitlab
module
Middleware
class
WebpackProxy
<
Rack
::
Proxy
module
Webpack
class
DevServerMiddleware
<
Rack
::
Proxy
def
initialize
(
app
=
nil
,
opts
=
{})
@proxy_host
=
opts
.
fetch
(
:proxy_host
,
'localhost'
)
@proxy_port
=
opts
.
fetch
(
:proxy_port
,
3808
)
...
...
lib/gitlab/webpack/manifest.rb
0 → 100644
View file @
73fd426d
require
'webpack/rails/manifest'
module
Gitlab
module
Webpack
class
Manifest
<
::
Webpack
::
Rails
::
Manifest
# Raised if a supplied asset does not exist in the webpack manifest
AssetMissingError
=
Class
.
new
(
StandardError
)
class
<<
self
def
entrypoint_paths
(
source
)
raise
::
Webpack
::
Rails
::
Manifest
::
WebpackError
,
manifest
[
"errors"
]
unless
manifest_bundled?
entrypoint
=
manifest
[
"entrypoints"
][
source
]
if
entrypoint
&&
entrypoint
[
"assets"
]
# Can be either a string or an array of strings.
# Do not include source maps as they are not javascript
[
entrypoint
[
"assets"
]].
flatten
.
reject
{
|
p
|
p
=~
/.*\.map$/
}.
map
do
|
p
|
"/
#{
::
Rails
.
configuration
.
webpack
.
public_path
}
/
#{
p
}
"
end
else
raise
AssetMissingError
,
"Can't find entry point '
#{
source
}
' in webpack manifest"
end
end
end
end
end
end
package.json
View file @
73fd426d
...
...
@@ -19,8 +19,8 @@
"
@gitlab-org/gitlab-svgs
"
:
"
^1.18.0
"
,
"
autosize
"
:
"
^4.0.0
"
,
"
axios
"
:
"
^0.17.1
"
,
"
babel-core
"
:
"
^6.26.
0
"
,
"
babel-loader
"
:
"
^7.1.
2
"
,
"
babel-core
"
:
"
^6.26.
3
"
,
"
babel-loader
"
:
"
^7.1.
4
"
,
"
babel-plugin-transform-define
"
:
"
^1.3.0
"
,
"
babel-preset-latest
"
:
"
^6.24.1
"
,
"
babel-preset-stage-2
"
:
"
^6.24.1
"
,
...
...
@@ -30,11 +30,11 @@
"
chart.js
"
:
"
1.0.2
"
,
"
classlist-polyfill
"
:
"
^1.2.0
"
,
"
clipboard
"
:
"
^1.7.1
"
,
"
compression-webpack-plugin
"
:
"
^1.1.
7
"
,
"
copy-webpack-plugin
"
:
"
^4.
4
.1
"
,
"
compression-webpack-plugin
"
:
"
^1.1.
11
"
,
"
copy-webpack-plugin
"
:
"
^4.
5
.1
"
,
"
core-js
"
:
"
^2.4.1
"
,
"
cropper
"
:
"
^2.3.0
"
,
"
css-loader
"
:
"
^0.28.
9
"
,
"
css-loader
"
:
"
^0.28.
11
"
,
"
d3-array
"
:
"
^1.2.1
"
,
"
d3-axis
"
:
"
^1.0.8
"
,
"
d3-brush
"
:
"
^1.0.4
"
,
...
...
@@ -51,7 +51,7 @@
"
dropzone
"
:
"
^4.2.0
"
,
"
emoji-unicode-version
"
:
"
^0.2.1
"
,
"
exports-loader
"
:
"
^0.7.0
"
,
"
file-loader
"
:
"
^1.1.
8
"
,
"
file-loader
"
:
"
^1.1.
11
"
,
"
fuzzaldrin-plus
"
:
"
^0.5.0
"
,
"
glob
"
:
"
^7.1.2
"
,
"
imports-loader
"
:
"
^0.8.0
"
,
...
...
@@ -66,24 +66,22 @@
"
marked
"
:
"
^0.3.12
"
,
"
monaco-editor
"
:
"
0.10.0
"
,
"
mousetrap
"
:
"
^1.4.6
"
,
"
name-all-modules-plugin
"
:
"
^1.0.1
"
,
"
pikaday
"
:
"
^1.6.1
"
,
"
prismjs
"
:
"
^1.6.0
"
,
"
raphael
"
:
"
^2.2.7
"
,
"
raven-js
"
:
"
^3.22.1
"
,
"
raw-loader
"
:
"
^0.5.1
"
,
"
react-dev-utils
"
:
"
^5.0.0
"
,
"
sanitize-html
"
:
"
^1.16.1
"
,
"
select2
"
:
"
3.5.2-browserify
"
,
"
sql.js
"
:
"
^0.4.0
"
,
"
style-loader
"
:
"
^0.2
0.2
"
,
"
style-loader
"
:
"
^0.2
1.0
"
,
"
svg4everybody
"
:
"
2.1.9
"
,
"
three
"
:
"
^0.84.0
"
,
"
three-orbit-controls
"
:
"
^82.1.0
"
,
"
three-stl-loader
"
:
"
^1.0.4
"
,
"
timeago.js
"
:
"
^3.0.2
"
,
"
underscore
"
:
"
^1.8.3
"
,
"
url-loader
"
:
"
^
0.6.2
"
,
"
url-loader
"
:
"
^
1.0.1
"
,
"
visibilityjs
"
:
"
^1.2.4
"
,
"
vue
"
:
"
^2.5.16
"
,
"
vue-loader
"
:
"
^14.1.1
"
,
...
...
@@ -92,10 +90,11 @@
"
vue-template-compiler
"
:
"
^2.5.16
"
,
"
vue-virtual-scroll-list
"
:
"
^1.2.5
"
,
"
vuex
"
:
"
^3.0.1
"
,
"
webpack
"
:
"
^3.11.0
"
,
"
webpack-bundle-analyzer
"
:
"
^2.10.0
"
,
"
webpack-stats-plugin
"
:
"
^0.1.5
"
,
"
worker-loader
"
:
"
^1.1.0
"
"
webpack
"
:
"
^4.7.0
"
,
"
webpack-bundle-analyzer
"
:
"
^2.11.1
"
,
"
webpack-cli
"
:
"
^2.1.2
"
,
"
webpack-stats-plugin
"
:
"
^0.2.1
"
,
"
worker-loader
"
:
"
^1.1.1
"
},
"devDependencies"
:
{
"
axios-mock-adapter
"
:
"
^1.10.0
"
,
...
...
@@ -126,8 +125,8 @@
"
karma-mocha-reporter
"
:
"
^2.2.5
"
,
"
karma-sourcemap-loader
"
:
"
^0.3.7
"
,
"
karma-webpack
"
:
"
3.0.0
"
,
"
nodemon
"
:
"
^1.1
5.1
"
,
"
nodemon
"
:
"
^1.1
7.3
"
,
"
prettier
"
:
"
1.11.1
"
,
"
webpack-dev-server
"
:
"
^
2.11.2
"
"
webpack-dev-server
"
:
"
^
3.1.4
"
}
}
spec/features/raven_js_spec.rb
View file @
73fd426d
require
'spec_helper'
feature
'RavenJS'
do
let
(
:raven_path
)
{
'/raven.
bundle
.js'
}
let
(
:raven_path
)
{
'/raven.
chunk
.js'
}
it
'should not load raven if sentry is disabled'
do
visit
new_user_session_path
...
...
spec/javascripts/pipelines/graph/linked_pipeline_spec.js
View file @
73fd426d
...
...
@@ -5,7 +5,7 @@ import mockData from './linked_pipelines_mock_data';
const
LinkedPipeline
=
Vue
.
extend
(
LinkedPipelineComponent
);
const
mockPipeline
=
mockData
.
triggered
[
0
];
describe
(
'
Linked pipeline
'
,
()
=>
{
describe
(
'
Linked pipeline
'
,
function
()
{
beforeEach
(()
=>
{
this
.
propsData
=
{
pipelineId
:
mockPipeline
.
id
,
...
...
@@ -38,7 +38,9 @@ describe('Linked pipeline', () => {
});
it
(
'
should render the project name
'
,
()
=>
{
const
projectNameElement
=
this
.
linkedPipeline
.
$el
.
querySelector
(
'
.linked-pipeline-project-name
'
);
const
projectNameElement
=
this
.
linkedPipeline
.
$el
.
querySelector
(
'
.linked-pipeline-project-name
'
,
);
expect
(
projectNameElement
.
innerText
).
toContain
(
this
.
propsData
.
projectName
);
});
...
...
@@ -55,7 +57,9 @@ describe('Linked pipeline', () => {
it
(
'
should render the correct pipeline status icon style selector
'
,
()
=>
{
const
pipelineStatusElement
=
this
.
linkedPipeline
.
$el
.
querySelector
(
'
.linked-pipeline-status
'
);
expect
(
pipelineStatusElement
.
firstChild
.
classList
.
contains
(
'
ci-status-icon-running
'
)).
toBe
(
true
);
expect
(
pipelineStatusElement
.
firstChild
.
classList
.
contains
(
'
ci-status-icon-running
'
)).
toBe
(
true
,
);
});
it
(
'
should have a ci-status child component
'
,
()
=>
{
...
...
spec/javascripts/pipelines/graph/linked_pipelines_column_spec.js
View file @
73fd426d
...
...
@@ -4,7 +4,7 @@ import mockData from './linked_pipelines_mock_data';
const
LinkedPipelinesColumnComponent
=
Vue
.
extend
(
LinkedPipelinesColumn
);
describe
(
'
Linked Pipelines Column
'
,
()
=>
{
describe
(
'
Linked Pipelines Column
'
,
function
()
{
beforeEach
(()
=>
{
this
.
propsData
=
{
columnTitle
:
'
Upstream
'
,
...
...
@@ -22,7 +22,9 @@ describe('Linked Pipelines Column', () => {
});
it
(
'
renders the pipeline orientation
'
,
()
=>
{
const
titleElement
=
this
.
linkedPipelinesColumn
.
$el
.
querySelector
(
'
.linked-pipelines-column-title
'
);
const
titleElement
=
this
.
linkedPipelinesColumn
.
$el
.
querySelector
(
'
.linked-pipelines-column-title
'
,
);
expect
(
titleElement
.
innerText
).
toContain
(
this
.
propsData
.
columnTitle
);
});
...
...
@@ -31,8 +33,9 @@ describe('Linked Pipelines Column', () => {
});
it
(
'
renders the correct number of linked pipelines
'
,
()
=>
{
const
linkedPipelineElements
=
this
.
linkedPipelinesColumn
.
$el
.
querySelectorAll
(
'
.linked-pipeline
'
);
const
linkedPipelineElements
=
this
.
linkedPipelinesColumn
.
$el
.
querySelectorAll
(
'
.linked-pipeline
'
,
);
expect
(
linkedPipelineElements
.
length
).
toBe
(
this
.
propsData
.
linkedPipelines
.
length
);
});
});
spec/javascripts/sidebar/ee_sidebar_mediator_spec.js
View file @
73fd426d
...
...
@@ -6,7 +6,7 @@ import CESidebarStore from '~/sidebar/stores/sidebar_store';
import
SidebarService
from
'
~/sidebar/services/sidebar_service
'
;
import
Mock
from
'
./ee_mock_data
'
;
describe
(
'
EE Sidebar mediator
'
,
()
=>
{
describe
(
'
EE Sidebar mediator
'
,
function
()
{
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
Mock
.
sidebarMockInterceptor
);
this
.
mediator
=
new
SidebarMediator
(
Mock
.
mediator
);
...
...
@@ -20,7 +20,8 @@ describe('EE Sidebar mediator', () => {
});
it
(
'
processes fetched data
'
,
()
=>
{
const
mockData
=
Mock
.
responseMap
.
GET
[
'
/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar
'
];
const
mockData
=
Mock
.
responseMap
.
GET
[
'
/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar
'
];
this
.
mediator
.
processFetchedData
(
mockData
);
expect
(
this
.
mediator
.
store
.
weight
).
toEqual
(
mockData
.
weight
);
...
...
spec/javascripts/vue_shared/components/linked_pipelines_mini_list_spec.js
View file @
73fd426d
...
...
@@ -4,7 +4,7 @@ import mockData from 'spec/pipelines/graph/linked_pipelines_mock_data';
const
ListComponent
=
Vue
.
extend
(
LinkedPipelinesMiniList
);
describe
(
'
Linked pipeline mini list
'
,
()
=>
{
describe
(
'
Linked pipeline mini list
'
,
function
()
{
describe
(
'
when passed an upstream pipeline as prop
'
,
()
=>
{
beforeEach
(()
=>
{
this
.
component
=
new
ListComponent
({
...
...
@@ -68,7 +68,11 @@ describe('Linked pipeline mini list', () => {
});
it
(
'
should render one linked pipeline item
'
,
()
=>
{
expect
(
this
.
component
.
$el
.
querySelectorAll
(
'
.linked-pipeline-mini-item:not(.linked-pipelines-counter)
'
).
length
).
toBe
(
3
);
expect
(
this
.
component
.
$el
.
querySelectorAll
(
'
.linked-pipeline-mini-item:not(.linked-pipelines-counter)
'
,
).
length
,
).
toBe
(
3
);
});
it
(
'
should render three ci status icons
'
,
()
=>
{
...
...
@@ -110,11 +114,17 @@ describe('Linked pipeline mini list', () => {
});
it
(
'
should set the correct pipeline path
'
,
()
=>
{
expect
(
this
.
component
.
$el
.
querySelector
(
'
.linked-pipelines-counter
'
).
getAttribute
(
'
href
'
)).
toBe
(
'
my/pipeline/path
'
);
expect
(
this
.
component
.
$el
.
querySelector
(
'
.linked-pipelines-counter
'
).
getAttribute
(
'
href
'
),
).
toBe
(
'
my/pipeline/path
'
);
});
it
(
'
should render the correct counterTooltipText
'
,
()
=>
{
expect
(
this
.
component
.
$el
.
querySelector
(
'
.linked-pipelines-counter
'
).
getAttribute
(
'
data-original-title
'
)).
toBe
(
this
.
component
.
counterTooltipText
);
expect
(
this
.
component
.
$el
.
querySelector
(
'
.linked-pipelines-counter
'
)
.
getAttribute
(
'
data-original-title
'
),
).
toBe
(
this
.
component
.
counterTooltipText
);
});
});
});
yarn.lock
View file @
73fd426d
This source diff could not be displayed because it is too large. You can
view the blob
instead.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment