-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Webpack #1476
Webpack #1476
Conversation
For the package task, I think it would be appropriate to remove it. It is only there for publishing on pypi, which most people will never do. We could possibly put the equivalent command as a one liner npm script. |
Are we punting on coverage for now, or is that still in the works? |
@jbeezley oh sorry, no punting, I had forgotten to put it there, good catch. I need to do a quick experiment with SitePen/remap-istanbul: A tool for remapping Istanbul coverage via Source Maps (and gotwarlost/babel-coverage to some extent). |
@sebastienbarre https://github.com/Kitware/candela also performs source-mapped coverage through Babel. If what we do can help inform your process (or vice-versa) it would be good to have a uniform solution. |
Candela uses karma to handle those complexities. Porting existing tests to use karma would be a significant undertaking which is why I suspect @sebastienbarre has chosen a more direct approach. |
Thanks for the write-up. My vote would be that we should get coverage working on this branch, then merge it and leave additional stuff to subsequent PR's. |
Ah ok, thanks for the explanation @jbeezley. |
There is also isparta for babel coverage if that helps. |
…ing is being worked out
Alright I'll write a quick remapper for the Blanket coverage files.
Line 23 was hit 167 times in ...
var View = __WEBPACK_IMPORTED_MODULE_1_backbone___default.a.View.extend({
constructor: function constructor(opts) {
// eslint-disable-line backbone/no-constructor
if (opts && __WEBPACK_IMPORTED_MODULE_0_underscore___default.a.has(opts, 'parentView')) {
... Line 23 is: if (opts && __WEBPACK_IMPORTED_MODULE_0_underscore___default.a.has(opts, 'parentView')) { This piece of Javascript I just tested: const sourceMap = require('source-map');
const fs = require('fs');
const SourceMapConsumer = sourceMap.SourceMapConsumer;
const checkSourceMap = filename => {
const rawSourceMap = JSON.parse(fs.readFileSync(filename));
const smc = new SourceMapConsumer(rawSourceMap);
console.log(smc.originalPositionFor({
line: 23,
column: 1
}));
};
checkSourceMap('girder/clients/web/static/built/girder.app.min.js.map'); will output:
now open import _ from 'underscore';
import Backbone from 'backbone';
import events from 'girder/events';
import eventStream from 'girder/utilities/EventStream';
var View = Backbone.View.extend({
constructor: function (opts) { // eslint-disable-line backbone/no-constructor
if (opts && _.has(opts, 'parentView')) { and line 9 is indeed: if (opts && _.has(opts, 'parentView')) { Thanks mozilla/source-map |
Great! Sounds like we are very close 😄 |
Pythoners? @zachmullen? Unfortunately I need to get going on my journey to NC. Could you guys take over please? :) Two issues:
but the mattrobenolt/python-sourcemap package I'm using in What's the protocol?
Thanks |
I'm on it. See you soon! On Sep 5, 2016 12:14 PM, "Sébastien Barré" notifications@github.com wrote:
|
Thanks Zach. To help you a bit:
Thanks! |
Travis is only showing two problems. One is the static analysis (McCabe complexity) of the combining script. The other is the fontello issue I already fixed on master. |
Conflicts: Gruntfile.js grunt_tasks/build.js package.json plugins/jobs/plugin_tests/jobsSpec.js plugins/jobs/web_client/views/JobDetailsWidget.js
@jbeezley there are several browser tests failing also, it's just that CTest is segfaulting during the coverage aggregation step, so there is no submission to CDash for the browser build. |
We are green, but we still have web client test failures on travis that are masked by CTest segfaulting. Anyone object if I go ahead and merge this into 2.0-integration and then fix our coverage and web client tests on a subsequent branch? |
👏 👏 |
🎆 🎉 🎈 |
grunt.config.merge({ | ||
curl: { | ||
fontello: { | ||
src: 'https://data.kitware.com/api/v1/file/57c5d1fc8d777f10f269dece/download', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm curious. Why are we not sticking the Fontello files directly in the repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered it, but it's around a 0.5MB diff every time we want to add or remove an icon. I don't care much either way though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I consider this a temporary solution until the network problems are resolved, or we find a different service entirely.
Here we go.
Scope
This PR holds all changes related to the ES6/ES2015 modularization of the Girder web client and 20+ of its plugins, as well as the subsequent bundling using Webpack.
Almost all source files have been updated to no longer rely on the global
girder
object/singleton. Specific functionalities, Jade templates, as well as Stylus/CSS styles must now be imported explicitly. For example:Importing on a "per-needed" basis will provide the added benefit of facilitating tree shaking and build-time checks.
Directory Structure
The directory structure in
clients\web\src
was not altered, but some functions/classes were moved to their own files. For example:auth.js
,constants.js
,dialog.js
,events.js
,misc.js
,rest.js
,router.js
,routes.js
,server.js
,collection.js
was moved tocollections\Collection.js
,model.js
was split intoModel.js
,AccessControlledModel.js
andMetadataMixin.js
inside themodels
subdir,plugin_utils.js
is now inutilities\PluginUtils.js
,utilities\jquery
subdir,Plugins
All plugins were cleaned-up to adopt the same directory structure and naming conventions as the core files, and to better convey which core files are being extended or wrapped. Specifically:
main.js
entry point,routes.js
,views
subdir,views/ItemPreviewWidget.js
,templates/itemPreviewWidget.jade
,stylesheets/itemPreviewWidget.styl
),wrap()
'ed is now to be found in a single file matching the same model/collection/view name and location (say,plugins/curation/web_client/views/HierarchyWidget.js
).Migration
I would recommend checking any collection, model, view, or plugin to help transitioning your own code. Search for instances of the
girder.
string to find the functions previously attached to thegirder
global namespace, and bring them into your code usingimport... from...
. Export your own code usingexport default ...
to make it available to the outside world as a module. Start a new plugin by copy/pasting an existing one.Note that it is still possible, although not recommended, to use a higher-level namespace.
For example, the old:
is now coded this way:
yet, it could also be written this way:
...but your bundler of choice (say, Webpack) would no longer be able to check at build-time if
fetchCurrentUser
is to be found ingirder/auth
. It could also be rewritten as:... but the risk here would be even higher, should the
auth
namespace or its contents be moved or renamed.Be aware that if you passed the
girder
global to a Jade template, you will now need to pass individual functions separately, and update the Jade template accordingly. For example:in
clients/web/src/views/body/CollectionsView.js
:becomes:
and in the corresponding
clients/web/src/templates/body/collectionList.jade
becomes:
Also note that a
girder
global is still available to facilitate testing, but only after the core Javascript bundles and all plugins have been loaded. It is nearly identical to the previously available global, but some functions were shuffled around, as described in the "Directory Structure" section.Tip: use
console.dir(girder)
to browse the new tree.then follow the same "path" to migrate to the new
import...from
statement:Importing from one plugin to another can be done using the
plugins/
prefix. For example,consider
JobStatus
being exported by thejobs
plugin in/plugins/jobs/web_client/JobStatus.js
:then later on used by the
worker
plugin in/plugins/worker/web_client/JobStatus.js
, like this (note that there is noweb_client
subdir here):TODO
Grunt Build-process
The old, Grunt build process is still in place. I do not advocate removing it actually, as Webpack is a bundler, not a task runner. It was nonetheless slimmed down, as
grunt_tasks/build.js
is almost 100% Webpack code at this point. A few Grunt plugins remain, and could potentially be removed in favor of Webpack (see such plugins as kevlened/copy-webpack-plugin as a replacement togrunt-contrib-copy
).grunt_tasks/dev.js
still usesgrunt-contrib-uglify
; it needs to be exercised, converted to the new modules, and likely fixed before it is Webpack'ed; UPDATE: soon to be webpack'ed,grunt_tasks/package.js
usesgrunt-shell
; it needs to be exercised and likely fixed,grunt_tasks/fontello.js
usesgrunt-contrib-copy
andgrunt-fontello
; it is functional and would likely be fine as is,grunt_tasks/plugin.js
still usesgrunt-contrib-copy
andgrunt-npm-install
; the code that handles Javascript, Jade, and Stylus for each plugin was moved and integrated into the single Webpack target ingrunt_tasks/build.js
; while plugins appear to be generated correctly, **a large section (starting atgrunt.file.expand()
) needs to be exercised and likely be fixed or removed*,grunt_tasks/sphinx.js
usesgrunt-shell
; it appears functional and would likely be fine left as is,grunt_tasks/swagger.js
usesgrunt-contrib-copy
andgrunt-contrib-stylus
; it is functional but could be Webpack'ed, or left as is,grunt_tasks/version.js
usesgrunt-file-creator
andgrunt-gitinfo
; it is functional and would likely be fine as is,Webpack
The Webpack target generates, in
clients\web\static\built
:girder.ext.min.js
andgirder.ext.min.css
(and corresponding source maps): all third-party/vendor Javascript and CSS (e.g. imported fromnode_modules
),girder.app.min.js
andgirder.app.min.css
(and corresponding source maps): all Girder core Javascript/Jade/CSS (e.g. found inclients\web\src
) used by the client and the plugins,plugin.min.js
andplugin.min.css
(and corresponding source maps) for each plugin, inplugins\name_of_plugin
: plugin code only, typically small, making calls intogirder.app
(andgirder.ext
),assets
subdirHowever:
girder.main.min.js
and eachplugin.min.js
; this needs to be investigated and fixed by myself (Seb; consider robertknight/webpack-bundle-size-analyzer), also consider theDllPlugin
, which would increase performance as well (Webpack Plugins we been keepin on the DLL, Optimizing Webpack for Faster React Builds, Optimizing Webpack build times and improving caching with DLL bundles, webpack/examples/dll). Also check trivago/parallel-webpack: Builds multi-config webpack projects in parallelwatch
target inbuild.js
needs to be converted to a similar capability compatible with Webpack; (usegrunt --watch
orgrunt webpack:watch
, forgrunt-contrib-watch
is too slow),$.girderModal()
looks too much like a side effect:import 'girder/utilities/jQuery';
; let's find a way to make it more explicit (check how jQuery does it nowadays), or restructure the files so that we have one prototype method per file, so that it would be more obvious why it's getting imported, e.g.import 'girder/utilities/jQuery/girderModal';
environment
anddebugJs
are used ingrunt_tasks/build.js
), but this will need some clean up later on,Testing
grunt_tasks/dev.js
, remove earlyreturn
in (grunt.registerTask
); I (Seb) could use some help for this one, from the original testing author Update: most tests are passing, but the way the test driver exists make it look like they are failing on some laptops,Plugins
All plugins were converted. Manual testing was performed to check that each plugin's UI is in place, using eye-ball technology.
plugins\autojoin\plugin_tests\autoJoin.spec
)Misc, Minor
constants.js
back to more relevant files, closer to the functions that most often use them?auth.js
,events.js
,rest.js
,router.js
, which essentially bundle utility functions, vs. the files inutilities
such asDialogHelper.js
,MiscFunctions.js
, orPluginUtils.js
, which also bundle utility functions. Are the former considered more important "utilities" then the latter? Or should they all be in theutilities
dir? Should some be merged somehow in the process? Or named more consistently?girder/router
exports{ router, splitRoute }
. Therefore, accessing the router from thegirder
singleton will look likegirder.router.router
; not ideal; consider renaminggirder/router
togirder/routing
to usegirder.routing.router
instead?girder/events
exports{ events, eventSream }
. Therefore, accessing the events object from thegirder
singleton will look likegirder.events.events
; not ideal; consider renaminggirder/events
togirder/eventing
to usegirder.eventing.events
instead?