Archiwum kategorii: CSS

When’s the last time you SFTP’d (or the like) into a server and changed a file directly?

Post pobrano z: When’s the last time you SFTP’d (or the like) into a server and changed a file directly?

In the grand tradition of every single poll question I’ve ever posted, the poll below has a has a fundamental flaw. In this case, there is no option between „In the last month” and „Never” but, alas, the results are interesting:

When's the last time you SFTP'd (or the equiv) into a server and changed a file directly?

— Chris Coyier (@chriscoyier) October 9, 2018

What I was trying to get at with this poll is how many people do and don’t do any sort of editing of production files directly and instead work locally. I don’t think I need to launch a major investigation to know that it’s most people and more than in the past.

Most workflows these days have us working locally and pushing new and updated files through a version control system, and even through systems beyond that, perhaps continuous integration processes, testing processes, actions, deployment — it’s big world of DevOps out there! Rarely do we skip the line and dip our fingers into production servers and make live manipulations. Cowboy coding, they sometimes call it.

But just because you don’t generally code that way doesn’t mean you never do it, which is another flaw of this poll. I know DevOps nerds who are constantly SSH-ing into servers to manipulate configuration files. I personally still hop into Coda and will directly SFTP into servers sometimes to edit .htaccess files, which are sometimes on my production sites and dev sites and that I generally .gitignore.

Anyways, I think this is a fun thing to talk about, so feel free to have at it in the comments. I’d love to hear to what degree you cowboy code. Still do it all the time and love it? Do you do it because you haven’t learned another way or that’s how your workplace demands? Do you have a personal philosophy about it? Let the rodeo begin. 🤠

The post When’s the last time you SFTP’d (or the like) into a server and changed a file directly? appeared first on CSS-Tricks.

Get References from HTML Built with Template Literals

Post pobrano z: Get References from HTML Built with Template Literals

One thing JavaScript template literals are great at is little blocks of HTML. Like:

// Probably from some API or whatever
const data = {
  title: "Title",
  content: "Content"
};

const some_html = `
  <div class="module">
    <h2>${data.title}</h2>
    <p>${data.content}</p>
  </div>
`;

But that’s still just a string. It’s not ready to append to the DOM just yet. And what if we need references to those elements inside somehow?

We’ve written about a couple of libraries that are in this vein: lit-html and hyperHTML. Those are pretty small libs, but are also sorta more about re-rendering of templates in an efficient way (like super mini React).

What if you just need the nodes? That’s almost a one-liner:

const getNodes = str => { 
  return new DOMParser().parseFromString(str, 'text/html').body.childNodes;
}

Now we could drop that template literal of HTML right into the DOM:

document.body.appendChild(getNodes(some_html)[0]);

Here’s that:

See the Pen pQyZOz by Chris Coyier (@chriscoyier) on CodePen.

But how do we get our hands on individual bits of that HTML? We don’t exactly have references to anything, even the whole chunk we put in.

I just saw this little lib called Facon that looks to do just this. It makes use of tagged template literals, which is super cool:

import f from 'facon';

const data = {
  title: "Title",
  content: "Content"
};

let html = f`
  <div class="module">
    <h2>${data.title}</h2>
    <p>${data.content}</p>
  </div>
`;

document.body.appendChild(html);

This skips the need for our little getNodes function, but more importantly, we can yank out those references!

let html = f`
  <div class="module">
    <h2 ref="title">${data.title}</h2>
    <p ref="content">${data.content}</p>
  </div>
`;

let { title, content } = html.collect();
title.innerText = "Title Changed!";

Here’s that:

See the Pen Facon Template by Chris Coyier (@chriscoyier) on CodePen.

The post Get References from HTML Built with Template Literals appeared first on CSS-Tricks.

CSS-Tricks Uses Jetpack

Post pobrano z: CSS-Tricks Uses Jetpack

(This is a sponsored post.)

Hey! I made a little page to explain all the ways in which this very site uses the Jetpack WordPress plugin.

Here’s the gist of it:

  • Our Jetpack subscription gives us VaultPress, which backs up literally everything on this site in real time. That helps me sleep.
  • Jetpack improves our site search and allows it to be tweaked and the design customized.
  • Jetpack connects to Twitter and Facebook, so as we publish posts it can kick out tweets and updates.
  • Jetpack allows us to author content in Markdown (and you to comment in Markdown).
  • Jetpack adds social login buttons to the comment form, so you don’t have to be troubled to type out your name and email.
  • We display related posts on articles, and Jetpack does a crack job of it without stressing out our server.

But Jetpack has way more features than that. That’s just what we use, what you might find useful for your site could be totally different.

Direct Link to ArticlePermalink

The post CSS-Tricks Uses Jetpack appeared first on CSS-Tricks.

Symbolic Links for Easier Multi-Folder Local Development

Post pobrano z: Symbolic Links for Easier Multi-Folder Local Development

You know how you open a „project” in a local code editor? I guess different editors have different terminology for it, but essentially what you are doing is opening a folder/directory and it shows you a sidebar full of files and folders you can navigate through and such.

Typically there is one parent folder, and everything else is within that folder. Right? Well, it doesn’t have to be! That’s where symbolic links come in.

Otherwise known as symlinks, they are like pointers to another place. While you don’t have to actually move the folder you are referencing, you can create a pointer to it that behaves as if you did.

You can create them right from the command line:

ln -s /path/to/original/ /path/to/link

You’ll get a link that looks like an „alias” on macOS. Ya know, the things you can make by right-clicking an item or going File > Make Alias. But they are different. In my experience, aliases tend not to work in code editors, but symlinks do.

Looks like an alias, but it’s really a symlink.

I was actually lazy (hey, I prefer GUIs for just about everything) and used Nick Zitzmann’s symboliclinker context menu plugin to help make the link I wanted (and allow me to make other ones super easy).

Why bother? I’ve had a handful of occasions over the years, but here’s one that just came up for me. I’m working on a WordPress theme, and there is a WordPress Functionality Plugin that goes with it. Ideally, I’d have just my theme folder open in my code editor (no need to have the entire WordPress root there, that would just slow my editor and make searching a mess). But I’d also like to have that plugin open at the same time, so in case I’m calling functions and such that the plugin controls, I can see both. But these folders are in totally different places…

No matter, I can put a symlink to the plugin in the theme. (You may want to .gitignore it, depending on your deployment setup and such.) Now I can search and find things in both places like I want:

I know that some editors have their own concept of this, like VS Code’s Multi-root Workspaces and how you can Project > Add Folder to Project in Sublime. But symlinks are a way to do the same thing but in a cross-editor and cross-system way that everyone can use!

The post Symbolic Links for Easier Multi-Folder Local Development appeared first on CSS-Tricks.

monday.com, a new way to manage your work! Meet the new visual project management tool

Post pobrano z: monday.com, a new way to manage your work! Meet the new visual project management tool

(This is a sponsored post.)

monday.com is a centralized platform for teams to manage every detail of their work, from high-level roadmap planning to the specifics of day-to-day tasks, while building a culture of transparency. It is a tool for an any-sized team, which can start with two freelancers working together to thousands collaborating across the globe. The tool is really popular amongst non-tech teams, often replacing burdensome excel files, whiteboards, and excessively long meetings.

The main thing is that it’s not limited to tech companies, it is used by churches, construction companies, schools and universities, startups, fortune 500 companies including WeWork, Samsung, Discovery Channel, Wix, NBC, General Assembly, McDonalds, Uber, Wix, AOL, and Adidas. Currently, it has over 22,000 paying teams.

monday.com is a tool to help people work better together. monday.com is not a project management tool because it isn’t projects that need managing, it’s people. People are any company’s most valuable resource and as people, we all face the same workplace challenges; communicating with others, not feeling appreciated or motivated to do our jobs, a lack of understanding of how our work fits into the bigger picture, among so many others. Those are the essential problems Monday is trying to solve.

What can this app do?

  • Creating and managing project’s milestones
  • Creating and assigning task
  • Attaching files to any project’s tabhe projects on the go.
  • Using mobile applications to manage projects
  • Communicating with your team members
  • Updating team using the news feed
  • Possible to keep clients in the loop
  • Organizing the organization into teams
  • Creating detailed project’s charts and reports
  • Tracking the time your team members spend on tasks
  • Managing projects’ financials
  • Website as well as a desktop app for mac and windows

monday.com aims to make every user feel empowered and part of something bigger than their own individual tasks, and as a result, to boost collective productivity and transparency.

Direct Link to ArticlePermalink

The post monday.com, a new way to manage your work! Meet the new visual project management tool appeared first on CSS-Tricks.

monday.com, a new way to manage your work! Meet the new visual project management tool

Post pobrano z: monday.com, a new way to manage your work! Meet the new visual project management tool

(This is a sponsored post.)

monday.com is a centralized platform for teams to manage every detail of their work, from high-level roadmap planning to the specifics of day-to-day tasks, while building a culture of transparency. It is a tool for an any-sized team, which can start with two freelancers working together to thousands collaborating across the globe. The tool is really popular amongst non-tech teams, often replacing burdensome excel files, whiteboards, and excessively long meetings.

The main thing is that it’s not limited to tech companies, it is used by churches, construction companies, schools and universities, startups, fortune 500 companies including WeWork, Samsung, Discovery Channel, Wix, NBC, General Assembly, McDonalds, Uber, Wix, AOL, and Adidas. Currently, it has over 22,000 paying teams.

monday.com is a tool to help people work better together. monday.com is not a project management tool because it isn’t projects that need managing, it’s people. People are any company’s most valuable resource and as people, we all face the same workplace challenges; communicating with others, not feeling appreciated or motivated to do our jobs, a lack of understanding of how our work fits into the bigger picture, among so many others. Those are the essential problems Monday is trying to solve.

What can this app do?

  • Creating and managing project’s milestones
  • Creating and assigning task
  • Attaching files to any project’s tabhe projects on the go.
  • Using mobile applications to manage projects
  • Communicating with your team members
  • Updating team using the news feed
  • Possible to keep clients in the loop
  • Organizing the organization into teams
  • Creating detailed project’s charts and reports
  • Tracking the time your team members spend on tasks
  • Managing projects’ financials
  • Website as well as a desktop app for mac and windows

monday.com aims to make every user feel empowered and part of something bigger than their own individual tasks, and as a result, to boost collective productivity and transparency.

Direct Link to ArticlePermalink

The post monday.com, a new way to manage your work! Meet the new visual project management tool appeared first on CSS-Tricks.

Simple Named Grid Areas

Post pobrano z: Simple Named Grid Areas

I think of named grid areas in CSS Grids as bring-your-own syntactic sugar. You don’t absolutely need them (you could express grid placement in other ways), but it can make that placement more intuitive. And, hey, if I’m wrong about that, correct me in the comments.

Say you set up a 3-column grid:

.grid {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: 
     200px  1fr  1fr;
}

No rows defined there; those are implicit and will appear as needed. We could define them, we just aren’t, because like most situations in web design, we don’t care how tall the items are — the height will grow as needed to accomodate the content.

Now, how do we place something in that very top-left position in the grid? We could tell the grid to place it there like this:

.item {
  grid-column: 1 / 2; /* start at the first grid column line and end at the second */
}

That works, although that .item better be the first child of .grid. Otherwise, something else may implicitly be placed there and .item will kick down to the next open row. If we wanted to be super sure to place it in the top-left, we could do the row as well:

.item {
  grid-column: 1 / 2;
  grid-row: 1 / 2;
}

Now it will be in the top-left for sure, even if other items are explicitly placed there (they’ll just overlap). We can even shorten things up with the grid-area property:

.item {
  grid-area: 1 / 1 / 2 / 2;
}

All those 1’s and 2’s might be intuitive enough for now, but the numbers become a bit much in more complex grids involving both column and row placement.

Check this. While we are defining the columns, we can name them with a separate property:

.grid {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: 
     200px  1fr  1fr;
  grid-template-areas:
    "pro    a    b"
    "pro    c    d";
}

Every quoted group in grid-template-areas is a row. Inside are names I just made up. Could be just about anything, as long as it makes sense to you. See how the word „pro” is repeated twice there on two rows? That’s important, as it’s saying that we could place a grid item where that value „pro” is and it will be in the first of three columns and span two rows. Pretty intuitive, yeah?

We place it like this:

.pro-features {
  /* rather than */
  grid-area: 1 / 1 / 2 / 3;
  /* we can now do */
  grid-area: pro;
}

Here’s that simple example:

See the Pen Simple Named Grid Areas by Chris Coyier (@chriscoyier) on CodePen.

Want to get even more descriptive with a grid? Try drawing it in your CSS comments.

The post Simple Named Grid Areas appeared first on CSS-Tricks.

Understanding React Render Props and HOC

Post pobrano z: Understanding React Render Props and HOC

Here’s a great post by Aditya Agarwal on the difference between render props and higher-order components in React. I particularly like the demo he chose to explain the two. But, to summarize:

Higher-order components (HOCs) take a component and return a component. So let’s say you have a component called Username that just returns a string of a user’s name and you want to capitalize that somewhere – this is the perfect opportunity to use a HOC that wraps that Username component and changes each character. Just like the excellent tutorial Kingsley Silas wrote up here on CSS-Tricks.

HOCs are particularly useful for when you want to modify a component and then use it in a bunch of places, or to make tiny batches of code to prevent overwhelming a component with too many options and props.

A render prop on the other hand is “a function prop that a component uses to know what to render.” At least, that’s what the React docs say, but it took me a while to figure it out. As far as I understand, it lets you provide a way for a React component (typically one that just has a bunch of data you want to reuse) and give it to another (so a component that then renders that data).

here’s a great example of this in the React docs:

class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>
        <Mouse render={mouse => (
          <Cat mouse={mouse} />
        )}/>
      </div>
    );
  }
}

What’s happening here is that someone defined a Mouse component in the codebase that provides x + y coordinates based on the position of the user’s mouse. This Mouse component then returns a bunch of data that we store as mouse and then pass it down into the Cat component which is what renders something with that data.

This is great when you want to reuse the data from Mouse but also when you want to pass lots of different types of data into the Cat component. Say you want Cat to render something else based on the type of data you feed into it.

So, to summarize: HOCs and render props are two ways to do similar work. Namely, they can break our code into lots of reusable bits and encourage us to make components that are more flexible in the long run.

Direct Link to ArticlePermalink

The post Understanding React Render Props and HOC appeared first on CSS-Tricks.

Continuous Integration: The What, Why and How

Post pobrano z: Continuous Integration: The What, Why and How

Not long ago, I had a novice understanding of Continuous Integration (CI) and thought it seemed like an extra process that forces engineers to do extra work on already large projects. My team began to implement CI into projects and, after some hands-on experience, I realized its great benefits, not only to the company, but to me, an engineer! In this post, I will describe CI, the benefits I’ve discovered, and how to implement it for free, and fast.

CI and Continuous Delivery (CD) are usually discussed together. Writing about both CI and CD within a post is a lot to write and read about all at once, so we’ll only discuss CI here. Maybe, I will cover CD in a future post. 😉

Table of Contents:

What is CI?

Continuous Integration, as I understand it, is a pattern of programming combining testing, safety checks, and development practices to confidently push code from a development branch to production ready branch continuously.

Microsoft Word is an example of CI. Words are written into the program and checked against spelling and grammar algorithms to assert a document’s general readability and spelling.

Why CI should be used everywhere

We’ve already touched on this a bit, but the biggest benefit of CI that I see is that it saves a lot of money by making engineers more productive. Specifically, it provides quicker feedback loops, easier integration, and it reduces bottlenecks. Directly correlating CI to company savings is hard because SaaS costs scale as the user base changes. So, if a developer wants to sell CI to the business, the formula below can be utilized. Curious just how much it can save? My friend, David Inoa, created the following demo to help calculate the savings.

See the Pen Continuous Integration (CI) Company Cost Savings Estimator by David (@davidinoa) on CodePen.

What really excites enough to scream to the top of the rooftops is how CI can benefit you and me as developers!

For starters, CI will save you time. How much? We’re talking hours per week. How? Oh, do I want to tell you! CI automatically tests your code and lets you know if it is okay to be merged in a branch that goes to production. The amount of time that you would spend testing your code and working with others to get code ready for production is a lot of time.

Then there’s the way it helps prevent code fatigue. It sports tools like Greenkeeper, which can automatically set up — and even merge — pull requests following a code review. This keeps code up-to-date and allows developers to focus on what we really need to do. You know, like writing code or living life. Code updates within packages usually only need to be reviewed for major version updates, so there’s less need to track every minor release for breaking changes that require action.

CI takes a lot of the guesswork out of updating dependencies that otherwise would take a lot of research and testing.

No excuses, use CI!

When talking to developers, the conversation usually winds up something like:

„I would use CI but…[insert excuse].”

To me, that’s a cop out! CI can be free. It can also be easy. It’s true that the benefits of CI come with some costs, including monthly fees for tools like CircleCI or Greenkeeper. But that’s a drop in the bucket with the long-term savings it provides. It’s also true that it will take time to set things up. But it’s worth calling out that the power of CI can be used for free on open source projects. If you need or want to keep your code private and don’t want pay for CI tools, then you really can build your own CI setup with a few great npm packages.

So, enough with the excuses and behold the power of CI!

What problems does CI solve?

Before digging in much further, we should cover the use cases for CI. It solves a lot of issues and comes in handy in many situations:

  • When more than one developer wants to merge into a production branch at once
  • When mistakes are not caught or cannot be fixed before deployment
  • When dependencies are out of date
  • When developers have to wait extended periods of time to merge code
  • When packages are dependent on other packages
  • When a package is updated and must be changed in multiple place
CI tests updates and prevents bugs from being deployed.

Recommended CI tools

Let’s look at the high level parts used to create a CI feedback loop with some quick code bits to get CI setup for any open source project today. We’ll break this down into digestible chunks.

Documentation

In order to get CI working for me right away, I usually set CI up to test my initial documentation for a project. Specifically, I use MarkdownLint and Write Good because they provide all the features and functionality I need to write tests for this part of the project.

The great news is that GitHub provides standard templates and there is a lot of content that can be copied to get documentation setup quickly. Read more about quickly setting up documentation and creating a documentation feedback loop.

I keep a package.json file at the root of the project and run a script command like this:

"grammar": "write-good *.md --no-passive",
"markdownlint": "markdownlint *.md"

Those two lines allow me to start using CI. That’s it! I can now run CI to test grammar.

At this point, I can move onto setting up CircleCI and Greenkeeper to help me make sure that packages are up to date. We’ll get to that in just a bit.

Unit testing

Unit tests are a method for testing small blocks (units) of code to ensure that the expected behavior of that block works as intended.

Unit tests provide a lot of help with CI. They define code quality and provide developers with feedback without having to push/merge/host code. Read more about unit tests and quickly setting a unit test feedback loop.

Here is an example of a very basic unit test without using a library:

const addsOne = (num) => num + 1 // We start with 1 as an initial value
  const numPlus1 = addsOne(3) // Function to add 3
  const stringNumPlus1 = addsOne('3') // Add the two functions, expect 4 as the value
    
  /**
    * console.assert
    * https://developer.mozilla.org/en-US/docs/Web/API/console/assert
    * @param test?
    * @param string
    * @returns string if the test fails
    **/
    
  console.assert(numPlus1 === 4, 'The variable `numPlus1` is not 4!')
  console.assert(stringNumPlus1 === 4, 'The variable `stringNumPlus1` is not 4!')

Over time, it is nice to use libraries like Jest to unit test code, but this example gives you an idea of what we’re looking at.

Here’s an example of the same test above using Jest:

const addsOne = (num) => num + 1

describe('addsOne', () => {
  it('adds a number', () => {
    const numPlus1 = addsOne(3)
    expect(numPlus1).toEqual(4)
  })
  it('will not add a string', () => {
    const stringNumPlus1 = addsOne('3')
    expect(stringNumPlus1 === 4).toBeFalsy();
  })
})

Using Jest, tests can be hooked up for CI with a command in a package.json like this:

"test:jest": "jest --coverage",

The flag --coverage configures Jest to report test coverage.

Safety checks

Safety checks help communicate code and code quality. Documentation, document templates, linter, spell checkers, and type checker are all safety checks. These tools can be automated to run during commits, in development, during CI, or even in a code editor.

Safety checks fall into more than one category of CI: feedback loop and testing. I’ve compiled a list of the types of safety checked I typically bake into a project.

All of these checks may seem like another layer of code abstraction or learning, so be gentle on yourself and others if this feels overwhelming. These tools have helped my own team bridge experience gaps, define shareable team patterns, and assist developers when they’re confused about what their code is doing.

  • Committing, merging, communicating: Tools like husky, commitizen, GitHub Templates, and Changelogs help keep CI running clean code and form a nice workflow for a collaborative team environment.
  • Defining code (type checkers): Tools like TypeScript define and communicate code interfaces — not only types!
  • Linting: This is the practice of ensuring that something matches defined standards and patterns. There’s a linter for nearly all programming languages and you’ve probably worked with common ones, like ESlint (JavaScript) and Stylelint (CSS) in other projects.
  • Writing and commenting: Write Good helps catch grammar errors in documentation. Tools like JSDoc, Doctrine, and TypeDoc assist in writing documentation and add useful hints in code editors. Both can compile into markdown documentation.

ESlint is a good example for how any of these types of tools are implemented in CI. For example, this is all that’s needed in package.json to lint JavaScript:

"eslint": "eslint ."

Obviously, there are many options that allow you to configure a linter to conform to you and your team’s coding standards, but you can see how practical it can be to set up.

High level CI setup

Getting CI started for a repository often takes very little time, yet there are plenty of advanced configurations we can also put to use, if needed. Let’s look at a quick setup and then move into a more advanced configuration. Even the most basic setup is beneficial for saving time and code quality!

Two features that can save developers hours per week with simple CI are automatic dependency updates and build testing. Dependency updates are written about in more detail here.

Build testing refers to node_modules installation during CI by running an install — for example, (npm install where all node_modules install as expected. This is a simple task and does fail. Ensuring that node_modules installs as expected saves considerable time!

Quick CI Setup

CI can be setup automatically for both CircleCI and Travis! If a valid test command is already defined in the repository’s package.json, then CI can be implemented without any more configuration.

In a CI tool, like CircleCI or Travis, the repository can be searched for after logging in or authentication. From there, follow the CI tool’s UI to start testing.

For JavaScript, CircleCI will look at test within a repository’s package.json to see if a valid test script is added. If it is, then CircleCI will begin running CI automatically! Read more about setting up CircleCI automatically here.

Advanced configurations

If unit tests are unfinished, or if a more configuration is needed, a .yml file can be added for a CI tool (like CircleCI) where the execute runner scripts are made.

Below is how to set up a custom CircleCI configuration with JavaScript linting (again, using ESlint as an example) for a CircleCI.

First off, run this command:

mkdir .circleci && touch .circleci/config.yml

Then add the following to generated file:

defaults: &defaults
  working_directory: ~/code
  docker:
    - image: circleci/node:10
  environment:
  NPM_CONFIG_LOGLEVEL: error # make npm commands less noisy
  JOBS: max <h3>https://gist.github.com/ralphtheninja/f7c45bdee00784b41fed
    version: 2
    jobs:
    build:
      <<: *defaults
      steps:
        - checkout
        - run: npm i
        - run: npm run eslint:ci

After these steps are completed and after CircleCI has been configured in GitHub (more on that here), CircleCI will pick up .circleci/config.yml and lint JavaScript in a CI process when a pull request is submitted.

I created a folder with examples in this demo repository to show ideas for configuring CI with config.yml filesand you can reference it for your own project or use the files as a starting point.

The are more even more CI tools that can be setup to help save developers more time, like auto-merging, auto-updating, monitoring, and much more!

Summary

We covered a lot here! To sum things up, setting up CI is very doable and can even be free of cost. With additional tooling (both paid and open source), we can have more time to code, and more time to write more tests for CI — or enjoy more life away from the screen!

Here are some demo repositories to help developers get setup fast or learn. Please feel free to reach out within the repositories with questions, ideas or improvements.

The post Continuous Integration: The What, Why and How appeared first on CSS-Tricks.

Continuous Integration: The What, Why and How

Post pobrano z: Continuous Integration: The What, Why and How

Not long ago, I had a novice understanding of Continuous Integration (CI) and thought it seemed like an extra process that forces engineers to do extra work on already large projects. My team began to implement CI into projects and, after some hands-on experience, I realized its great benefits, not only to the company, but to me, an engineer! In this post, I will describe CI, the benefits I’ve discovered, and how to implement it for free, and fast.

CI and Continuous Delivery (CD) are usually discussed together. Writing about both CI and CD within a post is a lot to write and read about all at once, so we’ll only discuss CI here. Maybe, I will cover CD in a future post. 😉

Table of Contents:

What is CI?

Continuous Integration, as I understand it, is a pattern of programming combining testing, safety checks, and development practices to confidently push code from a development branch to production ready branch continuously.

Microsoft Word is an example of CI. Words are written into the program and checked against spelling and grammar algorithms to assert a document’s general readability and spelling.

Why CI should be used everywhere

We’ve already touched on this a bit, but the biggest benefit of CI that I see is that it saves a lot of money by making engineers more productive. Specifically, it provides quicker feedback loops, easier integration, and it reduces bottlenecks. Directly correlating CI to company savings is hard because SaaS costs scale as the user base changes. So, if a developer wants to sell CI to the business, the formula below can be utilized. Curious just how much it can save? My friend, David Inoa, created the following demo to help calculate the savings.

See the Pen Continuous Integration (CI) Company Cost Savings Estimator by David (@davidinoa) on CodePen.

What really excites enough to scream to the top of the rooftops is how CI can benefit you and me as developers!

For starters, CI will save you time. How much? We’re talking hours per week. How? Oh, do I want to tell you! CI automatically tests your code and lets you know if it is okay to be merged in a branch that goes to production. The amount of time that you would spend testing your code and working with others to get code ready for production is a lot of time.

Then there’s the way it helps prevent code fatigue. It sports tools like Greenkeeper, which can automatically set up — and even merge — pull requests following a code review. This keeps code up-to-date and allows developers to focus on what we really need to do. You know, like writing code or living life. Code updates within packages usually only need to be reviewed for major version updates, so there’s less need to track every minor release for breaking changes that require action.

CI takes a lot of the guesswork out of updating dependencies that otherwise would take a lot of research and testing.

No excuses, use CI!

When talking to developers, the conversation usually winds up something like:

„I would use CI but…[insert excuse].”

To me, that’s a cop out! CI can be free. It can also be easy. It’s true that the benefits of CI come with some costs, including monthly fees for tools like CircleCI or Greenkeeper. But that’s a drop in the bucket with the long-term savings it provides. It’s also true that it will take time to set things up. But it’s worth calling out that the power of CI can be used for free on open source projects. If you need or want to keep your code private and don’t want pay for CI tools, then you really can build your own CI setup with a few great npm packages.

So, enough with the excuses and behold the power of CI!

What problems does CI solve?

Before digging in much further, we should cover the use cases for CI. It solves a lot of issues and comes in handy in many situations:

  • When more than one developer wants to merge into a production branch at once
  • When mistakes are not caught or cannot be fixed before deployment
  • When dependencies are out of date
  • When developers have to wait extended periods of time to merge code
  • When packages are dependent on other packages
  • When a package is updated and must be changed in multiple place
CI tests updates and prevents bugs from being deployed.

Recommended CI tools

Let’s look at the high level parts used to create a CI feedback loop with some quick code bits to get CI setup for any open source project today. We’ll break this down into digestible chunks.

Documentation

In order to get CI working for me right away, I usually set CI up to test my initial documentation for a project. Specifically, I use MarkdownLint and Write Good because they provide all the features and functionality I need to write tests for this part of the project.

The great news is that GitHub provides standard templates and there is a lot of content that can be copied to get documentation setup quickly. Read more about quickly setting up documentation and creating a documentation feedback loop.

I keep a package.json file at the root of the project and run a script command like this:

"grammar": "write-good *.md --no-passive",
"markdownlint": "markdownlint *.md"

Those two lines allow me to start using CI. That’s it! I can now run CI to test grammar.

At this point, I can move onto setting up CircleCI and Greenkeeper to help me make sure that packages are up to date. We’ll get to that in just a bit.

Unit testing

Unit tests are a method for testing small blocks (units) of code to ensure that the expected behavior of that block works as intended.

Unit tests provide a lot of help with CI. They define code quality and provide developers with feedback without having to push/merge/host code. Read more about unit tests and quickly setting a unit test feedback loop.

Here is an example of a very basic unit test without using a library:

const addsOne = (num) => num + 1 // We start with 1 as an initial value
  const numPlus1 = addsOne(3) // Function to add 3
  const stringNumPlus1 = addsOne('3') // Add the two functions, expect 4 as the value
    
  /**
    * console.assert
    * https://developer.mozilla.org/en-US/docs/Web/API/console/assert
    * @param test?
    * @param string
    * @returns string if the test fails
    **/
    
  console.assert(numPlus1 === 4, 'The variable `numPlus1` is not 4!')
  console.assert(stringNumPlus1 === 4, 'The variable `stringNumPlus1` is not 4!')

Over time, it is nice to use libraries like Jest to unit test code, but this example gives you an idea of what we’re looking at.

Here’s an example of the same test above using Jest:

const addsOne = (num) => num + 1

describe('addsOne', () => {
  it('adds a number', () => {
    const numPlus1 = addsOne(3)
    expect(numPlus1).toEqual(4)
  })
  it('will not add a string', () => {
    const stringNumPlus1 = addsOne('3')
    expect(stringNumPlus1 === 4).toBeFalsy();
  })
})

Using Jest, tests can be hooked up for CI with a command in a package.json like this:

"test:jest": "jest --coverage",

The flag --coverage configures Jest to report test coverage.

Safety checks

Safety checks help communicate code and code quality. Documentation, document templates, linter, spell checkers, and type checker are all safety checks. These tools can be automated to run during commits, in development, during CI, or even in a code editor.

Safety checks fall into more than one category of CI: feedback loop and testing. I’ve compiled a list of the types of safety checked I typically bake into a project.

All of these checks may seem like another layer of code abstraction or learning, so be gentle on yourself and others if this feels overwhelming. These tools have helped my own team bridge experience gaps, define shareable team patterns, and assist developers when they’re confused about what their code is doing.

  • Committing, merging, communicating: Tools like husky, commitizen, GitHub Templates, and Changelogs help keep CI running clean code and form a nice workflow for a collaborative team environment.
  • Defining code (type checkers): Tools like TypeScript define and communicate code interfaces — not only types!
  • Linting: This is the practice of ensuring that something matches defined standards and patterns. There’s a linter for nearly all programming languages and you’ve probably worked with common ones, like ESlint (JavaScript) and Stylelint (CSS) in other projects.
  • Writing and commenting: Write Good helps catch grammar errors in documentation. Tools like JSDoc, Doctrine, and TypeDoc assist in writing documentation and add useful hints in code editors. Both can compile into markdown documentation.

ESlint is a good example for how any of these types of tools are implemented in CI. For example, this is all that’s needed in package.json to lint JavaScript:

"eslint": "eslint ."

Obviously, there are many options that allow you to configure a linter to conform to you and your team’s coding standards, but you can see how practical it can be to set up.

High level CI setup

Getting CI started for a repository often takes very little time, yet there are plenty of advanced configurations we can also put to use, if needed. Let’s look at a quick setup and then move into a more advanced configuration. Even the most basic setup is beneficial for saving time and code quality!

Two features that can save developers hours per week with simple CI are automatic dependency updates and build testing. Dependency updates are written about in more detail here.

Build testing refers to node_modules installation during CI by running an install — for example, (npm install where all node_modules install as expected. This is a simple task and does fail. Ensuring that node_modules installs as expected saves considerable time!

Quick CI Setup

CI can be setup automatically for both CircleCI and Travis! If a valid test command is already defined in the repository’s package.json, then CI can be implemented without any more configuration.

In a CI tool, like CircleCI or Travis, the repository can be searched for after logging in or authentication. From there, follow the CI tool’s UI to start testing.

For JavaScript, CircleCI will look at test within a repository’s package.json to see if a valid test script is added. If it is, then CircleCI will begin running CI automatically! Read more about setting up CircleCI automatically here.

Advanced configurations

If unit tests are unfinished, or if a more configuration is needed, a .yml file can be added for a CI tool (like CircleCI) where the execute runner scripts are made.

Below is how to set up a custom CircleCI configuration with JavaScript linting (again, using ESlint as an example) for a CircleCI.

First off, run this command:

mkdir .circleci && touch .circleci/config.yml

Then add the following to generated file:

defaults: &defaults
  working_directory: ~/code
  docker:
    - image: circleci/node:10
  environment:
  NPM_CONFIG_LOGLEVEL: error # make npm commands less noisy
  JOBS: max <h3>https://gist.github.com/ralphtheninja/f7c45bdee00784b41fed
    version: 2
    jobs:
    build:
      <<: *defaults
      steps:
        - checkout
        - run: npm i
        - run: npm run eslint:ci

After these steps are completed and after CircleCI has been configured in GitHub (more on that here), CircleCI will pick up .circleci/config.yml and lint JavaScript in a CI process when a pull request is submitted.

I created a folder with examples in this demo repository to show ideas for configuring CI with config.yml filesand you can reference it for your own project or use the files as a starting point.

The are more even more CI tools that can be setup to help save developers more time, like auto-merging, auto-updating, monitoring, and much more!

Summary

We covered a lot here! To sum things up, setting up CI is very doable and can even be free of cost. With additional tooling (both paid and open source), we can have more time to code, and more time to write more tests for CI — or enjoy more life away from the screen!

Here are some demo repositories to help developers get setup fast or learn. Please feel free to reach out within the repositories with questions, ideas or improvements.

The post Continuous Integration: The What, Why and How appeared first on CSS-Tricks.