Dave Brock

Madison, WI

I'm a software developer living in Madison, Wisconsin.


If you do any work in open source, you probably live for GitHub. With all the time you spend using it, you can improve your experience by leveraging a variety of browser extensions.

The following is a rundown of my favorite GitHub extensions on my preferred browser, Google Chrome. While I am focusing on Chrome extensions, you'll find that there are plenty of GitHub extensions for other browsers, too.

Do you prefer a GitHub extension not listed here? Let me know in the comments!

Awesome Autocomplete for GitHub

The Awesome Autocomplete for GitHub extension, by Algolia, is by far my favorite GitHub Chrome extension.

This extension supercharges the top GitHub search bar by adding auto-completion, last active users, top public repositories, and more.

Search

You can even type aa<space> to find GitHub repositories directly from your Chrome address bar!

File Icon for GitHub, GitLab and Bitbucket

The default file icons in GitHub are so, so boring. Are you tired of seeing the default notepad icon next to every file, no matter the extension?

The File Icon for GitHub, GitLab and Gitbucket extension, by Homer Chen, adds file icons to GitHub repositories. Personally, this makes it easier for me to find certain files in folders with many files.

FileIcons

GitHub Code Folding

Any reasonable code editor gives you the ability to easily expand or collapse code blocks for readability. The GitHub Code Folding extension, by Noam Lustiger, allows you to do this inside the GitHub user interface.

CodeFolding-1

GitHub Repository Size

The GitHub Repository Size extension, by Harsh Vakharia, is another extension that is short, sweet, and useful.

The extension lists the size for an entire GitHub repository and also the size of each file.

Size

Hide Files on GitHub

The Hide Files on GitHub extension, by Sindre Sorhus, hides nonessential project files and folders from the GitHub user interface (like Yarn lock files, the .git folder, and so on). Of course, you can customize which files to ignore.

Isometric Contributions

The Isometric Contributions extension, by Jason Long, shows an isometric pixel art version of a user's contribution chart. It also includes more granular user data, like a user's busiest day, current streak, and longest streak.

Of course, you can easily switch between the isometric view and the default view. This extension does not have certain functionality like hovering over a day for details.

IsometricContributions

Notifier for GitHub

The Notifier for GitHub extension, by Sindre Sorhus, displays your unread GitHub notifications count. This way, you can keep track of any missed notifications even when you don't have GitHub open.

(The screenshot grabbed from the extension's repository.)

screenshot

Octotree

I cannot do without the Octotree extension. This extension offers an easy-to-navigate code tree, allowing for lightning-fast browsing of a repository's files.

Octotree

Refined GitHub

The Refined GitHub extension, by Sindre Sorhus, offers a slew of features that is missing from GitHub. If you look at the repository, you'll see that GitHub has integrated functionality that was first developed in this extension.

Some functionality includes the ability to mark issues and pull requests as unread, reaction avatars on comments, clickable references to issues and pull requests, and links to an issue's closing commit or pull request.

Render Whitespace on GitHub

Where do you stand on the tabs vs. spaces argument? You can only pick one. (In an effort to keep all my readers, I will abstain from this one.)

The Render Whitespace on GitHub extension, by Gleb Mazovetskiy, allows you to quickly find out the formatting of a repository's code.

Whitespace

Twitter for GitHub

When I discover a GitHub repository, I like to find out information about the author—generally this includes following the person on Twitter, which is often the best place to contact someone or and learn about them. If the author does not include their Twitter handle in his or her GitHub bio, it can be tedious and time-consuming to search on Twitter.

The Twitter for GitHub extension, by Nicolás Bevacqua, attempts to find a user's Twitter handle and display it on a GitHub profile.

GitHubTwitter


The beauty of a cross-platform framework like ASP.NET Core is your ability to choose tooling you prefer. With all its advantages, Visual Studio can sometimes be too powerful for what you need.

With ASP.NET Core, the days of being locked down to writing .NET in Visual Studio are over. For example, you can write your applications on editors like Visual Studio Code, whether you are on Mac, Windows, or a flavor of Linux.

Earlier this year, I spoke and wrote extensively about how to write an ASP.NET Core app with Visual Studio Code. As this support is evolving, you may notice experiences here and there that do not compare to using a full-fledged editor like Visual Studio—but if you are using Code for your Core apps you may find the trade-off worth it.

That gap is narrowing with the announcement that Visual Studio Code now has support for Razor, the .NET markup syntax engine that allows you to write dynamic views using .NET code and HTML markup.

Take advantage of Razor support in Code

Before you look at Razor support in Code, create an ASP.NET Core application in Visual Studio Code. We will just create an application based on the ASP.NET Core web application template. (For an in-depth tutorial on using ASP.NET Core with Code, you can review my blog post or an in-depth tutorial at the official Microsoft Docs site.)

As prerequisites, make sure you have Visual Studio Code, the C# extension, and the .NET Core SDK installed.

Create a quick .NET Core web app in Visual Studio Code

From Visual Studio Code, enter the following commands from the integrated terminal (if you don't see it, click Terminal > New Terminal):

dotnet new webapp -o TestRazorSupport
code --reuse-window TestRazorSupport

The first command uses the .NET Core CLI to create a new application based on the webapp template. The application now exists within a TestRazorSupport folder. The second command uses a Code command-line switch to open the application in your active Code window.

Now, you can open any view file (.cshtml) to experiment with Razor support.

Explore Razor support in Visual Studio Code

If you open a view—I will be looking at Pages/Contact.cshtml—you can see Razor support in action.

First, let's update the ContactModel with some additional properties. Here's what my Contact.cshtml.cs now looks like:

using System;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace TestRazorSupport.Pages
{
    public class ContactModel : PageModel
    {
        public string Message { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }

        public void OnGet()
        {
            Message = "Your contact page.";
            Name = "Dave Brock";
            Email = "dave@myemail.com";
        }
    }
}

In Contact.cshtml, let's access the Name property to check out the Razor support.

It works as you would expect—even inside HTML attributes—as we access the Email property:

And if we access .NET APIs (and steal from the announcement) it works beautifully!

Disclaimer: Support currently in preview

As discussed in the announcement, this is very much in preview and has limitations. Read the article for details on what these limitations are, how to provide feedback, and how to disable it if you come across issues.


(Some context: Blazor is an experimental .NET web framework using C# and HTML in the browser. See the preview documentation for more details on the project and how to get started.)

As developers, we often take advantage of the benefits of sharing common code in a specific project. That way, it can be shared and maintained in a centralized way - accessed easily whether it is your team's source control repository or, in the .NET world, a NuGet package.

This is no different with Blazor. When we use shared libraries, we can easily share components across projects. When we share components, all our target project needs to do is reference the shared project and add the component - no style imports necesssary!

In this article, we will demonstrate the power of Blazor shared libraries using a simple example with the default scaffolded Blazor application.

Prerequisites

Before getting started, make sure you have the following minimum prerequisites installed:

Create a Blazor application

Let's create a Blazor application.

  1. From Visual Studio 2017, click File > New > Project and select the Visual C# > .NET Core > ASP.NET Core Web Application.

  2. Give it a name, like MySharedLibDemo, and click OK.

    Blazor-NewProject-2

  3. Select the Blazor template and click OK. This will scaffold a default SPA application that is integrated with WebAssembly.

  4. After the scaffolding completes, click Debug > Start Without Debugging to run the application. Your site should resemble the following.

    InitialBlazorAppView-2

    Leave this running so we can save the application in Visual Studio and reload it.

    Next, we'll add a shared Blazor library. At this time, a Blazor shared library is not available in Visual Studio. We'll use the .NET Core command-line interface (CLI) to accomplish this.

  5. Right-click the solution and select Open Command Line. From your preferred command line utility, enter dotnet new to see all the .NET Core templates available to you. We will be adding the Blazor Library template to our project.

    core-templates-1

  6. From your prompt, enter dotnet new blazorlib -o MySharedBlazorLibrary. This will add the MySharedBlazorLibrary project in your directory.

  7. Right-click your solution and click Add > Existing Project. Browse to your library, select the MySharedBlazorLibrary.csproj file, and click Open. Your project structure will now resemble the following.

    Blazor-SolutionExplorer

  8. Finally, reference the shared project. From your main project, right-click Dependencies > Add Reference... Then, select your newly created project and click OK.

Update the ViewImports.cshtml file

For Blazor to use your shared project, add the following line to the _ViewImports.cshtml file that sits at the root of your main project.

@addTagHelper *, MySharedBlazorLibrary

This is a temporary solution. The Blazor team hopes to have this resolved. Until then, this is a required step.

Add shared component to your main project

Now, all you need to do is add the component to your project. If you remember, the shared project includes a Component1.cshtml file that includes a styled component. We will now add this to our main project.

From your Pages/Index.cshtml file, below the SurveyPrompt component, add the Component1 component. As you begin typing, you can use IntelliSense.

Autocomplete

Your Index.cshtml component should now look like this:

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<Component1 />

Notice you don't even need a @using statement in your view to reference your component!

View your changes

After you save your changes, reload the page to see your new component in action.

PageWithComponent-1

You have just referenced a component from a shared library with minimal effort. By merely importing the library, you were able to add a component and its styles quite easily.


If you want to clone a GitHub repository, the most common (and documented) way is to browse to it and click that green Clone or download button. In this case, I am cloning the .NET machine learning project:

CloneOrDownload

Typically, I would copy the Git repository path and clone it in a command line window, like so:

git clone https://github.com/dotnet/machinelearning.git

As it turns out, this is a waste of clicks. All you have to do is grab the URL from the address bar of your favorite browser and ignore the .git extension altogether.

Try this:
CloneWithoutExtension


I was writing some vanilla JavaScript this weekend - it has been quite awhile since I did so. As I've been writing mostly C# code lately, what always gets me with JavaScript isn't its pain points or subtle nuances. It's the different behavior from compiled languages I'm often used to, like C# or Java. No matter how often I work in JS, as long as I'm committed to being a polyglot, it'll trip me up to the point that it's just a little bit of an annoyance.

Take this seemingly simple JavaScript code. What will be output to the browser console?

var myString = 'I am outside the function';
function myFunction() {
    console.log(myString);
    var myString = 'I am inside the function';
};
myFunction();

Was your guess I'm outside the function? Or was it I'm inside the function? I hate to let you down, but in either case you would be incorrect.

In your favorite browser's developer tools, the console will log undefined. But why?

In JavaScript, functions create brand new scopes. If we condense the example a little:

function myFunction() {
    // new scope, the variable is inaccessible outside the function
    var myString = 'I am inside the function';
}
myFunction();
console.log(myString); // undefined!

Of course, if you've worked in JavaScript (or basically any programming language) you can't expect to declare a variable without an assignment and expect to get anything back but null or, in JavaScript's case, undefined when I do something like this:

var dave;
console.log(dave); // will log undefined

So, if we look at this again:

var myString = 'I am outside the function';
function myFunction() {
    console.log(myString);
    var myString = 'I am inside the function';
};
myFunction();

To take all we've learned, we need to be aware of how something called hoisting works. For our purposes just know this: variable declarations in JS are always hoisted to the top of the current scope -- variable assignments are not.

So here, the declaration is hoisted to the top of the scope - or, in our case, the myFunction() function. So before the console.log statement in the function, you can basically envision a var myString in the first line of the function. And, of course, knowing this now it is clear to see why the logging statement will come back as undefined.

Just remember this: always define your variables at the top of the current scope. Always.