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

Config webpack for lazy loading #1096

Closed
2 tasks
ChristopherChudzicki opened this issue Feb 28, 2023 · 3 comments
Closed
2 tasks

Config webpack for lazy loading #1096

ChristopherChudzicki opened this issue Feb 28, 2023 · 3 comments
Assignees

Comments

@ChristopherChudzicki
Copy link
Contributor

This is a technical detail of #648 that I think is best handled separately from the videoJS / nanogallery changes.

Webpack (and other bundling tools) support dynamic resource loading along the lines of:

// js bundle entrypoint
const loadVideoJs = () => import("./init_videojs").then(module => module.initVideoJs())

// init_videojs_example.js
import "videojs" // very large
const initVideoJs = () => { /* initialization code */ }

When a dynamic import like import("./init_videojs_example") is used:

  • webpack automatically splits our js into separate chunks, putting ./init_videojs_example and its dependencies in a separate chunk from the entrypoint
  • Initially, the chunk containing initVideoJs is not loaded. When the import is called (here via initVideoJs()) the corresponding chunk is loaded.

However, this does not work with our current webpack configuration because of how we've set set publicPath. Currently, lazy-loading like above results in requests like:

// in development ... wrong port 3000 should be 3001 (3000 is hugo, 3001 is webpack)
http://localhost:3000/static_sharedjs/base-theme_assets_js_init_videojs_example.js

// in production ... note the missing "/" after static_shared
http://localhost:3000/static_sharedjs/810.5c09f.js

Acceptance Criteria

  • lazy-loading like demonstrated above should be possible in ocw
  • our other assets should still load, both in production and in development.
@ChristopherChudzicki
Copy link
Contributor Author

ChristopherChudzicki commented Feb 28, 2023

The reason this is not working now is that when webpack tries to lookup the location of a dynamically imported module, it looks in publicPath. It almost works in production, but is farther from working in development.

In production, I believe we have publicPath set slightly wrong: it's missing a slash on the end (hence webpack looking in static_sharedjs rather than static_shared/js. (I suspect we've added Hugo code to tolerate the missing slash, which is why our assets load. But I'm not sure.) Easy fix.

In development, we run Hugo on port 3000 and webpack on port 3001. We set webpack asset URLs through Hugo: webpack_url.html partial prepends the webpack url to an input url. By using it, we indicate that assets should be loaded from localhost:3001.

But when webpack loads stuff dynamically, it uses URLs based on the publicPath set in webpack.dev.ts, and does not go through webpack_url.html partial.

What I think we should do is:
1. Fix the production publicPath to include a trailing /
2. Use an absolute URL as the development public path, http://localhost:3001/static_shared ... will need to either stop using webpack_url when including js/css, or edit webpack_url to not alter fully qualified urls.

There are some aspects of webpack_url.html partial that confuse me... Maybe we can talk to @gumaerc about it tomorrow.

@ChristopherChudzicki
Copy link
Contributor Author

As mentioend in meeting this morning, I think our best course of action is to replace WebpackDevServer (webpack serve) with webpack's watch mode watch --watch. Using watch mode, webpack will write files to disk. If we put them in base-theme/static/static_shared, then, because theya re in a static directory, Hugo will find them and monitor the webpack files for changes. So:

  • hugo server will have the files available at 3000, same port it runs on, and life is simpler
  • since webpack is running in watch mode, we'll get file changes, and hugo should respond to that

In particular, having everything on one port makes the dynamic module loading much simpler.

I did a little experimentation with this after our meeting. This branch: https://github.com/mitodl/ocw-hugo-themes/pull/new/cc/ww. I think it is largely working, but I haven't tested it too thoroughly.

Going to leave this to you and @MAbdurrehman12 , but ask me questions!

@MAbdurrehman12
Copy link
Contributor

@ChristopherChudzicki Great stuff 👏

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

No branches or pull requests

3 participants