Tuesday, March 28, 2017

My JavaScript Module experiments - CSS

This post is continuation of my JavaScript module experiments series with Webpack. Earlier posts below.

1 My JavaScript Module experiments
2 My JavaScript Module experiments - CI & CD
3 My JavaScript Module experiments - CSS

This post assumes the basic knowledge about NodeJS, NPM, Webpack such as its config file and require mechanism.

Should we bundle css?

It really depends. 

Traditional CSS development

If we take the scenario of simple web site development, we may not need bundling provided entire CSS is in single file. But that is not at all the scenario right now. We need the sites responsive and for that we may have to add dedicated styles for different screen resolutions. One way is to write everything in the same css or separated files loaded on demand. But keeping in different files and downloading all to client and deciding which to use will slow down the performance. Because it needs more http file requests. Keeping in separate files is easy in terms of maintaining. Normally the decision to what style needs to be applied is taken at client side based on the screen size. It will be overhead to request the css for different sizes when the user resize the browser window. So it is better to bundle the css for different sizes at server and download as one file. 

Modern CSS

Modern CSS means writing CSS with the help higher level languages such as LESS or SASS. They help us to write less reusable code and get things done. Since the poor browser cannot understand this LESS or SASS languages, we have to convert to CSS. That process is called transpilation. Here there are chances that some styles will be in pure CSS, some in LESS and some in SASS. As we have to convert to CSS and refer into the application, it is better to bundle the outputs to one css file and refer same.

HTML component

Another scenario is development of web components or on-demand view development. In those scenarios we don't have to keep entire CSS in single place and refer from the beginning. We have to bundle the css along with the JavaScript component which only loaded when needed.

Webpack and CSS

Now lets see how the Webpack and CSS works together. 3 different scenarios are listed below to understand at the simplest level. To keep it simple no other things like ECMA 6 or TypeScript is used.

Simple scenario - webpack and css

Here we are simply going to require .css files from JavaScript to get it available in the html. Below are the steps
  • Import the npm packages named css-loader & style-loader. These are the Webpack specific NPM packages to process .css . The first one is to recognize the .css file and other is to load the .css as <style> tag.
  • Modify the webpack.config.js file to have loader. For syntax refer to the sample given below
  • Add require statements in to the JavaScript file
    • require('./stylesheet.css');
Below is the link to sample.


To run the sample. 
  • Make sure there is NodeJS and NPM
  • Clone the repo to the local machine
  • Open NodeJS command prompt and navigate to the \ECMA-CSS folder
  • run 'npm install' command to download dependencies.
  • run 'webpack' command.
    • If the webpack is not available at system level, '.\node_modules\.bin\webpack' is required
  • This will produce bundle.js file
  • Just run the index.html file from file system. Make sure there are permissions to run JavaScript from local file
When running we can see that there are <style> tags added to the <head> which are not present in index.html file. Those are added by the style loader at runtime.

Combined css

Injecting <style> at runtime is not a good solution. Better is to have a final combined css file. The below sample shows that mechanism using one more npm package called 'extract-text-webpack-plugin'. Since the sample uses webpack 1, the version of 'extract-text-webpack-plugin' should be 1.0.1.


Here the index.html is referring to a style file called bundle.css which is not there in repository. When this sample is run using the same steps mentioned for above previous scenario, the bundle.css will be created by Webpack. Once that file is present, we can run the index.html as usual.

The bundling of multiple css files to one is done by using ExtractTextPlugin configured in webpack.config.js file and here we don't need the style-loader.

CSS & LESS together

This is the next level where we mix plain .css with advanced .less file and finally produce combined .css file. Sample is available in the below location.


In this sample, instead of earlier childstylesheet.css, childstylesheet.LESS is used. The npm packages used are less, and less-loader for compiling .less files and to load the same respectively. The webpack.config.js also modified to tell how to handle the .less files and to combine using ExtractTextPlugin.

During the compilation the .LESS file will be compiled to .css and then combined with other .css file to produce bundle.css file.

Further reading

https://webpack.github.io/docs/stylesheets.html
http://jamesknelson.com/writing-happy-stylesheets-with-webpack/
https://css-tricks.com/css-modules-part-2-getting-started/
http://stackoverflow.com/questions/39015521/import-css-and-js-files-using-webpack
https://github.com/webpack/file-loader/issues/32

No comments: