Latest Tutorials

Learn about the latest technologies from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

Styling React Components with styled-components

HTML , CSS and JavaScript form the foundation of all client-side applications. Each of these languages handles a different responsibility. HTML markup semantically organizes content, CSS rules styles content and JavaScript code adds dynamic interactivity to the content. Traditionally, developers build basic client-side applications along this standard separation of concerns, which groups code solely by language (and implicitly, by file type): HTML for structure, CSS for presentation and JavaScript for behavior. However, siloing code this way comes with a caveat. For example, if you have a carousel on your homepage, and you decide to modify its appearance, then you may need to consult three separate files ( .html , .css and .js files) to make the appropriate changes. With modern JavaScript libraries/frameworks, such as React , the separation of concerns shifts from languages to components. Now, all code belonging to a single component lives within a single file ( .jsx / .tsx for React). The component itself, written as a functional or class component, contains methods (lifecycle, render, etc.) that encapsulate its behavior. The JSX syntax within the render method (or within the return statement if written as a function) describes the component's structure. As for the component's presentation, there are two common approaches: Large CSS stylesheets are difficult to maintain, especially when tracking which rules override others and which rules can/cannot be removed. If you write styles using a CSS-in-JS library, then all styles belonging to a component exists alongside the component within a .jsx / .tsx file (or .js file if imported from a separate file). When the component is no longer used within the application, then deleting the component's styles is as simple as deleting the component itself. For a React component library, CSS-in-JS libraries provide lots of functionality to supercharge components' styles: Below, I'm going to show you how to add styled-components to a React component library and how to style a component with styled-components . To understand how styled-components works, let's walkthrough a simple example: ( src/components/Heading.jsx ) ( src/App.jsx ) Note : By convention, the names of styled components are prefixed with Styled , which tells developers distinguish styled components from other components. Here, the <Heading /> component renders the styled component <StyledHeading /> , which is an <h1 /> element that is bolded, colored black and has a font size of 4rem . In fact, you can customize the styles based on props passed to the styled component: ( src/components/Heading.jsx ) ( src/App.jsx ) The most common way to write styled components is with tagged template literals . Appending a template literal to the end of a tag function name executes the tag function with the template literal and its placeholder expressions passed as arguments. Example : When the logTagFnArgs function is called, the template literal is broken up into smaller substrings based on the positions of the placeholder expressions. As you can see, the substrings that come before and after the placeholder expressions (including empty strings if the placeholder expression is located at the start/end of the template literal), such as "Sum of " before ${x} , are stored within an array that's passed as the first argument to logTagFnArgs . Each placeholder expression is passed as a separate argument to logTagFnArgs . With the rest parameter syntax, we can have the function accept these separate arguments as a single array, hence why the exps array contains the values 5 ( x ), 10 ( y ) and 15 ( x + y ). In the styled-components example, styled.h1 is a tag function. Knowing that styled.h1 returns a React component, we can write our own basic implementation of the styled.h1 tag function. First, establish a list of HTML tags you want the styled object to support. Let's start off with <h1 /> , <h2 /> , <h3 /> , <h4 /> , <h5 /> and <h6 /> tags. Then, place them within a styled object, which will be exported for other files to import. createStyledComponent will be a function that accepts a tag as an argument (since it must know which HTML element to render), and it will style and return a React component based on the tagged template literal. Due to the closure, the anonymous function returned by createStyledComponent allows the functional component to access the tagged template strings and expressions. Also, some of the expressions are functions that involve props passed to the functional component. Using the tagged template strings, expressions and props, the functional component takes these values and applies styles to the element accordingly. parseStyles parses the tagged template literal into an object that contains the CSS rules as key/value pairs. All function expressions are evaluated with the component's props passed as its argument. For example, if the component has no props passed to it, then this... becomes... And the element's style attribute is set to this object. All excess whitespace around the rules and their properties/values are removed. All non-integer and non-string values (booleans, functions, arrays, etc.) are omitted. Altogether... ( src/styled.js ) If we substitute styled-components with this implementation, then the application still works. ( src/components/Heading.jsx ) Nevertheless, this implementation only inlines styles directly on the element. It does not generate custom CSS class names and cannot process SCSS-like syntax with nesting, such as &:hover . styled-components uses the CSS preprocessor Stylis to compile code written with this syntax into CSS code. The purpose of this implementation is to demonstrate how styled-components works under-the-hood at a high level. Let's clone the repository react-d3-charts , a component library that contains customizable D3 visualizations written in React and TypeScript. Currently, this repository only has one visualization component, a scatterplot. Inside of the project directory, install the dependencies: Install the library  styled-components as a dependency. Next, install @types/styled-components , which has TypeScript types for the styled-components library, as a dev. dependency. Inside of the src/components/XAxis.tsx file, which houses the component that renders a x-axis for the scatterplot component, observe that the two <text /> elements draw upon the same set of attributes and values: font family, font size and fill. If the component had many <text /> elements that rely on these same attributes, then there will be more repetitive JSX code. Let's place these styles within a single styled component named StyledText . Swap out the <text /> element with the <StyledText /> component and omit the fill , fontFamily and fontSize attributes. If you inspect this styled component via the developer console, then you will see a custom CSS class name added to the <text /> element. We can create styled components for the <path /> and <line /> elements. If you inspect these styled components via the developer console, then you will see custom CSS class names added to the <path /> and <line /> elements. If you check the contents of src/components/YAxis.tsx , then you will see that the y-axis has the same elements with the same styles as the x-axis: <path /> , <text /> and <line /> . We can refactor the code to make the styled components <StyledPath /> , <StyledText /> and <StyledLine /> reusable for the <YAxis /> component. Create a new folder src/styled and a new file src/styled/index.ts . Move all of the styled components into src/styled/index.ts and export them. ( src/styled/index.ts ) Inside of both src/components/XAxis.tsx and src/components/YAxis.tsx , substitute the <path /> , <text /> and <line /> elements with the styled components <StyledPath /> , <StyledText /> and <StyledLine /> exported from the src/styled/index.ts file. ( src/components/XAxis.tsx ) ( src/components/YAxis.tsx ) For a final version of this tutorial, check out the GitHub repository here . Add more styled components to this library! If you already maintain a React component library, then try adding styled components to your library.

Thumbnail Image of Tutorial Styling React Components with styled-components

How to Build a Composable Stack Component

Photo by  Sean Stratton  on  Unsplash One of the simplest and yet most common layout patterns found on the web is putting one element on top of another element with consistent space between them. From form labels, to paragraphs of text, to social media feeds. They all need to stack one thing on top of another with uniform space between them.  Let's say we are building the following component: As you will notice, we have a few parts to this widget. There is a title section and a form section made up of two input groups and a button. The one thing that they all have in common is that they follow the same pattern. They all stack vertically with space between them. Here is the same mockup with the different space sizes pointed out. What we need is a way to enforce that all the items will stack in the block direction. We also need a way to provide consistent space between the elements without creating space around the stacked elements themselves. That way, the stack can remain composable in any other environment. (I will be using Styled Components  in these examples, but everything can easily be translated to any flavor of CSS, including vanilla CSS.) Let's start with some basic markup. And this is what that looks like: The first problem we want to solve is to get the labels to stack on top of our inputs. This problem is easily solved with a single line of CSS: We create a new Stack component and set the display property to grid , thereby implicitly setting a single column track for items inside the Stack. Each item that is placed in that column creates an implicit row. We can then use this new Stack a component like this: Our component has already taken a major step in the right direction: The first thing you will notice is that not only are the labels stacked on top of each other, they also now take up the entire width of the column. All we need to do now is set the space between the items. We set the space between items using the gap property, which takes any valid sizing unit, such as px , % , or rem . To make it configurable via props, we will take advantage of the styled-components string interpolation and derive the value from props, like this: (If the syntax above is unfamiliar to you, it uses tagged template literals that are part of ES2015. You can find out more about tagged template literals over at MDN ) When we use styled.div we are calling a tagged template literal that will let us pass in a function inside the ${} that gives us access to the component props . We can then customize what the CSS looks like depending on the value of the props . The above code takes the value of the gutter prop and uses that as the value of the gap property. We could have used any name for the prop , such as space or even gap . I chose to use gutter as it is a common term when talking about page layouts. If no value is passed to gutter , it will fall back to 1rem . This means we can rewrite our Subscribe  component like this: And now our component looks like the final version: We have a component that will universally stack all of its children and will separate them via a configurable value that passed into the gutter prop. We could stop here, but I would recommend one more tweak to the gutter prop. Right now, we are allowing any value passed into the gutter. It is considered best practice to adopt a spacing scheme when you are laying out items on the web for consistency. Choosing a good spacing scheme is beyond the scope of this post. For simplicity, let's use a spacing scheme based on t-shirt sizes and looks something like this: Now, all we need to do is adjust our Stack component slightly, like this: and update our Subscribe  component like this: The Stack component is a straightforward yet powerful tool that allows you to compose vertical stacks of elements on your page.  

Thumbnail Image of Tutorial How to Build a Composable Stack Component

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Connecting Serverless Django to an Amazon RDS Instance (Part 1)

Serverless computing revolutionizes cloud infrastructure by having developers provision services and define resource demands with code rather than manually configuring hardware from scratch. Designing an application around a serverless architecture and workflow not only saves development time, but also drives down costs for scaling and operation expenses. Cloud computing platforms, such as Amazon Web Services (AWS), offer and maintain a plethora of serverless computing services to automate basic tasks and allow developers to deploy new services quickly. With AWS Lambda, instead of routing all incoming requests to a single server instance that hosts multiple API endpoints, we can distribute these endpoints across many functions. Since each function runs its own container, different functions can be allocated different amounts of memory and CPU power depending on the function's needs. Coupled with spinning up containers only in response to events and keeping them idle during inactivity (not online 24/7 like a traditional server), the savings compound exponentially while still serving end users. Regardless of traffic volume, AWS Lambda automatically creates instances of your function to meet this demand and only charges you for the function's run time and the total number of times it is invoked (per 1 million requests). The fact that AWS manages this entire infrastructure layer (e.g., system patches, security updates, etc.) by itself lets developers focus more on their own infrastructure. AWS Lambda provides runtimes to support various languages, such as Python and Java. There are many open-source libraries and utilities available for developing, deploying and securing serverless applications. For Python applications, Zappa makes the deployment process to a serverless environment simple via several built-in CLI utilities and a zappa_settings.json configuration file. Whether you want to deploy small microservices written with a framework like Flask , or large web applications written with a framework like Django , Zappa handles the deployment the same way without any additional framework-specific configuration. A limitation of Zappa is its inability to scaffold other AWS services/resources, such as RDS database instances (Aurora, PostgreSQL, MySQL, MariaDB, Oracle or SQL Server), during deployment. If your application directly connects to and accesses these AWS services/resources, then we must first provision those services/resources within the AWS Management Console. Below, I'm going to show you how to create an RDS database instance (specifically PostgreSQL) and connect it to a Django application deployed onto a Lambda function. Both the database and Lambda function will be placed within a private subnet of a VPC (virtual private network) to protect them from public Internet access. To get started, clone the following repository to your local machine: This repository's README.md file contains instructions on how to deploy and test a serverless Django application using Docker and Zappa. For Zappa to successfully deploy the Django application to AWS, visit the IAM console and enable the following permission policies: During deployment ( zappa deploy <stage> ), Zappa packages the application, dependencies and virtual environment into a Lambda-compatible archive, which is uploaded to an S3 bucket. Once it sets up the Lambda function, the IAM roles and policies and API Gateway resource, Zappa deletes the archive from the S3 bucket. Using middleware, Zappa turns API Gateway requests into WSGI requests, which can be processed with Python. Once done, Zappa returns the response through the API Gateway. The server is only alive during the execution of the function. If you decide to undo the deployment of the application via the command zappa undeploy <stage> , then Zappa automatically tears down the published API Gateway and Lambda function. Inside of the AWS IAM console, create a new user by clicking the "Add user" button. Name the user serverless-django-admin and enable programmatic access, which means an access key ID and secret access key must be provided to an AWS API, CLI, etc. to interact with AWS services. Under "Attach existing policies directly," check the permission policies mentioned above. Verify the list of permissions and create the user. Copy the access key ID and secret access key and paste them within the .env.* files. Set the environment variable AWS_ACCESS_KEY_ID to the access key ID and AWS_SECRET_ACCESS_KEY to the secret access key. A small network consists of resources connected to one other, such as a Django application connected to a database. Unrestricted access (from the public Internet) to any of these resources leaves them vulnerable to attacks from outside parties. If the database contains any sensitive or personally identifiable information, and this data becomes compromised, then you will be held liable for the data breach! Ideally, the database should have a firewall to filter out all traffic that does not originate from the Django application. A virtual private cloud (VPC) lets you to isolate parts of your network ("subnets") from the public Internet by controlling inbound and outbound traffic via security groups that act as "virtual firewalls." Amazon VPC comes with 65,536 private IP addresses available to be allocated to resources by default, which accounts for both small and large private networks. The network can be divided into subnets, which each groups a subset of the network's resources. Subnets are either private or public. Resources within a private subnets are not accessible from the public Internet. However, they can only access the public Internet under special circumstances. Resources within a public subnets are accessible from and can access the public Internet. To create a VPC, visit the AWS VPC console and click on the "Launch VPC Wizard" button. This opens the VPC wizard, which guides you through the process of creating a VPC step-by-step. The wizard presents four options: Since the Lambda function serving the Django application will be publicly accessible from the public Internet via an invocation URL and the PostgreSQL database will be protected from the public Internet, select the "VPC with Public and Private Subnets" option. The public subnet will host a network address translation (NAT) gateway, which allows resources within a private subnet to be accessed from the public Internet. The private subnet will host our Lambda function and RDS database, and the security group rules of the RDS database will be modified to only accept traffic from other resources within the same network. This way, only the Lambda function is accessible from the public Internet. Let's create these two subnets. The IPv4 CIDR block determines the range of IP addresses available for allocation within a subnet. For the public subnet, set the public subnet's IPv4 CIDR block to 10.0.0.0/21 and the private subnet's IPv4 CIDR block to 10.0.8.0/21 . Each has over two thousand IP addresses, which should be more than sufficient. If you need more IP addresses, then pick different blocks. For the public subnet to be reachable from the public Internet, you must obtain an Elastic IP address , which is a static, public IPv4 address, and associate it to the NAT gateway. To obtain an Elastic IP address, skip to the "Obtaining an Elastic IP Address" section and follow the directions. Copy the allocation ID of the Elastic IP address and come back to the wizard. Paste this ID into the "Elastic IP Allocation ID" field. Note : If you want to keep the private subnet completely isolated from the public Internet (and accessible from a corporate network, etc.), then go back to "Step 1: Select a VPC Configuration" of the wizard and choose the option "VPC with a Private Subnet Only and Hardware VPN Access." Once the VPC is successfully created, you will find the VPC listed under "Your VPCs." Additionally, you will find the VPC's private and public subnets listed under "Subnets." Under "Security Groups," you will find the VPC's default security group. All instances of the Lambda function belong to this security group. When we provision our RDS database, we will need to assign a security group to it, so take note of the security group's ID for later. An Elastic IP address is easy to obtain. Inside of the AWS VPC console, select "Elastic IPs" under the "Virtual Private Cloud" collapsible list in the left sidebar. Click on the "Allocate Elastic IP address" button. Leave the Elastic IP address settings on the default settings, unless you pick a specific network border group , which determines where AWS advertises IP addresses. Click the "Allocate" button to allocate this IP address. Once the Elastic IP address is allocated successfully, copy the allocation ID to associate to the VPC's NAT gateway. Continue on to the second part of this tutorial here , which dives into provisioning an AWS RDS PostgreSQL database and setting its security group rules.

Thumbnail Image of Tutorial Connecting Serverless Django to an Amazon RDS Instance (Part 1)

Automating a React Library's Build Process with RollupJS and Babel

The meteoric adoption of TypeScript in recent years has led to the increased publication of well-documented, robust libraries. TypeScript boosts developer productivity and lessens the likelihood of bugs (and typos) by embracing static code analysis and feeding suggestions to code completion engines, but at the cost of additional bloat (from type annotations and syntactic sugar) and tooling requirements. Although TypeScript is a superset of JavaScript, web browsers and runtimes, such as Node.js, cannot execute TypeScript code. Furthermore, applications written in JavaScript cannot import TypeScript libraries as modules. If you choose to write a library in TypeScript, then you need to identify the library's target audience: Depending on the configuration of your library's build process, the library's module bundler can output compiled versions of the library that address these scenarios. For example, if a developer has written their application using the module format ES modules , then they can import the ES module version of the library (outputted into a .mjs file by the module bundler) at the top of the application's source code via an import statement. Since ES modules was released several years ago as part of the ES6 standard, the JavaScript language had no native implementation for importing/exporting modules prior to the ES6 standard. With older module formats, such as CommonJS and UMD, still actively used by some codebases, you may want to specify these formats as outputs of the library's module bundler to maximize the library's usage and adoption by other developers. Commonly, a library's build process involves the RollupJS module bundler and Babel JavaScript compiler convert code written with the latest features of JavaScript (and/or non-standard syntaxes, such as TypeScript and JSX) into efficient " flat distributables ." Babel compiles the code while RollupJS generates a distributable (within a dist folder) for each module format you decide to support. For example, the library may have one distributable for CommonJS (a .cjs file) and another for ES module (an .mjs file). Regardless of the module format, these distributables are capable of running on older JavaScript engines. Ideally, anytime you make changes to your library and push those changes to its remote repository, those changes should trigger an automated workflow to rebuild the distributables and bump its version accordingly. Updating distributables this way allows developers to quickly receive the latest copies of your library. Below, I'm going to show you how to automate a React library's build process using RollupJS and Babel. To get started, clone the following repository: This repository contains a component library with customizable D3 visualizations written in React and TypeScript. Currently, this repository only has one visualization component, a scatterplot. Inside of the project directory, install the dependencies: For this tutorial, we will be adding RollupJS and Babel to this library. Browsers and certain environments cannot run TypeScript and JSX code. Therefore, we must install Babel to compile this code into JavaScript code that can run on these technologies. Plus, you may need to transform newer JavaScript features (ES2015+), such as arrow functions or async / await , if you decide to target older browsers, such as Internet Explorer. Note : A plugin applies a single transformation to the code, whereas a preset is a collection of plugins. To configure Babel, create a .babelrc.json file. Inside of .babelrc.json , list the installed presets and plugins. For this library, let's target browsers with more than 0.2% market share and are not considered "dead." ( .babelrc.json ) Note : >0.2% , not dead and not op_mini all are queries used to filter for the target browsers. To check out the list of browsers that fall under these Browserslist queries, run the following command: Before installing RollupJS, the library must provide an entry point , which tells RollupJS where to start building the bundle. RollupJS crawls the library's modules to create a module dependency graph based on its imports/exports. From there, RollupJS uses this graph to drop any unused dependencies (known as tree-shaking) and generate the bundle using the finalized graph and an object of output options. The entry point serves as the root node of the graph and determines which modules will end up in the bundled output. For this library, the entry point is src/index.ts , which exports each React component (along with their prop interfaces) via aggregate exports. ( src/index.ts ) All components exported within this module are publicly available to be consumed by applications importing it. Install the following dependencies: Within the root of the project directory, create a rollup.config.js file, which configures RollupJS. Commonly, RollupJS configurations involve three options: ( rollup.config.js ) For our library, we will output two bundles: one for CommonJS and one for ES modules. Since the output option of the RollupJS configuration references file paths from package.json , let's update the package.json file with these paths, which tell RollupJS where to place the build output. ( package.json ) Note : sideEffects reassures a module bundler that unused modules do not have "side-effects," and thus, they can be safely removed from the module dependency graph. Essentially, this option grants the module bundler permission to tree-shake. Now, let's update package.json 's scripts with build scripts. ( package.json ) Finally, run the following command to build the library: Check out the contents of the dist/index.cjs.js and dist/index.esm.js files. Notice that in both files, all instances of let and const have been replaced with var , JSX code has been replaced with calls to React.createElement , etc. For a final version of this tutorial, check out the GitHub repository here . Add a build process to your React library!

Thumbnail Image of Tutorial Automating a React Library's Build Process with RollupJS and Babel

Composing Layouts

Composition, simply put, is when you build something greater than the sum of its parts. For example, an organism is composed of organs, which are composed of organ parts, which are composed of cells, which are composed of atoms. A musical composition can be broken down to nothing more than masterfully applying rhythm and tempo to 12 unique notes, creating all of our musical masterpieces. Composition also applies to web layout. Complex layouts can be broken down into simpler "layout primitives," as described by Heydon Pickering . These layout primitives are single-purpose layout components that do one thing and one thing well. It is by strategically combining these primitives that we achieve more complex layout structures. Let's take the below hero layout, for example: Naively we might choose to do something like this: Several CSS methodologies like BEM , Object-Oriented CSS(OOCSS) , or Atomic CSS  can help create more consistent class names and are generally useful in managing our CSS style sheets at scale. Unfortunately, those methodologies can only get you so far. When we approach our component's layout as something unique for each component, we miss a fantastic opportunity to define a consistent visual structure in our application. Instead, all of our layouts are treated as unique things that need to be built from scratch over and over again. Instead of looking at our Hero component as one isolated element, let's break it up into smaller, single-purpose layout components, like this: (Don't worry about how these components are implemented right now. Just focus on the intended outcome of the components.) Then we can apply these layout components like this: In code, this would translate to something like this: These "layout primitives" can be applied in a signup form, a blog post feed, a feature page, or any other part of our web page. Most of the layouts we use every day are not that unique and can be broken down, at least in part, to one of a handful of layout patterns. Thinking in terms of layout composition can feel strange at first. Probably one of the more difficult parts is knowing **where** you should apply your style rules in your component.

Thumbnail Image of Tutorial Composing Layouts