TheOdinProject / curriculum

The open curriculum for learning web development
https://www.theodinproject.com/
Other
9.96k stars 13.32k forks source link

JS Webpack: Further improvement on Webpack tutorials/intro #26214

Closed MaoShizhong closed 1 year ago

MaoShizhong commented 1 year ago

Describe your suggestion

Extending the discussion from the following PR: #26140

TL:DR; I have issues with the official tutorial on output management in step 2 in particular. They teach multiple entry points but do not do a good job of explaining what they are/why they might be needed (especially when none of the projects in this part ofthe course would really benefit at all from them) and the more important HtmlWebpackPlugin section relies on the multiple entry points tutorial to demonstrate its usage. It also does not mention using the template option to provide a src html file that will allow the user to work entirely within src (advisable) for things like adding their own static HTML and using webpack-dev-server to serve from src instead of dist. This will be particularly useful in things like the To-do List where someone might want their own static HTML but also use HtmlWebpackPlugin (which will overwrite their static html whenever you build unless you use a template).


In a recent Discord discussion (inc. messages before the linked message), further specific issues with the webpack lessons/tutorials were brought up.

In the actual Webpack lesson, assignment step 2 indicates the lesson is simply to learn about HtmlWebpackPlugin and how it can create/insert HTML files for you and that's it. Yet, the lesson starts off talking about multiple entry points (and poorly explained too, regarding the practical uses/"why" part) - something which I cannot see how it would be relevant to any of the course's projects using Webpack. I've seen people unnecessarily use them, not knowing why they're using them/why they should only need a single entry point which ended up leading to a bunch of bad.

The tutorial introduces HtmlWebpackPlugin but it and subsequent tutorials teach you to work with an index.html file in dist/ and not src/. I've seen people then have projects where they work with html and assets inside dist/ but work with css/js inside src/ whereas ideally, they do everything within src/ and simply build for production which goes into dist/. HtmlWebpackPlugin can easily faciliate this with the simple one-line template option in webpack.config.js, with a filepath to an html file in src/ which it will then use to build the dist html file for production. This is a very simple step that will help people more easily understand the workflow and organisation, and udnerstand how to keep their static html without HtmlWebpackPlugin overwriting it in dist when building.

I would propose making some sort of change to step 2 of the webpack lesson's assignment. I'm not entirely sure how to go about this yet but I feel the current tutorial is not appropriate. Even if you skip the multiple entry points part, the HtmlWebpackPlugin section continues off the previous part, and it doesn't mention anything about templates which I honestly feel is the most useful part of HtmlWebpackPlugin.

The webpack page on HtmlWebpackPlugin is a bit short and isn't really a tutorial of any kind. The plugin's repo README does explain better (especially template) but the useful stuff is a small drop in an ocean of vastly out-of-scope stuff, and I can't really find any good brief tutorials that would fall into "output management" like the original but are presented more appropriately without going into out-of-scope topics that only serve to confuse people at this point in the course (especially with stuff that will not be remotely relevant for the course material).

Thoughts?

Path

Node / JS

Lesson Url

https://www.theodinproject.com/lessons/node-path-javascript-webpack

Checks

(Optional) Discord Name

Mao

(Optional) Additional Comments

No response

KevinMulhern commented 1 year ago

Thanks for the detailed write up @MaoShizhong 💪

@TheOdinProject/javascript any thoughts on this please?

MaoShizhong commented 1 year ago

I've come across this resource which is a short video and some written instructions that use a single entry point and only talk about using HtmlWebpackPlugin to generate dist/index.html using a src template file. It uses some redundant options (due to default values) but I believe these can be pointed out in a small note. Perhaps a little link to the plugin's repo section on options could be given just to point out the different options available and their default values (even if not used (and won't be by many people for these projects)).

Perhaps something like rewriting step 2 along these lines:

  1. Follow along with this video and article to learn how to install HtmlWebpackPlugin to let webpack automatically create dist/index.html and insert the bundled script for you from an html template in src! This is particularly useful so you can work entirely within src during development and reserve dist solely for "production/distribution code". The most important plugin option in the video is the template option - the other options are optional and some are not needed due to their default values which you can see from HtmlWebpackPlugin's documentation.

I've also thoughts that rather than simply going straight from the lesson overviews to the assignments, I feel it'd benefit to have some actual lesson content between that goes through and explains in even a little detail things like what loaders are for, basic output management, dev-server etc. Basically the stuff that I can imagine most people will end up wanting to use for their projects at a minimum. Then the assignments can be used to consolidate that understanding by following along a tutorial. Given the tutorials don't really explain the "why" very well, I feel going into them already understanding some of the why/what the hell is going on will be a big confidence and understanding boost. If that sounds like a good idea, I'm happy to have a go at drafting up some of that content for discussion and review.

MaoShizhong commented 1 year ago

Just in case it helps for any further discussion, I thought I'd write up a quick draft for what I meant above by including our own lesson content in the webpack lesson (since currently it just introduces the lesson overview then dives straight into linking the official tutorials in the assignment with little other context).

Bundling

As briefly introduced in the previous lesson, if you give webpack a file as an entry point, it will build a dependency graph based on all the imports/exports starting there, before bundling everything into a single .js file in dist. If for whatever reason you needed it to output multiple bundles (e.g. you have multiple html pages that each need their own), then each entry point you give Webpack will produce its own output bundle.

If you are only dealing with bundling JavaScript then this is fairly straightforward. But what if your project also included CSS or assets like images or fonts? If you import your CSS into your JavaScript, Webpack can bundle this within the output .js file. It can also load any assets used in src (be that in your CSS or your JavaScript files) into dist. However, it cannot do this by itself. It needs to be configured with the correct loaders and rules so that it knows what else to expect other than JavaScript and also what to do with those files. With the right loaders/plugins/rules, you could even do things such as optimise images when you build your project into dist. In the assignment links below, you will get to see how you can install and configure these loaders and rules for CSS and assets.

Html-webpack-plugin

Since we would like to do all of our development within src and save dist for the production build (the code that you will actually deploy), what about handling HTML files?

Similar to how we will need loaders and rules for CSS and assets, we can use a plugin called html-webpack-plugin which will automatically build an HTML file in dist for us when we build our project. It will also then automatically add certain things like our output bundle in a <script> tag, or the code for a favicon if we configured it to use one.

By default, it will just create this from a blank template, so the resulting HTML file will essentially be the usual boilerplate with our script and perhaps any other options we add in the configuration. If we had our own dist/index.html then it would be overwritten! In order to preserve any of our own HTML, we can tell it to use a template and provide a path to our own HTML file in src. The webpack website has a basic tutorial on installing and configuring html-webpack-plugin for a default HTML build within your webpack configuration in the assignment tutorial below, but it does not demonstrate using the template option. An example of how to set the template option within your webpack configuration file is as follows:

// webpack.config.js
// ...
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/template.html',
        }),
    ],
// ...

Then perhaps altering step 2 of the assignment similarly to the message above?

Would love to hear thoughts on this, as I personally feel improving this portion will really help clear up a lot of confusion I see people having around this part, even with the improved intro to bundlers added in the previous lesson.

wise-king-sullyman commented 1 year ago

That all sounds great to me 🚀