{"id":13528128,"url":"https://github.com/TheLarkInn/artsy-webpack-tour","last_synced_at":"2025-04-01T11:31:13.815Z","repository":{"id":65501886,"uuid":"80546862","full_name":"TheLarkInn/artsy-webpack-tour","owner":"TheLarkInn","description":"Annotations on webpack source code in a pseudo-guided fashion.","archived":false,"fork":false,"pushed_at":"2018-06-18T11:35:40.000Z","size":31859,"stargazers_count":526,"open_issues_count":5,"forks_count":34,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-03-29T15:08:02.124Z","etag":null,"topics":["tutorial","webpack","webpack-tutorial"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheLarkInn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-31T18:05:53.000Z","updated_at":"2025-03-26T18:20:55.000Z","dependencies_parsed_at":"2023-01-26T09:30:57.538Z","dependency_job_id":null,"html_url":"https://github.com/TheLarkInn/artsy-webpack-tour","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLarkInn%2Fartsy-webpack-tour","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLarkInn%2Fartsy-webpack-tour/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLarkInn%2Fartsy-webpack-tour/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheLarkInn%2Fartsy-webpack-tour/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheLarkInn","download_url":"https://codeload.github.com/TheLarkInn/artsy-webpack-tour/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246631770,"owners_count":20808751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["tutorial","webpack","webpack-tutorial"],"created_at":"2024-08-01T06:02:13.903Z","updated_at":"2025-04-01T11:31:08.804Z","avatar_url":"https://github.com/TheLarkInn.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# artsy-webpack-tour\nAnnotations on webpack source code in a pseudo-guided fashion.\n\n## Just an Experiment\nMy goal as one of the maintainers for [webpack](https://github.com/webpack/webpack) is being able to help developers better understand how webpack works.\n\nDemystify the tool so it helps you become more comfortable understanding how to use it and contributing to our source code and supporting packages.\n\n## Have a question?\nThe whole goal is to teach you how to use webpack, therefore please ask questions about the annotations you see inside of a github issue, and I will help you clarify any parts of what is seen below. There is **NO wrong question**.\n\n## Disclaimer: This may not match master!\nI will likely not keep this up to date with every change in master on webpack/webpack. Rather, the purpose is to teach how to read and view the flow of the compilation lifecycle through webpack.\n\n## Table of Contents\n\n1. [WebpackOptionsApply.js (List of plugins)](#Step1)\n2. [WebpackOptionsApply.js (Explanation of Options)](#Step2)\n3. [WebpackOptionsApply.js (Native modules)](#Step3)\n4. [WebpackOptionsApply.js (Source Map Flavors)](#Step4)\n5. [WebpackOptionsApply.js (More module madness!)](#Step5)\n6. [WebpackOptionsApply.js (after plugins)](#Step6)\n7. [Compiler.js (The Complier's Constructor)](#Step7)\n8. [Compiler.js (The Complier's Execution Process)](#Step8)\n9. [Compiler.js (The Complier's Execution Process Part 2)](#Step9)\n10. [Compiler.js (Compilation prelude)](#Step10)\n11. [Compilation.js (Welcome to the compilation)](#Step11)\n12. [Compilation.js (Welcome to the compilation)](#Step11)\n13. [Compilation.js](#Step13)\n14. [Compilation.js (Building chains)](#Step14)\n15. [NormalModuleFactory.js](#Step15)\n16. [NormalModuleFactory.js](#Step16)\n17. [NormalModuleFactory.js](#Step17)\n18. [NormalModule.js](#Step18)\n19. [Compilation.js (Back to compilation!)](#Step19)\n20. [Compilation.js](#Step20)\n21. [NormalModule.js](#Step21)\n22. [NormalModule.js](#Step22)\n23. [Compilation.js](#Step23)\n24. [Compilation.js](#Step24)\n25. [Compilation.js](#Step25)\n26. [Compilation.js](#Step26)\n27. [Compiler.js](#Step27)\n28. [Compilation.js](#Step28)\n\n\n## Text Transcripts\nTo make this searchable, the text of each image has been transcribed. The title of each transcript anchors to the respective image. The transcripts are not made to be read through, rather they provide a tool to search out a specific section based on the commentary.\n\n### Help Wanted ❤😍💕❤😍💕❤😍💕❤😍💕❤😍\n\n### Version (webpack 2.2.1+ from master)\n\n#### [WebpackOptionsApply.js (List of plugins)](#Step1)\n\u003ca name=\"Step1\"\u003e![Step 1](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative01.png)\u003c/a\u003e\n\n* \"All plugins for options cases\"  \n* \"These handle any module format\"\n\n#### [WebpackOptionsApply.js (Explanation of Options)](#Step2)\n\u003ca name=\"Step2\"\u003e![Step 2](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative02.png)\u003c/a\u003e\n\n* \"getting opts from config\"  \n* \"options target code\"  \n* \"ES5 OOP (class W0A(?) extends 0A)\"  \n* \"records\"  \n* \"never used this before ¯\\\\_(ツ)_/¯ \"  \n* \"plugin system makes for extremely flexible feature development\"\n\n#### [WebpackOptionsApply.js (Native modules)](#Step3)\n\u003ca name=\"Step3\"\u003e![Step 3](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative03.png)\u003c/a\u003e\n\n* \"Certain targets ship w/ other modules native to their deploy target like Electron\"  \n* \"Similar to electron man but instead the \"client\" side. Thus diff externals\"\n\n#### [WebpackOptionsApply.js (Source Map Flavors)](#Step4)\n\u003ca name=\"Step4\"\u003e![Step 4](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative04.png)\u003c/a\u003e\n\n* \"handling bad target values\"  \n* \"all of this logic is for the 'devtool' prop. Allows for about 15-20 flavors of source maps\"  \n* \"That was Sean's first ever PR!!!\"\n\n#### [WebpackOptionsApply.js (More module madness!)](#Step5)\n\u003ca name=\"Step5\"\u003e![Step 5](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative05.png)\u003c/a\u003e\n\n* \"1. Single plugin for entry prop that is registered then\"  \n* \"2. Executes via subsequent event\"  \n* \"these plugins are grouped b/c they are all for module interop\"  \n* \"these plugins all pertain to general optimizations including tree shaking\"  \n* \"performance budgets code\"  \n* \"in version 1, you had to do this yourself, now in v2 we handle it\"  \n\n#### [WebpackOptionsApply.js (after plugins)](#Step6)\n\n\u003ca name=\"Step6\"\u003e![Step 6](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative06.png)\u003c/a\u003e\n\n* \"nice for custom plugins that need to execute after all other default plugins\"  \n* \"same as abover except after resolvers are created\"  \n* \"saftey net incase someone nulls the input fs\"  \n* \"(Also resolvers are created here. The factory comes from webpack/enhanced-resolve)\"  \n\n#### [Compiler.js (The Complier's Constructor)](#Step7)\n\u003ca name=\"Step7\"\u003e![Step 7](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler01.png)\u003c/a\u003e\n\n* \"The Compiler\"  \n* \"yes, you can set your own custom file system\"  \n* \"depreceate where the parser used to live\"  \n* \"options from your config will end up here\"  \n* \"Constructor\"  \n\n#### [Compiler.js (The Complier's Execution Process)](#Step8)\n\u003ca name=\"Step8\"\u003e![Step 8](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler02.png)\u003c/a\u003e\n\n* \"top lvl. function for entire webpack compliation process\"  \n* \"timings for builds\"  \n* \"here are all of the compiler's plugin events\"  \n* \"all plugin events start with 'applyPlugins'\"  \n* \"that means you can write custom plugins for any of these events\"  \n* \"still track time till the end\"  \n\n#### [Compiler.js (The Complier's Execution Process Part 2)](#Step9)\n\u003ca name=\"Step9\"\u003e![Step 9](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler03.png)\u003c/a\u003e\n\n* \"next step in process (called inside of .run)\"  \n* \"compilation is being created\"  \n* \"create info to init compliation\"  \n* \"the compilation plugins are firing\"  \n\n#### [Compiler.js (Compilation prelude)](#Step10)\n\u003ca name=\"Step10\"\u003e![Step 10](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler04.png)\u003c/a\u003e\n\n* \"we drive into the compilation next\"  \n* \"used for long term hashing\"  \n* \"lets you plugin to multiple child compilations vs. just the parent\"  \n* \"we create modules from here\"\n\n#### [Compilation.js (Welcome to the compilation)](#Step11)\n\u003ca name=\"Step11\"\u003e![Step 11](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler05.png)\u003c/a\u003e\n\n* \"plugin system\"  \n* \"compiler thaty created it\"  \n* \"Templates: bind the dep. graph to actual output code.\"  \n* \"the literal constructor for each dep.\"  \n* \"the shape of these templates vary by the type of dependency\"  \n\n#### [SingleEntryPlugin.js (Down the rabbit hole!)](#Step12)\n\u003ca name=\"Step12\"\u003e![Step 12](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler06.png)\u003c/a\u003e\n\n* \"The plugins start to take over!!\"  \n* \"there's one of those dep. types I was talking about\"  \n* \"that's the values from your entry property\"  \n* \"back to the compilation to start walking the dependency graph\"\n\n\n#### [Compilation.js](#Step13)\n\u003ca name=\"Step13\"\u003e![Step 13](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler07.png)\u003c/a\u003e\n\n* \"open empty slot for chunk about to be created\"  \n* \"this is the module that will be resolved\"  \n* \"it wasn't originated from another module, so set null\"  \n* \"next fn to visit :)\"  \n\n#### [Compilation.js (Building chains)](#Step14)\n\u003ca name=\"Step14\"\u003e![Step 14](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler08.png)\u003c/a\u003e\n\n* \"track time to build chain\"  \n* \"if 'bail:true', explode\"  \n* \"else build anyways, show error after\"  \n* \"safety net so deps are created properly\"  \n* \"tip: depfactory.create = module\"  \n* \"the dir path it came from\"  \n* \"why an array? think nodes on a graph and dependencies are all adjacent nodes\"  \n* \"a module is created: passed to callback!!\"  \n* \"more timing\"  \n* \"module officially added to compilation\"  \n* \"Can also be null?\"  \n* \"finish early if so\"  \n* \"if a module is returned, use it and flag ready\"  \n* \"I smell some recursion coming up!!!!\"\n\n#### [NormalModuleFactory.js](#Step15)\n\u003ca name=\"Step15\"\u003e![Step 15](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compiler09.png)\u003c/a\u003e\n\n* \"see if there is a cache entry first\"  \n* \"allows plugins to hijack and modify original 'request' obj.\"  \n* \"IE: NormalReplacementPlugin\"  \n* \"cache\"  \n* \"return resolved module\"  \n\n#### [NormalModuleFactory.js](#Step16)\n\u003ca name=\"Step16\"\u003e![Step 16](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf01.png)\u003c/a\u003e\n\n* \"this gets triggered from .creal\"  \n* \"resolver event triggered \u0026 assigned\"  \n* \"resolver is now going to ensure that the module you requested actually exists\"  \n* \"don't error, skip\"  \n* \"the result returned has everything needed to create module\"  \n* \"will visit here next\"  \n* \"more on this stuff later\"  \n* \"the NormalModule instance is finally created\"  \n* \"event for plugins to use\"  \n* \"send module back to be added to chunk\"\n\n#### [NormalModuleFactory.js](#Step17)\n\u003ca name=\"Step17\"\u003e![Step 17](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf02.png)\u003c/a\u003e\n\n* \"as you can see callback handles resolved requests\"    \n* \"find \u0026 extract loaders being used in require()\"    \n* \"new code for handling ident in loader opts. \"  \n* \"Rules are normalized from configuration\"  \n* \"find all pre \u0026 post loaders\"  \n* \"paths to loaders are now resolved\"  \n* \"always ordered post-normal-pre\"\n\n#### [NormalModule.js](#Step18)\n\u003ca name=\"Step18\"\u003e![Step 18](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf03.png)\u003c/a\u003e\n\n* \"We are arriving here from the NormalModuleFactory\"  \n* \"Parser instance\"  \n* \"path the user specifies\"  \n* \"path before query etc, are parsed\"  \n* \"loaders to be applied\"  \n* \"dependencies for context modules (superclass owns this.dependencies)\"  \n* \"Normal Module constructor\"  \n* \"extends module\"\n\n#### [Compilation.js (Back to compilation!)](#Step19)\n\u003ca name=\"Step19\"\u003e![Step 19](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf04.png)\u003c/a\u003e\n\n* \"just finished time for the callback\"  \n* \"this new Normal Module\"  \n* \"fails if factory fails \"  \n* \"timing/profiling\"  \n* \"check cache and profile\"  \n* \"next stop\"  \n* \"next stop+1\"  \n* \"find deps of module to go through resolve, vreate, build process cycle till graph is complete\"\n\n#### [Compilation.js](#Step20)\n\u003ca name=\"Step20\"\u003e![Step 20](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf05.png)\u003c/a\u003e\n\n* \"Up until now, we know the following about our entry module:   \n\" • request path  \n-loaders assigned and applied  \n-source value in new\"  \n* \"we venture back to the callback\"  \n* \"collect mod, and dep diagnostics, report the to compilation as errors\"  \n* \"last chance for plugins to modify the NormalModule obj\"  \n* \"Same as above for warning separately\"  \n* \"Let plugins handle post build events\"  \n* \"stable(?) topological ped sort. see compareLocations.j\"\n\n#### [NormalModule.js](#Step21)\n\u003ca name=\"Step21\"\u003e![Step 21](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf06.png)\u003c/a\u003e\n\n* \"timings\"  \n* \"1. yet another callback 💕\"  \n* \"Really important to remember that once inside this block, loaders have finally been applied\"  \n* \"2. see if noParse is set if so, don't send to parser\"  \n* \"3. pass raw src to parser along w/ options\"  \n* \"4. if loaders are used correctly, the final loader will return js that acorn can parse, else FAIL! \"\n\n#### [NormalModule.js](#Step22)\n\u003ca name=\"Step22\"\u003e![Step 22](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf07.png)\u003c/a\u003e\n\n* \"still here\"  \n* \"a value ref. later for Loaders.\"  \n* \"1. What is loaderContext? The loader contect rep. is also known as the Loader API.   It is a collection of utilities and stateful info about the current module being loaded\"  \n* \"1a. loader context\"  \n* \"Finally!! Loaders are ran!!\"  \n* \"2. This fin actually comes from a  supporting npm module: loader-runner.\"  \n* \"loaders can specify deps of their own declaratively\"   \n* \"like css =\u003e background img\"  \n* \"css-loader =\u003e url loader\"  \n* \"2a. loader runner\"  \n* \"3. can also return a buffer\"  \n* \"4. if supported loader sends back src maps.\"  \n* \"5. remember last sketch? we send back to be parsed\"\n\n#### [Compilation.js](#Step23)\n\u003ca name=\"Step23\"\u003e![Step 23](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf08.png)\u003c/a\u003e\n\n* \"We've already covered this tl;dr caching\"  \n* \"finally back 2 levels up of callbacks\"  \n* \"?=unresolved\"  \n* \"oh hey no context switching \u003c3\"  \n* \"timing \u0026 profile\"  \n* \"the next step in building the dep graph\"  \n* \"right now at this point we only have 1 module\"\n\n#### [Compilation.js](#Step24)\n\u003ca name=\"Step24\"\u003e![Step 24](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf09.png)\u003c/a\u003e\n\n\"for now, lets consider this the entry module.\"  \n\"the final call from addEntry fn\"  \n\"unflatten deps\"  \n\"deps. can come from some 'resourece' aka file/resolved location, this dedupes the loc. and groups by [[dep1, dep2],...[block],...]\"  \n\"hard to explain; 100% a module is a dep block dep block is hisgest super class that exists to rep. dep. relationships\"  \n\"time to add all deps \u0026 bfs graph traversal\"  \n\"OMG I JUST Figureed out DependenciesBlock fully just now!!!\"  \n\"So the whole point is that deps can be uniq bit from the same place\"  \n\n#### [Compilation.js](#Step25)\n\u003ca name=\"Step25\"\u003e![Step 25](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf10.png)\u003c/a\u003e\n\n* \"profiling\"  \n* \"since we've gone to a signle entry dep to now an arrau pf deps we'll need to iterate through them\"  \n* \"i can haz functional error handling?\"  \n* \"by calling create\"  \n* \"now we async iterate through all deps and process them w/ their dep factory\"  \n* \"warnings \u0026 error handlers\"  \n* \"Already learned this fun stuff\"  \n* \"tie deps back to origin modules (2 way ref.)\"  \n* \"profile pt1\"  \n* \"end of 1 way traversal\"  \n* \"cache checks\"  \n\n#### [Compilation.js](#Step26)\n\u003ca name=\"Step26\"\u003e![Step 26](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf11.png)\u003c/a\u003e\n\n* \"some profiling + ?\"  \n* \"recursion begins\"  \n* \"remember we are still inside async factory iterator also.\"  \n* \"recurse the graph!\"  \n* \"we can actually go back to original event\"  \n* \"finally traversal is complete\"\n\n#### [Compiler.js](#Step27)\n\u003ca name=\"Step27\"\u003e![Step 27](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-nmf12.png)\u003c/a\u003e\n\n* \"Brain Recapitulation!!!!\"  \n* \"We just spent like 5 hours in Compilation, but the graph is done building and now we are back\"  \n* \"this is where we last left off\"  \n* \"finish \u0026 seal are next to be called...\"  \n\n#### [Compilation.js](#Step28)\n\u003ca name=\"Step28\"\u003e![Step 28](https://github.com/TheLarkInn/artsy-webpack-tour/blob/master/images/webpack-narrative-compilation-seal01.png)\u003c/a\u003e\n\n* \"lets dive in to here\"  \n* \"warnings \u0026 errors\"  \n* \"triggered here yay!\"  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTheLarkInn%2Fartsy-webpack-tour","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTheLarkInn%2Fartsy-webpack-tour","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTheLarkInn%2Fartsy-webpack-tour/lists"}