Tag: Project

5 Mistakes I Made When Starting My First React Project

You know what it’s like to pick up a new language or framework. Sometimes there’s great documentation to help you find your way through it. But even the best documentation doesn’t cover absolutely everything. And when you work with something that’s new, you’re bound to find a problem that doesn’t have a written solution.

That’s how it was for me the first time I created a React project — and React is one of those frameworks with remarkable documentation, especially now with the beta docs. But I still struggled my way through. It’s been quite a while since that project, but the lessons I gained from it are still fresh in my mind. And even though there are a lot of React “how-to” tutorials in out there, I thought I’d share what I wish I knew when I first used it.

So, that’s what this article is — a list of the early mistakes I made. I hope they help make learning React a lot smoother for you.

Using create-react-app to start a project

TL;DR Use Vite or Parcel.

Create React App (CRA) is a tool that helps you set up a new React project. It creates a development environment with the best configuration options for most React projects. This means you don’t have to spend time configuring anything yourself.

As a beginner, this seemed like a great way to start my work! No configuration! Just start coding!

CRA uses two popular packages to achieve this, webpack and Babel. webpack is a web bundler that optimizes all of the assets in your project, such as JavaScript, CSS, and images. Babel is a tool that allows you to use newer JavaScript features, even if some browsers don’t support them.

Both are good, but there are newer tools that can do the job better, specifically Vite and Speedy Web Compiler (SWC).

These new and improved alternatives are faster and easier to configure than webpack and Babel. This makes it easier to adjust the configuration which is difficult to do in create-react-app without ejecting.

To use them both when setting up a new React project you have to make sure you have Node version 12 or higher installed, then run the following command.

npm create vite

You’ll be asked to pick a name for your project. Once you do that, select React from the list of frameworks. After that, you can select either Javascript + SWC or Typescript + SWC

Then you’ll have to change directory cd into your project and run the following command;

npm i && npm run dev

This should run a development server for your site with the URL localhost:5173

And it’s as simple as that.

Using defaultProps for default values

TL;DR Use default function parameters instead.

Data can be passed to React components through something called props. These are added to a component just like attributes in an HTML element and can be used in a component’s definition by taking the relevant values from the prop object passed in as an argument.

// App.jsx export default function App() {   return <Card title="Hello" description="world" /> }  // Card.jsx function Card(props) {   return (     <div>       <h1>{props.title}</h1>       <p>{props.description}</p>     </div>   ); }  export default Card;

If a default value is ever required for a prop, the defaultProp property can be used:

// Card.jsx function Card(props) {   // ... }  Card.defaultProps = {   title: 'Default title',   description: 'Desc', };  export default Card;

With modern JavaScript, it is possible to destructure the props object and assign a default value to it all in the function argument.

// Card.jsx function Card({title = "Default title", description= "Desc"}) {   return (     <div>       <h1>5 Mistakes I Made When Starting My First React Project</h1>       <p>{description}</p>     </div>   ) }  export default Card;

This is more favorable as the code that can be read by modern browsers without the need for extra transformation.

Unfortunately, defaultProps do require some transformation to be read by the browser since JSX (JavaScript XML) isn’t supported out of the box. This could potentially affect the performance of an application that is using a lot of defaultProps.

Don’t use propTypes

TL;DR Use TypeScript.

In React, the propTypes property can be used to check if a component is being passed the correct data type for its props. They allow you to specify the type of data that should be used for each prop such as a string, number, object, etc. They also allow you to specify if a prop is required or not.

This way, if a component is passed the wrong data type or if a required prop is not being provided, then React will throw an error.

// Card.jsx import { PropTypes } from "prop-types";  function Card(props) {   // ... }  Card.propTypes = {   title: PropTypes.string.isRequired,   description: PropTypes.string, };  export default Card;

TypeScript provides a level of type safety in data that’s being passed to components. So, sure, propTypes were a good idea back when I was starting. However, now that TypeScript has become the go-to solution for type safety, I would highly recommend using it over anything else.

// Card.tsx interface CardProps {   title: string,   description?: string, }  export default function Card(props: CardProps) {   // ... }

TypeScript is a programming language that builds on top of JavaScript by adding static type-checking. TypeScript provides a more powerful type system, that can catch more potential bugs and improves the development experience.

Using class components

TL;DR: Write components as functions

Class components in React are created using JavaScript classes. They have a more object-oriented structure and as well as a few additional features, like the ability to use the this keyword and lifecycle methods.

// Card.jsx class Card extends React.Component {   render() {     return (       <div>         <h1>{this.props.title}</h1>         <p>{this.props.description}</p>       </div>     )   } }  export default Card;

I prefer writing components with classes over functions, but JavaScript classes are more difficult for beginners to understand and this can get very confusing. Instead, I’d recommend writing components as functions:

// Card.jsx function Card(props) {   return (     <div>       <h1>{props.title}</h1>       <p>{props.description}</p>     </div>   ) }  export default Card;

Function components are simply JavaScript functions that return JSX. They are much easier to read, and do not have additional features like the this keyword and lifecycle methods which make them more performant than class components.

Function components also have the advantage of using hooks. React Hooks allow you to use state and other React features without writing a class component, making your code more readable, maintainable and reusable.

Importing React unnecessarily

TL;DR: There’s no need to do it, unless you need hooks.

Since React 17 was released in 2020, it’s now unnecessary to import React at the top of your file whenever you create a component.

import React from 'react'; // Not needed! export default function Card() {}

But we had to do that before React 17 because the JSX transformer (the thing that converts JSX into regular JavaScript) used a method called React.createElement that would only work when importing React. Since then, a new transformer has been release which can transform JSX without the createElement method.

You will still need to import React to use hooks, fragments, and any other functions or components you might need from the library:

import { useState } from 'react';  export default function Card() {   const [count, setCount] = useState(0);   // ... }

Those were my early mistakes!

Maybe “mistake” is too harsh a word since some of the better practices came about later. Still, I see plenty of instances where the “old” way of doing something is still being actively used in projects and other tutorials.

To be honest, I probably made way more than five mistakes when getting started. Anytime you reach for a new tool it is going to be more like a learning journey to use it effectively, rather than flipping a switch. But these are the things I still carry with me years later!

If you’ve been using React for a while, what are some of the things you wish you knew before you started? It would be great to get a collection going to help others avoid the same struggles.


5 Mistakes I Made When Starting My First React Project originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

CSS-Tricks

, , , , ,

Using CSS Cascade Layers to Manage Custom Styles in a Tailwind Project

If a utility class only does one thing, chances are you don’t want it to be overridden by any styles coming from elsewhere. One approach is to use !important to be 100% certain the style will be applied, regardless of specificity conflicts.

The Tailwind config file has an !important option that will automatically add !important to every utility class. There’s nothing wrong with using !important this way, but nowadays there are better ways to handle specificity. Using CSS Cascade Layers we can avoid the heavy-handed approach of using !important.

Cascade layers allow us to group styles into “layers”. The precedence of a layer always beats the specificity of a selector. Specificity only matters inside each layer. Establishing a sensible layer order helps avoid styling conflicts and specificity wars. That’s what makes CSS Cascade Layers a great tool for managing custom styles alongside styles from third-party frameworks, like Tailwind.

A Tailwind source .css file usually starts something like this:

@tailwind base; @tailwind components; @tailwind utilities; @tailwind variants;

Let’s take a look at the official Tailwind docs about directives:

Directives are custom Tailwind-specific at-rules you can use in your CSS that offer special functionality for Tailwind CSS projects. Use the @tailwind directive to insert Tailwind’s base, components, utilities and variants styles into your CSS.

In the output CSS file that gets built, Tailwind’s CSS reset — known as Preflight — is included first as part of the base styles. The rest of base consists of CSS variables needed for Tailwind to work. components is a place for you to add your own custom classes. Any utility classes you’ve used in your markup will appear next. Variants are styles for things like hover and focus states and responsive styles, which will appear last in the generated CSS file.

The Tailwind @layer directive

Confusingly, Tailwind has its own @layer syntax. This article is about the CSS standard, but let’s take a quick look at the Tailwind version (which gets compiled away and doesn’t end up in the output CSS). The Tailwind @layer directive is a way to inject your own extra styles into a specified part of the output CSS file.

For example, to append your own styles to the base styles, you would do the following:

@layer base {   h1 {     font-size: 30px;   } }

The components layer is empty by default — it’s just a place to put your own classes. If you were doing things the Tailwind way, you’d probably use @apply (although the creator of Tailwind recently advised against it), but you can also write classes the regular way:

@layer components {   .btn-blue {     background-color: blue;     color: white;   } }

The CSS standard is much more powerful. Let’s get back to that…

Using the CSS standard @layer

Here’s how we can rewrite this to use the CSS standard @layer:

@layer tailwind-base, my-custom-styles, tailwind-utilities;  @layer tailwind-base {   @tailwind base; }  @layer tailwind-utilities {   @tailwind utilities;   @tailwind variants; } 

Unlike the Tailwind directive, these don’t get compiled away. They’re understood by the browser. In fact, DevTools in Edge, Chrome, Safari, and Firefox will even show you any layers you’ve defined.

CSS Cascade Layers with Tailwind CSS layers in DevTools.

You can have as many layers as you want — and name them whatever you want — but in this example, all my custom styles are in a single layer (my-custom-styles). The first line establishes the layer order:

@layer tailwind-base, my-custom-styles, tailwind-utilities;

This needs to be provided upfront. Be sure to include this line before any other code that uses @layer. The first layer in the list will be the least powerful, and the last layer in the list will be the most powerful. That means tailwind-base is the least powerful layer and any code in it will be overridden by all the subsequent layers. That also means tailwind-utilities will always trump any other styles — regardless of source order or specificity. (Utilities and variants could go in separate layers, but the maintainers of Tailwind will ensure variants always trump utilities, so long as you include the variants below the utilities directive.)

Anything that isn’t in a layer will override anything that is in a layer (with the one exception being styles that use !important). So, you could also opt to leave utilities and variants outside of any layer:

@layer tailwind-base, tailwind-components, my-custom-styles;  @layer tailwind-base {   @tailwind base; }  @layer tailwind-components {   @tailwind components; }  @tailwind utilities; @tailwind variants;

What did this actually buy us? There are plenty of times when advanced CSS selectors come in pretty handy. Let’s create a version of :focus-within that only responds to keyboard focus rather than mouse clicks using the :has selector (which lands in Chrome 105). This will style a parent element when any of its children receive focus. Tailwind 3.1 introduced custom variants — e.g. <div class="[&:has(:focus-visible)]:outline-red-600"> — but sometimes it’s easier to just write CSS:

@layer tailwind-base, my-custom-styles; @layer tailwind-base {   @tailwind base; }  @tailwind utilities;  @layer my-custom-styles {   .radio-container {     padding: 4px 24px;     border: solid 2px rgb(230, 230, 230);   }   .radio-container:has(:focus-visible) {     outline: solid 2px blue;   } }

Let’s say in just one instance we want to override the outline-color from blue to something else. Let’s say the element we’re working with has both the Tailwind class .outline-red-600 and our own .radio-container:has(:focus-visible) class:

<div class="outline-red-600 radio-container"> ... </div>

Which outline-color will win?

Ordinarily, the higher specificity of .radio-container:has(:focus-visible) would mean the Tailwind class has no effect — even if it’s lower in the source order. But, unlike the Tailwind @layer directive that relies on source order, the CSS standard @layer overrules specificity.

As a result, we can use complex selectors in our own custom styles but still override them with Tailwind’s utility classes when we need to — without having to resort to heavy-handed !important usage to get what we want.


Using CSS Cascade Layers to Manage Custom Styles in a Tailwind Project originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

CSS-Tricks

, , , , , , ,
[Top]

How the Heck Do You Install an Existing npm Project?

(This is a sponsored post.)

We’ve gotten a good overview of how npm works and how to use it to install packages and run commands at this point. Now let’s go a little further and see what it looks like to download and install an existing npm project, rather than starting one from scratch. More likely than not, that’s probably what you’ll be doing most of the time. It’s much, much easier than installing and configuring all the individual pieces one by one.

That’s what we’re covering in this final chapter of the guide to npm, and I’ll be drawing from personal experience on a real-life project of mine.

Guide chapters

  1. Who the Heck is This Guide For?
  2. What the Heck Does “npm” Mean?
  3. What the Heck is the Command Line?
  4. What the Heck is Node?
  5. What the Heck is a Package Manager?
  6. How the Heck Do You Install npm?
  7. How the Heck Do You Install npm Packages?
  8. What the Heck Are npm Commands?
  9. How the Heck Do You Install an Existing npm Project? (You are here!)

Here’s a real-life npm project

The project I’ve chosen for this is my own SvelteKit static blog starter. I think it’s a nice example because it comes with lots of pre-installed packages that are great for demonstration purposes.

This is a real project of mine that’s designed to give you—as you might have guessed by the name—a head-start for building a statically-generated blog site. (“Statically generated” means that our code will be compiled down to .html files, ready to deploy anywhere on the web. This is one of a few approaches encompassed in the “Jamstack” way of building sites.)

And no worries if you don’t know anything about SvelteKit—this is just to demonstrate, and we won’t write anything you don’t already know. That said, it’s worth noting that SvelteKit uses Vite under the hood, which is actually a npm package that gives us access to modern build tools and a super speedy development server.

Cloning the project

First, we need to “clone” the project, which is a fancy word for copying the project to our system so we can work on it locally. There are two ways to clone an existing project.

If you prefer the in-browser, visual way, head to the starter repo over at GitHub, and click the “Code” dropdown that’s located directly in GitHub’s UI, and select the “Download ZIP” option.

A screenshot of a GitHub repo zoomed in to the top-right corner of the page with the Code button clicked and showing options to clone the repository. The option to download a ZIP file has a big white arrow pointing at it towards the left to call it out for this existing npm project.

Alternatively, if you prefer using the command line instead, run this command (just make sure you’re in a place where you don’t mind a new project folder added to your computer, e.g. cd /path/to/folder):

npx degit https://github.com/josh-collinsworth/sveltekit-blog-starter.git sveltekit-blog-starter 

You may remember that npx allows us to run npm packages without permanently installing them. degit clones the project just like git clone would, but without its Git history (literally, “de-git”).

Whichever method you use, you get a fresh new sveltekit-blog-starter folder. Let’s open it in a code editor, pop open the terminal, and run the npm install (or npm i) command.

An open dark Terminal that has run the npm i command to install an existing npm project called sveltekit-blocg-starter. 202 npm packages are installed in three seconds. There are zero vulnerabilities.
npm automatically runs an audit when installing packages.

At this point, you’ll see a note about vulnerabilities, like we covered in the last section of this guide. It may say something like “found 0 vulnerabilities” (as it does in screenshot above), but it’s quite possible that number will be greater than zero. If you do see vulnerabilities, don’t worry. You’re free to ignore it for now since this isn’t a project we intend to launch in production for others to see or use. (See the section on npm audit in a previous chapter for more info.)

Starting the server and making changes

If you were to peek inside of the package.json file in the cloned project, you’d see the command to start the dev server:

npm run dev

Run that command in the terminal and you should see something like the following almost immediately:

An open dark terminal window that ran the npm run dev command. The terminal output shows that a localhost address has been set up where the development for the project can be previewed.

In VS Code, you can press CMD while clicking the http://localhost:3000 URL, or you can manually enter it in your browser. Either way, the site should be displayed in the browser!

A screenshot of a website that is open at a localhost URL, demonstrating that the development server for the npm project is running and can be viewed in the browser. The site has a light aqua header with a My Awesome Blog heading followed by three navigation links, all centered in the container. After that is the main body of the page with a faint pale green background and darker text, including a heading that says SvelteKit static blog starter followed by a short description of the project and an unordered list of features.

Let’s take just a moment here to appreciate how relatively fast and simple that was! Yes, we might have had to install a bunch of scaffolding first, but that’s an up-front, one-time cost. We have an entire project running on our machine with just a couple of commands—and we can do this same thing any time we want to install another existing project!

I won’t go deep into the details of this particular project because it’s unimportant to learning npm, but it’s a nice example because it has lots of cool things pre-configured, and we can easily make changes and see them update right away in the browser. Let’s look at a few of those commands next.

SvelteKit requires Node 14 or higher. If you installed npm as part of this guide, that won’t be a problem for you. But if you already had it installed before we started, and if you run into errors trying to get this project running, it’s worth a quick node -v to be sure. nvm is your friend if you need to upgrade.

Automatically compile Sass on save

You can find the project’s Sass files in the src/lib/assets/scss/ folder. Try opening the global.scss file directly. Make a change, save it, and you should see the update automatically (and almost instantly) in your browser.

An animated GIF showing the development site preview open on the left and the VS Code editor on the write with a global.scss file open. The body font size is changed in the Sass code, then saved, which triggers an immediate new preview in the browser without having to manually reload the page.

Making content changes

The starter site actually uses the repo’s README.md file as its homepage. If you open README.md and begin making changes (it’s OK if you don’t know Markdown, any edit will do), you should also see those changes show up as soon as you save just like Sass did in the last step:

If you want, you can open another page, say the src/routes/contact.svelte file, and update the HTML to see it live refresh in your browser as well as soon as it saves.

You can even duplicate one of the Markdown files inside of src/routes/blog/_posts/ and make edits to see that it automatically appear in the list of posts on the /blog page, if you want to go that far. (Just be sure to give it a unique title.)

Understanding imports

There’s one important thing about npm projects that we mentioned briefly in the fourth chapter, but haven’t covered yet: imports. This guide wouldn’t really be complete if we didn’t touch on that. The basic idea is that we can—true to the name—import a package, only do so without ever installing it either in a project folder or your system. Instead, it’s used on the spot.

How so? Open up the svelte.config.js folder in the project root, and you’ll see a block of import lines at the top, something like this:

import adapter from '@sveltejs/adapter-static' import { mdsvex } from 'mdsvex' import preprocess from 'svelte-preprocess' import rehypeAutolinkHeadings from 'rehype-autolink-headings' import rehypeSlug from 'rehype-slug'

Every one of those imports is an installed package used in this file. What each package actually does isn’t important right now; I just want to call attention to the import syntax. This is how we use packages in our actual code files; we tell JavaScript what to import and from where. Then we can call it in our code.

This syntax is called “ES6 imports,” which is only important (get it?!) to know because it’s the standard that both browser-based JavaScript and Node JavaScript have agreed on using going forward.

Previously, Node JavaScript used (and often still uses) a slightly different syntax called CommonJS. If you see an import that looks like this, that’s the old CommonJS style:

const myPackage = require('package-name')

The other crucial thing to understand about the ES6 style of import is: the syntax is npm-specific, not a language standard.

To be clear: you can use import in normal JavaScript. It’s a very ordinary feature of the language. But you need to provide a relative path, or (in more modern browsers) a URL to whatever you’re importing. Just using a string with a package’s slug, like we see here, though, isn’t valid.

So why is it used if it’s not technically valid code? Because handling this style of import is one of the nice things npm does for us. When we tell npm to import somePackage from 'name' as a string, npm automatically knows to go search through the installed packages on the project to find the import what we asked for. This saves us from both typing tedious relative paths, and from actually needing to know where our packages live deep in the labyrinth of node_modules.

This may go without saying, but: since the syntax isn’t valid, you won’t be able to use it successfully unless your npm project includes a bundler or compiler of some kind, to process the imports and modules into valid browser code.

Building the final site

Most npm projects like this have two main purposes:

  1. Help you develop your site or app
  2. Build a finalized, production version

SvelteKit is no exception. When we’re done with our (awesome) development server setup and happy with our changes, we can run this command:

npm run build

If your dev server is still running, you can either stop it with Ctrl+C, or open up a new terminal tab. You won’t be able to type any commands in the same terminal window where the dev process is running since it’s an active, continuous task.

When we run the build command, SvelteKit chews through all the files in the project and spits out a fully bundled, ready-to-deploy collection of static HTML, CSS and JavaScript files, and does so rather quickly. You could upload this collection of files anywhere you can host a website. Modern tooling; good old-fashioned output.

When the build command finishes, you should see a new build folder in the root (i.e. top level) of your project folder. If you look through it, you’ll notice there are no longer .md, .svelte, or any other files that can’t be read by a browser. Everything has been compiled into pure HTML, CSS and JavaScript, not to mention—as you’ll see if you open a JavaScript or CSS file—they are thoroughly minified to be as small as possible to load in the browser as fast as possible.

If you want, you can run npm run preview once the build is finished to see how the compiled site loads in the browser. The difference here is that the content will be loaded from the final build folder, rather than built with pre-compiled files on the fly as it would when using the dev command. You won’t see any difference unless you open up the Network tab in DevTools (or try to update something), but you’ll be looking at the final product.

This is an optional step, but I think it’s pretty cool to get an idea of how few compiled files we actually end up with, considering all the various files we put into the project, and how tiny the final bundle actually is, thanks to the amazing build tools built into this project. (For the record, it’s all SvelteKit and Vite.)

Modern deployment practices

This is a topic for another time, but modern deployment often doesn’t require you to run a build command and upload the files yourself (though that’s still an option). Instead, a host (like Netlify or Vercel) connects directly to the GitHub repo of your project and, whenever you push changes to the main branch of the repo, the host runs your build command for you and deploys the compiled files automatically!

That’s one of the many extremely nice features of this new era of front-end development. No messing with FTP or manually dragging files anywhere; we are confident that everything is built and deployed automatically when we push our code, without us needing to do anything!

Wrapping up this npm guide

If you’ve made it this far, congratulations! And thank you. Congratulations, because this was a long, long read. And thank you, because… well, it was a long, long read.

But you made it, and hopefully, you learned some important things as well. I mentioned at the start that my goal was not brevity, but effectiveness. That means we covered a lot. We started with a brief overview of npm and where it fits in the modern front-end development landscape before getting familiar with the command line. From there, we broke down the terms “Node” and “package manager” to get a precise understanding of what npm is and does. Once we got acquainted with the role that packages managers play in development, we dove straight into npm, including how to install it, add packages to a project, set up commands, and finally, how to jump into an existing project that uses npm.

My hope is that everything we covered in this npm guide at least opens the door enough for you to explore npm further and level up when you’re ready. It often takes me repeating something many times and trying multiple approaches for something to truly sink in. So, if you’re sitting there feeling almost as confused as you were before, take some more time on this. Reflect on what you know and what you’ve learned, and come back—or try a new approach when you’re ready!

Guide chapters

  1. Who the Heck is This Guide For?
  2. What the Heck Does “npm” Mean?
  3. What the Heck is the Command Line?
  4. What the Heck is Node?
  5. What the Heck is a Package Manager?
  6. How the Heck Do You Install npm?
  7. How the Heck Do You Install npm Packages?
  8. What the Heck Are npm Commands?
  9. How the Heck Do You Install an Existing npm Project? (You are here!)

How the Heck Do You Install an Existing npm Project? originally published on CSS-Tricks. You should get the newsletter and become a supporter.

CSS-Tricks

, , ,
[Top]

My tiny side project has had more impact than my decade in the software industry

That’s a heartwrenching title from Michael Williamson. I believe it though. It’s kinda like a maximized version of the blogging phenomenon where if you work on a post for weeks it’ll flop compared to a post that’s some dumb 20-minute thought. Or how your off-handed remark to some developer at the perfect time might cause some huge pivot in what they are doing, changing the course of a project forever. For Mike, it was a 3,000 line-of-code side project that had more impact on the world than a career of work as a software developer.

I’ve tried to pick companies working on domains that seem useful: developer productivity, treating diseases, education. While my success in those jobs has been variable – in some cases, I’m proud of what I accomplished, in others I’m pretty sure my net effect was, at best, zero – I’d have a tough time saying that the cumulative impact was greater than my little side project.

Impact is fuzzy though, isn’t it? I don’t know Mike, but assuming he is a kind and helpful person, think of all the people he’s likely helped along the way. Not by just saving them minutes of toil, but helped. Helped grow, helped through hard times, helped guide to where they ought to go. Those things are immeasurable and awfully important.

Direct Link to ArticlePermalink


The post My tiny side project has had more impact than my decade in the software industry appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , , , , , ,
[Top]

How to Automate Project Versioning and Releases with Continuous Deployment

Having a semantically versioned software will help you easily maintain and communicate changes in your software. Doing this is not easy. Even after manually merging the PR, tagging the commit, and pushing the release, you still have to write release notes. There are a lot of different steps, and many are repetitive and take time.

Let’s look at how we can make a more efficient flow and completely automating our release process by plugin semantic versioning into a continuous deployment process.

Semantic versioning

A semantic version is a number that consists of three numbers separated by a period. For example, 1.4.10 is a semantic version. Each of the numbers has a specific meaning.

Major change

The first number is a Major change, meaning it has a breaking change.

Minor change

The second number is a Minor change, meaning it adds functionality.

Patch change

The third number is a Patch change, meaning it includes a bug fix.

It is easier to look at semantic versioning as Breaking . Feature . Fix. It is a more precise way of describing a version number that doesn’t leave any room for interpretation.

Commit format

To make sure that we are releasing the correct version — by correctly incrementing the semantic version number — we need to standardize our commit messages. By having a standardized format for commit messages, we can know when to increment which number and easily generate a release note. We are going to be using the Angular commit message convention, although we can change this later if you prefer something else.

It goes like this:

<header> <optional body> <optional footer>

Each commit message consists of a header, a body, and a footer.

The commit header

The header is mandatory. It has a special format that includes a type, an optional scope, and a subject.

The header’s type is a mandatory field that tells what impact the commit contents have on the next version. It has to be one of the following types:

  • feat: New feature
  • fix: Bug fix
  • docs: Change to the documentation
  • style: Changes that do not affect the meaning of the code (e.g. white-space, formatting, missing semi-colons, etc.)
  • refactor: Changes that neither fix a bug nor add a feature
  • perf: Change that improves performance
  • test: Add missing tests or corrections to existing ones
  • chore: Changes to the build process or auxiliary tools and libraries, such as generating documentation

The scope is a grouping property that specifies what subsystem the commit is related to, like an API, or the dashboard of an app, or user accounts, etc. If the commit modifies more than one subsystem, then we can use an asterisk (*) instead.

The header subject should hold a short description of what has been done. There are a few rules when writing one:

  • Use the imperative, present tense (e.g. “change” instead of “changed” or “changes”).
  • Lowercase the first letter on the first word.
  • Leave out a period (.) at the end.
  • Avoid writing subjects longer than 80 charactersThe commit body.

Just like the header subject, use the imperative, present tense for the body. It should include the motivation for the change and contrast this with previous behavior.

The footer should contain any information about breaking changes and is also the place to reference issues that this commit closes.

Breaking change information should start with BREAKING CHANGE: followed by a space or two new lines. The rest of the commit message goes here.

Enforcing a commit format

Working on a team is always a challenge when you have to standardize anything that everyone has to conform to. To make sure that everybody uses the same commit standard, we are going to use Commitizen.

Commitizen is a command-line tool that makes it easier to use a consistent commit format. Making a repo Commitizen-friendly means that anyone on the team can run git cz and get a detailed prompt for filling out a commit message.

Generating a release

Now that we know our commits follow a consistent standard, we can work on generating a release and release notes. For this, we will use a package called semantic-release. It is a well-maintained package with great support for multiple continuous integration (CI) platforms.

semantic-release is the key to our journey, as it will perform all the necessary steps to a release, including:

  1. Figuring out the last version you published
  2. Determining the type of release based on commits added since the last release
  3. Generating release notes for commits added since the last release
  4. Updating a package.json file and creating a Git tag that corresponds to the new release version
  5. Pushing the new release

Any CI will do. For this article we are using GitHub Action, because I love using a platform’s existing features before reaching for a third-party solution.

There are multiple ways to install semantic-release but we’ll use semantic-release-cli as it provides takes things step-by-step. Let’s run npx semantic-release-cli setup in the terminal, then fill out the interactive wizard.

Th script will do a couple of things:

  • It runs npm adduser with the NPM information provided to generate a .npmrc.
  • It creates a GitHub personal token.
  • It updates package.json.

After the CLI finishes, it wil add semantic-release to the package.json but it won’t actually install it. Run npm install to install it as well as other project dependencies.

The only thing left for us is to configure the CI via GitHub Actions. We need to manually add a workflow that will run semantic-release. Let’s create a release workflow in .github/workflows/release.yml.

name: Release on:   push:     branches:       - main jobs:   release:     name: Release     runs-on: ubuntu-18.04     steps:       - name: Checkout         uses: actions/checkout@v2       - name: Setup Node.js         uses: actions/setup-node@v1         with:           node-version: 12       - name: Install dependencies         run: npm ci       - name: Release         env:           GITHUB_TOKEN: $ {{ secrets.GITHUB_TOKEN }}         # If you need an NPM release, you can add the NPM_TOKEN         #   NPM_TOKEN: $ {{ secrets.NPM_TOKEN }}         run: npm run release

Steffen Brewersdorff already does an excellent job covering CI with GitHub Actions, but let’s just briefly go over what’s happening here.

This will wait for the push on the main branch to happen, only then run the pipeline. Feel free to change this to work on one, two, or all branches.

on:   push:     branches:       - main

Then, it pulls the repo with checkout and installs Node so that npm is available to install the project dependencies. A test step could go, if that’s something you prefer.

- name: Checkout uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v1 with:     node-version: 12 - name: Install dependencies run: npm ci # You can add a test step here # - name: Run Tests # run: npm test

Finally, let semantic-release do all the magic:

- name: Release run: npm run release

Push the changes and look at the actions:

The GitHub Actions screen for a project showing a file navigating on the left and the actions it includes on the right against a block background.

Now each time a commit is made (or merged) to a specified branch, the action will run and make a release, complete with release notes.

Showing the GitHub releases screen for a project with an example that shows a version 1.0.0 and 2.0.0, both with release notes outlining features and breaking changes.

Release party!

We have successfully created a CI/CD semantic release workflow! Not that painful, right? The setup is relatively simple and there are no downsides to having a semantic release workflow. It only makes tracking changes a lot easier.

semantic-release has a lot of plugins that can make an even more advanced automations. For example, there’s even a Slack release bot that can post to a project channel once the project has been successfully deployed. No need to head over to GitHub to find updates!


The post How to Automate Project Versioning and Releases with Continuous Deployment appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , , ,
[Top]

Run Gulp as You Open a VS Code Project

When I open my local project for this very site, there is a 100% chance that I need to run this command before anything else: gulp. I set that up fresh less than a year ago so I’m on the latest-and-greatest stuff and have my workflow just how I like it. I did a few more tweaks a few months later to make things a smidge nicer (even adding a fancy fun little dock icon!).

That’s when I learned about VS Code Tasks. Generically, the can just run command line tasks that you configure whenever you choose to run them by name. But I’m particularly compelled by the idea that they can run when you open a project.

It’s this easy to run Gulp:

{   "version": "2.0.0",   "tasks": [     {       "label": "Run Gulp",       "command": "gulp",       "type": "shell",       "runOptions": {         "runOn": "folderOpen"       }     }   ] }

Except… that started to fail on my machine. I use nvm to manage Node versions, and despite my best effort to nvm alias default to the the correct version of Node that works nicely with Gulp, the Node version was always wrong, and thus running gulp would fail. The trick is to run nvm use first (which sets the correct version from my .nvmrc file), then gulp runs fine.

That works fine in a fresh terminal window, but for some reason, even making the command run two tasks like this (chaining them with a semicolon):

"command": "nvm use; gulp",

…it would still fail. It didn’t know what nvm meant. I don’t know what the heart of the problem is exactly (why one terminal doesn’t know the same things that another terminal does), but I did manage to sort out that the global nvm has a shell script with one job: defining the nvm command. So you “source” that, as they say, and then the nvm command works.

So my final setup is:

{   "version": "2.0.0",   "tasks": [     {       "label": "Run Gulp",       "command": ". ~/.nvm/nvm.sh; nvm use; gulp",       "type": "shell",       "runOptions": {         "runOn": "folderOpen"       }     }   ] } 

And that, dear readers, runs Gulp perfectly when I open my CSS-Tricks project, which is exactly what I wanted.

High five to Jen Luker who went on this journey with me and helped me get it to the finish line. 🤚


The post Run Gulp as You Open a VS Code Project appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , ,
[Top]

What I Learned by Fixing One Line of CSS in an Open Source Project

I was browsing the Svelte docs on my iPhone and came across a blaring UI bug. The notch in the in the REPL knob was totally out of whack. I’m always looking to contribute to open source, and I thought this would be a quick and easy fix. Turns out, there was a lot more to it than just changing one line of CSS. 

Replicating, debugging, setting up the local environment was interesting, difficult, and meaningful.

The issue

I opened my browser DevTools, thinking I’d see the same issue in the phone view. But, the bug wasn’t there. Now this is a seriously tricky CSS problem.

💡 What I learned

If you’re using Chrome on iOS as your browser, you’re still using Safari’s renderer. From Wikipedia:

Chrome uses the iOS WebKit – which is Apple’s own mobile rendering engine and components, developed for their Safari browser – therefore it is restricted from using Google’s own V8 JavaScript engine.

This is backed up by caniuse, which provides this note on iPS Safari:

Screenshot of caniuse with a note saying the safari browser for iOS is tried to the operating system, so the numbers used are based on the OS version.

Now it’s clear why the issue wasn’t showing up on my machine but it was showing up on my phone. Different rendering engines! 

Reproduce the issue locally

I pulled down the project and ran it locally. I confirmed it was still an issue by running the local code in a simulator as well as on my actual iPhone. Safari on macOS has an easy way to open up DevTools instances of each one.

Screenshot of the Safari Develop menu expanded with the Simulator option highlighted in blue.

This provides access to a console just like you would in the browser but for iOS Safari.  I’m not going to lie, Apple’s developer experience is top notch (see what I did there? 😬).

I’m able to reproduce the issue locally now.

💡 What I learned

After pulling down the Svelte repo and looking around the code a bit, I noticed the UI and SVGs were being pulled in via a package called @sveltejs/site-kit. Great, now I need my local version of site kit to get pulled into svelte/site so I can see changes and debug the issue.

I needed to point the node_modules in Svelte’s package.json to my local copy of site-kit. This sounded like a Symlink. After looking through the docs without much luck I Googled around and stumbled upon npm-link. That let me see what I was doing!

I can now make local changes to site-kit and see them reflected in the Svelte project.

Solving the issue

Seriously, all this needed was a one-line change:

border: transparent;

But locating where that one line should go was not as straightforward as you’d think. Source maps on the project are still a little rough around the edges and are showing this CSS coming from the Nav.svelte component when it was really coming from another file. That would be another great way to contribute to the project!

Then you search around and learn that this is being handled and you learn a little more about how it’s done. Everything now looks great on mobile and desktop.

That’s all it needed!

Let’s rewind

What started as a quick, one-line change became a bit of a journey. I had to:

  • Run the project and component repositories
  • Learn about system linking
  • Contribute documentation about lining to site-kit
  • Learn about different browser renderers
  • Learn how to emulate an iOS Safari browser
  • Learn how to get access to its debugger
  • Find the issue when source maps weren’t working correctly
  • Fix the issue (finally!)

Working on your own, you normally don’t get to deal with issues like this, or have a large complex system you need to build a mental model of and learn. You don’t get to learn from maintainers. Most importantly, you don’t see all of the hard work that goes into building a popular technical product.

When I submitted this idea to CSS-Tricks. Chris said he had recently dealt with a similar situation. Difficult learning is durable learning. Embrace the struggle.

Never stop learning

I grabbed another issue from the Svelte project and now I’m learning about CSSStyleSheet because there’s another issue (I think), with how Safari handles keyframe animations within stylemanager.ts. And so the learning continues down paths I never would have treaded in my day-to-day work.

When something breaks, enjoy the journey of learning the system. You’ll gain valuable insights into why that thing broke and what can be done to fix it. That’s one of the awesome benefits of contributing to open source projects and why I’d encourage you to do the same.


The post What I Learned by Fixing One Line of CSS in an Open Source Project appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS-Tricks

, , , , ,
[Top]

Become a Front-End Master in 2020 With These 10 Project Ideas

This is a little updated cross-post from a quickie article I wrote on DEV. I’m publishing here ‘cuz I’m all IndieWeb like that.

I love this post by Simon Holdorf. He’s got some ideas for how to level up your skills as a front-end developer next year. Here they are:

  • Build a movie search app using React
  • Build a chat app with Vue
  • Build a weather app with Angular
  • Build a to-do app with Svelte

… and 5 more like that.

All good ideas. All extremely focused on JavaScript frameworks.
I like thinking of being a front-end developer as being someone who is a browser person. You deal with people who use some kind of client to use the web on some kind of device. That’s the job.

I love JavaScript frameworks, but knowing them isn’t what makes you a good front-end developer. Being performance-focused and accessibility-focused, and thus user-focused is what makes you a front-end master, beyond executing the skills required to get the website built.

In that vein, here’s some more ideas.

  • Go find a Dribbble shot that appeals to you. Re-build it in HTML and CSS in the cleanest and most accessible way you can.
  • Find a component you can abstract in your codebase, and abstract it so you can re-use it efficiently. Consider accessibility as you do it. Could you make it more accessible in a way that benefits the entire site? How about your SVG icon component — how’s that looking these days?
  • Try out a static site generator (perhaps one that isn’t particularly JavaScript focused, just to experience it). What could the data source be? What could you make if you ran the build process on a timed schedule?
  • Install the Axe accessibility plugin for DevTools and run it on an important site you control. Make changes to improve the accessibility as it suggests.
  • Spin up a copy of Fractal. Check out how it can help you think about building front-ends as components, even at the HTML and CSS level.
  • Build a beautiful form in HTML/CSS that does something useful for you, like receive leads for freelance work. Learn all about form validation and see how much you can do in just HTML, then HTML plus some CSS, then with some vanilla JavaScript. Make the form work by using a small dedicated service.
  • Read a bit about Serverless and how it can extend your front-end developer skillset.
  • Figure out how to implement an SVG icon system. So many sites these days need an icon set. Inlining SVG is a great simple solution, but how you can abstract that to easily implement it with your workflow? How can it work with the framework you use?
  • Try to implement a service worker. Read a book about them. Do something very small. Check out a framework centered around them.
  • Let’s say you needed to put up a website where the entire thing was the name and address of the company, and a list of hours it is open. What’s the absolute minimum amount of work and technical debt you could incur to do it?

The post Become a Front-End Master in 2020 With These 10 Project Ideas appeared first on CSS-Tricks.

CSS-Tricks

, , , , , ,
[Top]

So, you think you’ve got project management nailed down

(This is a sponsored post.)

Who needs a project manager? You’re an organized person who can keep track of your own work, right?

Wrong.

Well, wrong if you’re part of a team. The thing about being self-organized is that it’s related to project management but not synonymous with it. Case in point: what happens if your project relies on someone else’s involvement? Sure you’re organized, but can you always say the same about your co-workers? Chances are you need something to keep everyone in sync so that a project stays on course.

That’s where you should consider trying monday.com.

monday.com is project management, but with a human touch. Sure, there’s task lists, assignments, milestones, due dates, and such like you would expect from any project management tool. That’s a given. That said, monday.com takes things up a notch by stripping away the barriers that prevent team members from collaborating with one another. For example, monday.com includes real-time messaging, file sharing, reporting, and a slew of other features that bridge the gaps between people and tasks so that everyone has purview into the progress of a project. Plus, it’s so pretty to look at.

There’s so much more than meets the eye because monday.com goes beyond project management. There’s resource management that ensures you have the right tools for a project, forecasting to affirm the prospect of a business opportunity, and even client management services. Seriously, your team and perhaps company can lean into monday.com and get a ton of use out of it.

You know what to do from here. Give monday.com a try. There’s a free trial and we’re sure you’ll find it to be so useful that you’ll want to stick with it well beyond.

Get Started

Direct Link to ArticlePermalink

The post So, you think you’ve got project management nailed down appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

So, you think you’ve got project management nailed down

(This is a sponsored post.)

Who needs a project manager? You’re an organized person who can keep track of your own work, right?

Wrong.

Well, wrong if you’re part of a team. The thing about being self-organized is that it’s related to project management but not synonymous with it. Case in point: what happens if your project relies on someone else’s involvement? Sure you’re organized, but can you always say the same about your co-workers? Chances are you need something to keep everyone in sync so that a project stays on course.

That’s where you should consider trying monday.com.

monday.com is project management, but with a human touch. Sure, there’s task lists, assignments, milestones, due dates, and such like you would expect from any project management tool. That’s a given. That said, monday.com takes things up a notch by stripping away the barriers that prevent team members from collaborating with one another. For example, monday.com includes real-time messaging, file sharing, reporting, and a slew of other features that bridge the gaps between people and tasks so that everyone has purview into the progress of a project. Plus, it’s so pretty to look at.

There’s so much more than meets the eye because monday.com goes beyond project management. There’s resource management that ensures you have the right tools for a project, forecasting to affirm the prospect of a business opportunity, and even client management services. Seriously, your team and perhaps company can lean into monday.com and get a ton of use out of it.

You know what to do from here. Give monday.com a try. There’s a free trial and we’re sure you’ll find it to be so useful that you’ll want to stick with it well beyond.

Get Started

Direct Link to ArticlePermalink

The post So, you think you’ve got project management nailed down appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]