Skip to content
This repository has been archived by the owner on Mar 5, 2020. It is now read-only.

Use webpack to (re)generate index HTML files #839

Merged
merged 20 commits into from
May 14, 2015

Conversation

toolness
Copy link
Contributor

While researching #585 I ran into jlongster's Backend Apps with Webpack series of posts and decided to familiarize myself with using webpack in node (as opposed to the browser) by using it to watch and rebuild our static index files during gulp watch.

This has a number of benefits:

  • Rebuilding index HTML files is a lot faster. We don't have to spawn a subprocess anymore, and webpack rebuilds only the code that's changed.
  • Index HTML files are only rebuilt when an actual file they use changes. Currently, for example, changing lib/travis.js will trigger a full rebuild of the index HTML files, even though that file has nothing to do with rebuilding index HTML files.
  • We can reuse more of our webpack code pipeline in node, rather than relying on a completely separate build toolchain (in the form of node-jsx). We haven't completely decoupled ourselves from that toolchain yet, as everything outside of gulp watch still uses it, but the plan is to migrate away from it, so that our build toolchain is ultimately simplified. We're still using node-jsx but only for running node-side tests. This should also make migrating to Use a lightweight server that dynamically renders HTML #585 (and quickly iterating on the server during development) easier.

Limitations:

  • We're not rebuilding the sitemap.xml file in gulp watch anymore. Hopefully not that big a deal.
  • Until we've completely replaced our use of node-jsx with webpack, we're moving away from dev/prod parity, which isn't awesome. So we should finish that migration ASAP.
  • Running the test/index-static.test.js test is slower because it builds the webpack bundle now, but I'd rather it just run slower than assume the developer manually builds it before running the test, and then have devs get frustrated when they change the code but the tests still fail.
  • We're building the index HTML generator bundle in dist/index-static, which probably isn't awesome because it's really just an intermediate file that isn't intended for distribution. As such, we should probably put it in some sort of intermediate directory that's also in our .gitignore. The index HTML generator bundle is in the build directory, intended for intermediate build files rather than files to be distributed.

@toolness toolness added this to the The Wiz milestone Apr 29, 2015
@toolness toolness changed the title [WIP] Use webpack to watch and regenerate index HTML files [WIP] Use webpack to (re)generate index HTML files Apr 29, 2015
@toolness
Copy link
Contributor Author

@mmmavis do you want to take a look at this one? It's a bit of a doozy so no worries if not, but I think you could learn a lot from it. This stuff is also pretty new to me, so I could use a second opinion :)

If you accept the mission, I recommend trying out the following to manually test things:

  • While running gulp watch, intentionally add syntax and runtime errors in various places in the code. This is to simulate real developers making real editing mistakes. Then make sure the console logs useful errors!
  • While running gulp watch, add basic edits in various parts of the code, and make sure the site regerates itself properly.
  • Run gulp without this PR, make a copy of the dist directory, then run gulp with this PR, and make sure the index.html files in the two dist directories are identical.

@@ -70,6 +70,32 @@ function handleError() {
});
}

function createIndexFileStream() {
var stream = new PassThrough({ objectMode: true });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This returns an IndexFileStream of all the index.html files in the site. It does a bit of trickery because we first need to generate the webpack bundle that generates the index files.

@toolness toolness changed the title [WIP] Use webpack to (re)generate index HTML files Use webpack to (re)generate index HTML files Apr 30, 2015
@mmmavis
Copy link
Member

mmmavis commented May 6, 2015

@toolness I'll get to this PR today - hopefully I won't take too long this time 😶

@mmmavis mmmavis self-assigned this May 6, 2015
@toolness
Copy link
Contributor Author

toolness commented May 6, 2015

No worries! It's not a big rush either, so feel free to take your time and ask any questions that come up.

@mmmavis
Copy link
Member

mmmavis commented May 11, 2015

Sorry for the delay - my other tickets took longer than I expected. Will work on this one today 😁

@hannahkane hannahkane added this to the Optimistic 80s Movie milestone May 11, 2015
@hannahkane hannahkane removed this from the The Wiz milestone May 11, 2015
entry: entry,
target: 'node',
devtool: 'sourcemap',
externals: function(context, request, callback) {
Copy link
Member

Choose a reason for hiding this comment

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

Hey @toolness could you help me understand what context and request are? I see they being mentioned on http://webpack.github.io/docs/configuration.html#externals but the doc doesn't go in detail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yeah, this was annoying for me to figure out, because webpack's documentation is sparse in some places. :( I think I literally just console.log'd the arguments to get an idea of what they actually were, lol. Not a very strong sign of forwards-compatibility, but the good news is that at least we'll know when it breaks, since that code is executed so often!

Copy link
Member

Choose a reason for hiding this comment

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

heh, console.log is always good! I think it'll help a lot for understanding webpack related stuff especially... 😶

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, webpack can be really confusing. :( Hopefully it will improve with age...

@mmmavis
Copy link
Member

mmmavis commented May 13, 2015

Hi @toolness

  • While running gulp watch, intentionally add syntax and runtime errors in various places in the code. This is to simulate real developers making real editing mistakes. Then make sure the console logs useful errors!

Working perfectly.

  • While running gulp watch, add basic edits in various parts of the code, and make sure the site regerates itself properly.

Yes, this works great as well. (files got regenerated themselves and with manual refresh on browser I was able to see the changes)

  • Run gulp without this PR, make a copy of the dist directory, then run gulp with this PR, and make sure the index.html files in the two dist directories are identical.

Question: by identical did you mean comparing the code in those files or?

}, function(err, html) {
if (err) {
return this.emit('error', err);
}
Copy link
Member

Choose a reason for hiding this comment

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

(commenting on this line instead since Github doesn't let me do it on line 19)

I'm just curious why we have to reverse the array. Does it matter which url gets popped first? Is it to preserve the ordering that the URLs get set in indexStatic.URLS?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, yeah, it is to preserve the ordering. Instead of using .pop() in the _read method I should've just used .shift(), but because I constantly get confused between shift and unshift and didn't want to look up the docs, at the time I just opted to reverse the array being popped-from instead! 😅

@toolness
Copy link
Contributor Author

Question: by identical did you mean comparing the code in those files or?

Yeah, um, I really should've done this myself before issuing this PR, but I think it'd be useful for both of us to do it, just to make sure. Basically I mean e.g. using the current develop branch without this PR and generating the files, then renaming the dist directory to dist-old, then switching to this PR and generating the files, and comparing the index.html files in dist and dist-old using a tool like diff. Since theoretically, both should be identical.

}
};

self.build = function(cb) {
Copy link
Member

Choose a reason for hiding this comment

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

Hi @toolness , I just wanna check I'm getting this right.

So this part means
if index-static.bundle.js has been generated, move on
if it's still being build, we make sure it doesn't get rebuilt within 100ms?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very close--basically we don't want multiple builds going on simultaneously, so we just block any additional requests after the first one to wait until the first one is finished. They "wait" by coming back every 100ms and checking to see if the first one is done yet.

It's kind of an overly-complicated way to do it honestly. Maybe I should use a singleton promise instead?

@mmmavis
Copy link
Member

mmmavis commented May 14, 2015

Hey @toolness could you rebase this PR with develop so I can diff comparing the 2 copies of dist? thanks!

@mmmavis
Copy link
Member

mmmavis commented May 14, 2015

I rebased on my local branch but diff dist/ dist-develop/ did return some code differences back. 😮 I don't always trust my rebasing skill so @toolness could you rebase and double check?

@toolness
Copy link
Contributor Author

Ugh, yeah, actually don't worry about diffing the files--even doing this kind of diff on the exact same branch appears to fail, because the data-reactid being given to elements is totally changing between runs. It must be based on the current timestamp or something? Anyways, super annoying.

@mmmavis
Copy link
Member

mmmavis commented May 14, 2015

Alrighty! This PR totally make sense to me now! Thanks for walking me through @toolness
Hooray R+ 👍 and I can finally unblock you 😂

👯 👯 👯 👯 👯

mmmavis added a commit that referenced this pull request May 14, 2015
Use webpack to (re)generate index HTML files
@mmmavis mmmavis merged commit 950565b into mozilla:develop May 14, 2015
@toolness
Copy link
Contributor Author

Wooot thanks mavis!

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

Successfully merging this pull request may close these issues.

None yet

3 participants