Skip to content
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 updates #1120

Closed

Conversation

salvatore-fxpig
Copy link
Contributor

Description of proposed changes

This pull request changes some elements in webpack config, namely:

  • Forces aliasing of react and react utilities to allow better compatibility with out-of-root-folder extensions
  • Normalizes use of react-hot-loader
  • Forces resolution of modules to pre-transpiled code where available (which is almost everywhere), hopefully alleviating the problem with non-transpiled code appearing in the final bundle and breaking compatibility with old browser
  • Moves to eval-source-map because why not go with the best quality if it's only for debugging (note: I tried debugging performance using cheap-module-source-map and it was utterly impossible, everything was mapped to the bundles xD)

Related issue(s)

#902

Testing

A general smoke test should suffice probably... !

Thank you for contributing to Nextstrain!

@salvatore-fxpig
Copy link
Contributor Author

The check fail triggered my curiosity a bit about the packaging.

There's a couple of "easy" optimizations in there that could save a couple of k (react-select, d3-range), then a couple more complex ones (chunking away react-ga and the locales folder.

If you have strong concerns for bundle size, have you considered keeping a separate vendor bundle ? It would not affect worst-case loading time at all, but it would improve average loading time significantly.

@salvatore-fxpig
Copy link
Contributor Author

As alternative to loading modules: ["main" ...] one could babelize node_modules, lots of people doing that now, takes a bit more to compile but should be safer from the point of view of adding new extensions in the future, and saves a bit of package size as well.

@jameshadfield jameshadfield temporarily deployed to auspice-webpack-updates-5idcpu May 13, 2020 06:14 Inactive
@jameshadfield jameshadfield temporarily deployed to auspice-webpack-updates-5idcpu May 14, 2020 11:41 Inactive
Copy link
Member

@jameshadfield jameshadfield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this -- there are a lot of webpack improvements possible within auspice & it's been a while since I dived into this.

There's a couple of "easy" optimizations in there that could save a couple of k (react-select, d3-range), then a couple more complex ones (chunking away react-ga and the locales folder.

Would like to explore these, but caching is probably a better investment right now. I've just seen #1126 which does all of this!

If you have strong concerns for bundle size, have you considered keeping a separate vendor bundle ? It would not affect worst-case loading time at all, but it would improve average loading time significantly.

I think we need to be doing this in the medium-term future, but it'll add in an extra layer of complexity which is why I haven't explored it yet. Adding hashes to the bundles and allowing them to be cached may be a better solution, or one which should be implemented first (currently the bundles have a cache max-age=0) I've just seen #1126 which does all of this!


[regression] the hot-reloading implementation in this PR exhibits strange behavior in that the first modification to source code triggers a bundle rebuild & the browser automatically updates-in-place, however subsequent modifications to source code don't update the browser-in-place (refreshing the browser must be done). Seems to be a regression compared with current master.

[bug] this doesn't build when auspice is used as a dependency of a project, with auspice-client-customisations which import react via:

import React from "react"; 
ERROR in /Users/naboo/github/nextstrain/nextstrain.org/auspice-client/customisations/navbar.js
Module not found: Error: Can't resolve 'react' in '/Users/naboo/github/nextstrain/nextstrain.org/auspice-client/customisations'
 @ /Users/naboo/github/nextstrain/nextstrain.org/auspice-client/customisations/navbar.js 20:0-26 89:22-27 97:22-27 102:24-29 112:22-27 147:26-31 217:2-7 228:22-27 230:18-23 234:18-23 238:74-79 242:19-24 244:42-47 248:18-23 252:103-108 254:181-186
 @ /Users/naboo/github/nextstrain/nextstrain.org/auspice-client/customisations sync ^\.\/.*$
 @ ./src/util/extensions.js
 @ ./src/util/googleAnalytics.js
 @ ./src/index.js
 @ multi babel-polyfill ./src/index

To reproduce, you can clone the nextstrain.org repo using branch testing-auspice-pr-1120 and run the following:

npm install
npm run build

"@libraries": path.join(__dirname, 'node_modules')
"@libraries": path.join(__dirname, 'node_modules'),
// Pins all react stuff to auspice dir, and uses hot loader's dom (can be used safely in production)
"react": path.join(__dirname, 'node_modules/react'), // eslint-disable-line quote-props
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When auspice is a dependency of a project X, then __dirname does point to the correct location (X/node_modules/auspice) however react is not present within X/node_modules/auspice/node_modules for reasons unknown to me.

I think this approach is the right one in order to ensure that customisations use the same libraries as "core" auspice. My original idea was to force customisations to import code via import react from "@libraries/react" but this also had problems. I remember that approach worked when auspice was a global install, but not when it was a "normal" dependency, and these were perhaps the same issues as we're seeing now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had a look and while it feels like a bit of a "nuclear" option, explicitly looking for the "root" node_modules folder in the webpack config seems to do the trick.

As for the hot loader thing, could you verify if #1126 has the same problem ? I remember resolving this but it was fairly entangled with the react-i18n module IIRC so if it works in #1126 I'd rather not do it twice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems by some lucky combination the hot loader actually works well without using the hot-loader dom nor the patch/import, so I pushed a micro commit that reverts those changes and removes the regression.

A more extensive, hopefully more stable solution using the "recommended" implementation of react-hot-loader is found in #1126 and requires a bit of fiddling with react-i18n.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1126 still isn't perfect, but i'd rather pursue the stable solution, even if we do it in a subsequent PR.

@jameshadfield
Copy link
Member

Going to close this, as #1126 is much more complete (albeit with a few tweaks needed).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants