Configuring Jest with React and Babel

Posted: 2019-08-26T11:38:00+05:30
Jest is a really good frontend testing framework and works great with React and Babel out of the box, along with Enzyme for component testing. But, imports with React and Babel can often be filled with nasty imports. I wrote in a previous blog about how to make better more cleaner imports using some webpack tweaks.

But the problem appears when we try to write Jest and Enzyme tests with them. Because Babel can now longer understand and parse the imports. And without Babel parsing them and converting to ES5, jest cannot test the components. So we actually need a mix of Babel configuration and Jest configuration.

Note: This post assumes you already have jest, babel-jest and babel/plugin-transform-modules-commonjs packages installed using your favorite javascript package manager.

Basically, the workaround is first we need to resolve the cleaner imports into the absolute paths for the import using Jest configurations, and then use the Babel configurations to parse the rest code (without the modules) to ES5.

The configuration files look something like these:

babel.config.js

module.exports = api => {
const isTest = api.env('test');
if (isTest) {
return {
presets: [
[
'@babel/preset-env',
{
modules: false,
},
],
'@babel/preset-react',
],
plugins: [
"@babel/plugin-transform-modules-commonjs",
],
}
} else {
return {
presets: [
[
'@babel/preset-env',
{
modules: false,
},
],
'@babel/preset-react',
],
}
}
};


jest.config.js

module.exports = {
moduleNameMapper: {
'^~/(.*)$': '<rootDir>/path/to/jsRoot/$1'
}
}

So let's go through the code a little.

In babel.config.js, we make a check to see if the code is right now in test environment. This is helpful because
  1. Jest sets the environment to "test" when running a test so it is easily identifiable
  2. It ensures that the test configuration don't mess up with the non test configurations in our Webpack config (or any other configuration you are using)
So in this case, I am returning the exact same Babel configuration that I need in my Webpack config in non-test environment.

In the test configuration for Babel, we are using a plugin "@babel/plugin-transform-modules-commonjs". This is needed to parse all the non component imports like React, etc. along with parsing the components from ES6 to ES5 after jest does the path resolution. So it helps to convert the modules from ES6 to ES5.

Now, let's see the jest.config.js. The jest configuration allows us to do something called moduleNameMapper. This is a very useful configuration in many different usecases. It basically allows us to convert the module names or paths we use for module import to something that jest understands (or in our case, something that the Babel plugin can parse). 

So, the left hand part of the attribute contains a regular expression which matches the pattern we are using for imports. Since our imports look something like '~/path/from/jsRoot/Component', so the regular expression to capture all such imports is '^~/(.*)$'. Now, to convert them to absolute paths, we need to append '<rootDir>/path/to/jsRoot/' in front of the component path.

And, voila! That should allow Jest to properly parse, convert to ES5 and then test.

The best part? We can use the cleaner imports even in the .test.js files and this configuration will work perfectly with that too.

Comments

What's the preferred unit in CSS for responsive design?

Posted: 2018-04-04T17:16:00+05:30
Obviously, it's %. What a stupid question? Well, you can sometimes use em maybe. Or, maybe vh/vw.  Well, anything except for px for sure.

Sadly, the answer isn't as simple as that. In fact, there is no proper answer to that question and depends a lot on the design decisions taken rather than a fixed rule of making websites responsive. Funny thing is, many times you might actually want to use px instead of % because the later is going to mess things up. In this blog, I will try to describe some scenario's when each of the units work better in a responsive environment.

PS: All of this is mostly my personal opinion and working experience. Not to be mistaken as a rule book.


Where to use %?

Basically, anywhere you have certain kind of layout or grid involved. I use % whenever I feel that the screen needs to be divided into proportions rather than fixed sizes. Let's say I have a side navigations area and the remaining body in a website. I would use % in this case to measure the margins and the area of distribution. Since I definitely want to vary them on changing screen. Or a grid of rows and columns. I will want the width of the grid to be in percentage so that the number of columns allowed change with the width of the screen.

Another use of percentage is while determining the margin of an element. You might want to have much more margin on a wider screen than in a smaller screen. Hence, often the margin-left and margin-right are advisable to be in percentage.

Also, for fonts and typography elements, you should use % since px isn't compatible with W3C standards of accessibility.

PS: A lot many times, it is preferable to use flexbox and grid layout instead of trying to layout things via margins and floats.

Where to use px?

To be honest, yes, it is better to avoid px when you think of making things fluid in responsive. But having said that, there are some cases where even in a fluid design, you want things to have a fixed value. One of the most commonly used examples is top navigation height. You don't want to change the height of the top navigation bar's height with the change in screen size. You might want the width to change or show a hamburger button instead of showing the list of hyperlinks, but you most often want to keep the height of the navigation bar fixed. You can either do it by setting height attribute of CSS or maybe you want to do it with padding, but the unit mostly should be px.

Another use would be for margin of an element but this time the top and bottom margins instead of left and right. Mostly, when you have your website divided into sections, you would want the margin between the different sections to be of a fixed value and not to change with the screen width.

Where to use em?

em is mainly to be used while setting font-sizes and typography elements. By that I mean wherever I have a text involved it is often good to use em. The size of em basically depends on the font-size of the parent element. So if the parent element has 100% font-size (default browser font-size), then 1 em = 16px. But em is a compounded measure. So the more and more nested elements you have the idea or measure of em keeps changing. So it can often be very tricky to work with em. But this is also a feature that might sometimes help to get a compounded font size.

Where to use rem?

The main difference between em and rem is rem depends on the font-size of the root element of a website(basically root-em) or the <html> element. So whatever be the font-size of the root element, rem is always computed based on that and hence unlike em, the computed pixel value is more uniform throughout the website. So rem and em usability depend highly on the use case.

Where to use vh or vw?

vh and vw stand for viewport height and viewport width. The advantage of vh or vw over width is that you can control based on both the height and the width of the media screen that appears in the viewport. 1vh basically means 1% of viewport height. So if you want something to take the entire height of the screen, you would use 100vh. This has applications in both setting width and also setting font-sizes. You can mention the font-size of a typography will either change based on the height or on the width of the viewport instead of the font-size of your parent element. Similarly, you can also set line height based on viewport height instead of the parent element measures.

Where to use media queries?

Even after using all of the above strategically, you will almost necessarily need to use media queries. Media queries are a more definitive set of CSS codes based on the actual media screen width of the device. Mostly, we use it in a conditional way similar to other programming languages. So we can mention if media screen width less than 720px, make this 10% wide, else make it 25% wide. Well, but why do we need it? The main reason for this is the aspect ratio of screens. In a desktop, the width of the screen is much more than the height and hence 25% wide might not occupy a whole lot of screen. However, in a mobile screen where the width is much smaller than the height, 25% might actually occupy more area than you want it to. Hence media queries are needed so that when there is a transition from wide screens to narrow screens, even the percentage widths are changed.


As far as I feel, there are use-cases and scenarios where each of them might be useful. Yes, px is the least used unit if you are concerned about responsiveness, but there will definitely be some elements on your website to which you want to give a fixed width or height. All the other measures are changing, but the way they change is different from each other and hence depends a lot on the designer and the frontend. Also, CSS4 has added a lot of new features which at least make handling of layout lot easier than before.

Comments