Outline
Babel and Webpack
Source Map
Watching files
Serving content
Modularize code
Adding input
Styling
CSS on it’s own
LESS source maps
Conclusion
Babel and Webpack
This time around I decided to build a project from the ground up including my own choice of build system. I had used Gulp in previous projects for basic tasks such as JS and CSS minification as well as LESS compilation. Hearing about people using Webpack on other projects, I decided to look into using this system especially since I would be using Babel to convert my JSX and ES6 code.
The first difference I noticed when constructing a Webpack config compared to Gulp was the setting oriented nature of the file. With Gulp I was accustomed to specifying a chain of commands for a task, but with Webpack the workflow felt more “object based” than “function based”. This is a preliminary observation based on a basic setup, of course, but made Webpack distinctive to me nonetheless.
Source map
I have never used source maps as part of my development work before I started coding with React framework. The main reasons were A) wasn’t aware of their purpose before and B) had no need for them even if I had been aware. Most of my Javascript work before had been with frameworks and MVC libraries like Backbone and VueJS. These all involved compilation and package management to various degrees but left the code fundamentally unaltered from the source files.
I quickly realized that tracing bugs in React compiled code back to the original JSX files would be cumbersome. This is when the concept of the source map came to my attention. It was surprisingly easy to add source map creation in Webpack with just one command:
devtool: ‘source-map’
Watching files
My next challenge was figuring out how to speed up the development process so that I would not have to invoke the Webpack build process using the command line every time I made a file change. With Gulp I was familiar with the concept of watchers that trigger Gulp tasks whenever file changes are made. Given Webpack’s settings approach I came back to the command line and introduced myself to the watch functionality.
webpack –watch
Serving content
The method above worked well for compiling the static JS, but the matter of serving the files still remained. For simple projects I generally use the basic Python http server.
python -m SimpleHTTPServer 8080
The Webpack dev server, on the other hand, appealed to me since I could take care of compiling, serving content, and refreshing the browser in one package.
Modularize code
Based on my previous framework experience, I decided to split my code up into separate files right away. This was another case where the difference between Webpack and Gulp became apparent. With Gulp I was accustomed to specifying a catch all path to scoop up all the files in a directory for processing. With Webpack, on the other hand, I found that additional configuration was unnecessary; the imports were all picked up automatically by the compiler.
Adding input
After splitting my code into modules, I decided the next step would be connecting input to output. In order to accomplish this I created a new module for form inputs and made a TextInput component. I placed a callback in my project base and passed it into the TextInput component. This allowed me to change the application state from the TextInput module and automatically display the latest data on my app’s homepage.
updateUserName(name){this.setState({“user”: name.target.value});}<input type=”text” onChange={this.updateUserName}/>
Styling
After getting a basic site structure built, it was time to learn how to set up the styling system. I have used a lot of different CSS processors and LESS is still my favourite one. Configuring LESS in Webpack proved to be more complex than Gulp, however. This was one of the cases where I needed to fall back on the documentation extensively.
The first step was getting styles to show up on the page using the simplest method possible. I used the Webpack less-loader to accomplish this.
{test: /\.less$/,loader: “style!css!less”}
The downside of this approach is that it bundles the LESS as CSS code inside of the Javascript instead of a separate stylesheet. For my next step I aimed to place my generated CSS outside of the bundled JS to allow for source mapping of the CSS to the original LESS.
CSS on it’s own
To get the CSS into it’s own file, I was introduced to the concept of extracting data from the bundle. I eventually settled on using the ExtractTextPlugin.
loader:ExtractTextPlugin.extract(“style-loader”,”css-loader!less-loader”),
This step seemed somewhat counterintuitive to me, since Webpack is bundling all of the code only to have some of it extracted for styling purposes. With Gulp I was accustomed to have different processes for handling JS and CSS tasks.
LESS source maps
When I first started using LESS I wanted to incorporate Bootstrap as I had done with plain CSS styled sites. This is when I first encountered the issue of debugging compiled styles. Searching for declarations or comments in the compiled css and then trying to find them in the LESS files could get quite tedious. As started previously, source maps came to my attention when working with Javascript, but I started to wonder if they were possible with other files.
As I’ve come to except from Webpack, adding source map support was simply a matter of adding a setting to the loader specification: sourcemap.
{test: /\.less$/,exclude: /node_modules/,loader: ExtractTextPlugin.extract(“style-loader?sourceMap”, “css-loader? sourceMap!autoprefixer? browsers=last 5 version!less-loader?sourceMap”),},
The one downside that I’ve countered so far is that CSS to LESS mappings appear to be specific only to the top-most selector, which means I could have a selector 100 lines down in the LESS while the mapping points to the parent selector on line 3. This is only my first observation of mappings of course, which I know from using JSX -> JS can vary in precision.
Conclusion
After having used Gulp to automate simple build processes and Webpack for React JS, my opinion is that while Gulp may require more skill when it comes to crafting the build process with all the methods involved it is still easier for me to understand. Webpack processes, on the other hand, felt more obfuscated behind the declarative nature of the configuration.
For my next experiment I want to switch my build system over to a Gulp process while maintaining my current compiled output (JS and CSS).