GraphQL? Security? Queries? DoS? Server? EXPLOSION!!! GraphQL is fast becoming one of the...
webpack and the power of loaders
WHY USE WEBPACK?
HOW DOES WEBPACK WORK?
Straight from the great documentation online - “when webpack processes your application, it internally builds a dependency graph which maps every module your project needs and generates one or more bundles.” But “How?”, you may wonder. A helpful way to think about this is that webpack needs an entry point to begin the bundling process.
This entry is a module, which may point to another module through the use of an import statement. webpack will traverse the imports as well to build the graph. After the starting point - the module is then passed to the webpack compiler. The compiler then directs it into a container, and executes plugins onto it (to sort by type) before it's rendered onto the browser.
the journey of a module -> 1.compiler, 2. compilation, 3. resolver, 4. loaders , 5. module factory, 6. parser, 7. chunk template, 8. bundle
Plugins are the "secret sauce" or the "magic potion" that makes webpack so powerful for us as developers. They allow us to introduce our custom behaviors into the build process. Plugins are the backbone of webpack and they also serve the purpose of doing anything else that a loader cannot do. There is an extensive list of plugins available here.
Building plugins is a bit more complex than building loaders but loaders are also of great importance on the module level. Loaders allow you to determine what should happen when webpack's module resolution mechanism encounters a file. Let’s look at them more closely and also lay the foundation to build our own.
WEBPACK LOADERS AND HOW TO B.Y.O. (BUILD YOUR OWN)
For babel-loader, our webpack config file would look something like this:
Now let’s think about this - is there a chance you might be double matching the files when looking for a match like so “/\.m?js$/”? The “exclude” property allows us to tell webpack which files to ignore. Excluding the node_modules folder to avoid further slowing transformations is important to remember when using babel-loader.
Let’s think about a few other hypothetical situations - it becomes slightly more interesting if you need to use more than one loader for a given rule. webpack's loaders are evaluated from right to left or executed from bottom to top. If you had the following array of loaders: ['style-loader', 'css-loader', 'some-custom-loader'], webpack will start from right to left and will then execute ‘some-custom-loader’ first, then the ‘css-loader’ and finally the ‘style-loader’.
THE B.Y.O. PART
OK, so let’s say we need a custom loader to transform gRPC proto files. Here are the main ideas following the important steps to build our own - loaders are functions that we can define and then use through our webpack config:
// The simplest loaders are functions
// which take a files source and then return it
// you can add more functionality here
module.exports = mygRPCLoader;
Remember: in our webpack config file, a loader definition consists of conditions based on which to match and actions that should be performed when a match happens.
Below is what the webpack.config.js would look like using our new gRPC proto file loader:
// adding the new loader to the config
// matching .proto
// To test a single loader, you can simply use path to resolve a local file within a rule object
The beauty of loaders is that they allow webpack to support a wide variety of formats. You set them up, connect them to your directory structure and just like that you are provided with a set of actions that will be performed to the matched files.