Category Archives: Yarn

Check for vulnerabilities using audit

This is a reminder post as I occasionally forget this command in yarn and npm.

Third party packages within our applications occasionally need updating due to security issues/vulnerabilities. Github kindly supplies information via dependabot, but if you’re not using github or simply want to check the latest state of the packages used in your code, you can use

yarn audit

See yarn audit for more information.

For NPM it’s the same CLI option, i.e.

npm audit

See npm audit for more information.

Building and testing TypeScript code using Github actions

In previous posts we’ve used Github actions to build .NET core code, now let’s create a workflow to build/transpile a TypeScript application.

  • Create a file (mine’s named build.yml) in your Github repo. in the folder .github/workflows
  • As per other examples of such a .yml action file we need to give the build a name and set up the triggers, so let’s do that, here’s the code
    name: Build
    
    on:
      push:
        branches: [ master ]
      pull_request:
        branches: [ master ]
    
    jobs:
      build:
    
        runs-on: ubuntu-latest
    

    In the above we’ve simply named the action Build which is triggered by pushes to master (and pull requests). We then set the action up to run on an ubuntu VM

  • Next we’ll add the following code to create a strategy (basically think, job configurations and application wide variables)
    strategy:
      matrix:
        node-version: [12.x]
    

    In this case we’re creating a variable named node-version with the version of node we want to use.

  • Now we’ll create the steps for the build
    steps:
      - uses: actions/checkout@v2
      - name: Node.js
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm install -g yarn    
      - name: yarn install, build and test
        run: | 
          yarn 
          yarn build
          yarn test
    

    Firstly we declare the checkout action to be used, then we used the setup-node action to (as the name suggests) setup node with the version we defined. In this example we then run npm to install yarn. Obviously we could have simply used npm instead (and you can replace the yarn commands with npm if you wish).

    Finally we have a step to install, build and test our code running the relevant yarn commands to carry out these tasks.

The above expects the package.json of your project to have scripts named test and build. For example

"scripts": {
  "test": "jest",
  "build": "tsc"
}

How to yarn link when the package is not published?

In the previous post we looked at using yarn link to work on development of a package whilst using it within our application (or other package).

There’s a problem. This only works if you’ve previously published the package to an npm compatible repository because when you run yarn in your application, it’ll see the dependency of your package and try to get it from the remote repository.

Note: this in not an issue if the package was published it’s only an issue for unpublished packages.

What we can do is change the dependency from using a version number to essentially use a local path. For example, let’s assume we have the following in our packages.json

"dependencies": {
   "@namespace/package-name": "1.0.0"
}

As stated, running yarn will result in and error no such package available. Changing this line to

"dependencies": {
   "@namespace/package-name": "link:../dev/package-name"
}

In other words, link: followed by the path to our package under development, then all will work, running yarn will no longer fail with the no such package available error.

You also needn’t run the link commands on the package or application to create a symbolic link if you use this syntax, just remember to change it back to the version number once the package is published.

yarn link

Yarn’s link functionality is really useful when developing a package and wanting to use it in your application whilst the package is in development.

Let’s assume you’ve created a package, for the sake of having an example, let’s assume it’s a cool new radio button control. You’ve created it and pushed to npm and all’s great but then you want to make some changes.

You don’t want to make those changes and push them to npm so that you can test them, yes you could take the code from the package etc. or use Yalc.

Or we can use yarn link.

In the package you’re editing, simply run

yarn link

this will result in the following command being available to run in the application using the package

yarn link "@namespace/package-name"

Note: obviously remove the namespace if non is used and replace package-name with the name of the package to link.

After you execute the above command and if you’re using Visual Code’s look at the explorer window, in the node_modules of the application using the package you’ll find the @namespace/package-name with a little symbolic link icon.

If you wish to unlink then, from your application use

yarn unlink "@namespace/package-name"

and from the package itself

yarn ulink

Yarn and what not to commit to your source repos

When working with yarn you’ll find your source code folder includes the following files and folder (amongst others)

  • packages.json
  • yarn.lock
  • node_modules

If using TypeScript you may also have tsconfig.json.

The node_modules folder is basically everything downloaded via yarn that are either included within the packages.json or dependencies of those packages. So unless you’re fearful of versions of mdoules/dependencies becoming unavailable, this folder can be left out of source control, plus it can get big quickly.

The packages.json file should be committed as it obviously includes all the information regarding the packages used and their versions, but is also used for scripts etc.

Interestingly, I thought that yarn.lock should also be excluded as it’s generated by yarn, but according to Lockfiles should be committed on all projects.

If you have tsconfig.json, this file is a TypeScript configuration file. Hence this should be committed to ensure other team members are using the same configuration.

What about .vscode

If you’re using VSCode as your editor/development tool then you’ll notice that a .vscode folder is created in some cases with settings.json etc. within it.

Obviously whether you commit .vscode (or individual files within it) depends on whether you’re also aiming to commit shared settings etc. To my mind this would be a good thing as I use multiple machines for development and it’s an easy way for me to share settings between machines. This said if you’re a larger team it also might be useful to ensure everyone uses the same settings.

Starting out with Yarn

Yarn is a node package manager that can be used in place of npm. Beyond the basic package management functionality, such as adding and removing dependencies it can also execute scripts to create applications, such as React apps. and build them (i.e. get them ready for deployment) as well as run them.

Creating package.json

To get started we would run the following command within the project’s folder to generate a package.json file (or create one yourself using your preferred text editor).

yarn init

You’ll be presented with a set of questions which will then result in the contents of the package.json file. These include your project name, version, description, git repository etc. If you don’t have any response to the questions just press enter, we can always fill in missing data later.

Here’s an example package.json file

{
  "name": "MyProject",
  "version": "1.0.0",
  "description": "MyProject Description",
  "main": "index.js",
  "repository": {
     "url": "https://myproject-repos",
     "type": "git"
  },
  "author": "PutridParrot <emailaddress>",
  "license": "MIT"
}

Adding dependencies

I said at the start of this post that yarn is a package manager, so obviously we’ll want to add some package dependencies. Again, we can add our information to the package.json directly using our preferred text editor or use the yarn application from the command line to do this. Ofcourse the yarn command does a little more, it will check the yarn registry (by default this is https://registry.yarnpkg.com/)

To add a package dependency we use

yarn add [package]

So for example, we can add React using

yarn add react

This results in the addition for the following to the package.json

  "dependencies": {
    "react": "^16.8.6"
  }

Check out Packages to allow us to search for packages.

We can remove a package using

yarn remove react

Creating an application

We can also create an application. For example to create a React application (i.e. grabs the dependencies, generates the code etc.) we can use

yarn create react-app my-app
yarn create react-app my-app --typescript

Running scripts

We can also add scripts to the package.json, like this

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }

Now we can execute scripts using

yarn start

There’s much more yarn can do, but this post covers the most often used commands (or at least the one’s I’ve used most so far).

Creating a React application by hand

By default it’s probably better and certainly simpler to create a React application using yarn create but it’s always good to know how to create such an application from scratch yourself.

To start with, create a folder for our application and within it create a folder named src, within this create an empty file named index.tsx. Then add the following to this file

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

We don’t actually have React dependencies available to our application at this point so run the following, these will add React as well as TypeScript and TypeScript definitions of React (obviously if you don’t want to work in TypeScript, remove the –typescript switches and the last three yarn commands).

yarn add react --typescript
yarn add react-dom --typescript
yarn add react-scripts
yarn add typescript
yarn add @types/react
yarn add @types/react-dom

yarn will create the package.json file and download the required dependencies. They purpose of the dependencies are probably pretty obvious – the first includes React, the second React-dom and the third gives us the scripts we’re used to when running the code generated React applications, such as supplying the script for yarn start.

Within the package.json add the following, which will add the scripts that we’re used to having available

"scripts": {
   "start": "react-scripts start",
   "build": "react-scripts build",
   "test": "react-scripts test",
   "eject": "react-scripts eject"
}

We’re going to need to also add a folder named public which we’ll place an index.html file in which will act as our default page. Here’s a minimal version copied from a React generated application

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#000000" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>Game App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

At this point we should be able to execute

yarn start

and now we should see a React application running in the browser.

If you want to add some CSS to the application, we can simply create index.css in the src folder, create your styles then to use it in index.tsx add the following at the top of the file

import './index.css';

If you’re using VSCode, as I am, you may wish to click on the status bar where it display a version of TypeScript, when index.tsx is open, and set to the most upto date version listed.

Deploying your React application to IIS

We’re going to simply go through the steps for creating a React application (it’ll be the default sample application) through to deployment to IIS.

Create the React application using yarn

First off let’s create a folder in your development folder. Next, via your preferred command prompt application (and ofcourse assuming you have yarn installed etc.). Execute the following from your command prompt within your newly created folder

yarn create react-app my-app --typescript

this will create a bare bones sample application and grab all the dependencies required for it to run.

Does it run?

If you want to verify everything working, just change directory to the application we created (we named it my-app in the previous yarn command) and execute the following command

yarn start

A node server will run and your preferred browser will display the React application (assuming everything worked).

Building our application

At this point our application will happily run via yarn, but for deployment, we need to build it, using

yarn build

This will create a build folder off our our my-app folder.

Creating an IIS website to our React application

We’re going to now simply create a website within IIS which points the the same folder we just created (obviously if you prefer you can deploy the code to the inetpub folder).

In the Internet Information Services (IIS) Manager control panel (this information is specific to IIS 7.0, things may differ in newer versions but the concepts will be the same).

  • Select the Sites connections, right mouse click on it
  • Select Add Web Site
  • Supply a site name, mine’s sample As can be seen the name need not be related to our application name
  • Set the Physical path to build folder created in the previous build step, so for example this will be {path}/my-app/build
  • Port’s 80 and 8080 are usually already set-up and being used by the default web site, so change the port to 5000 and press OK to complete the addition of the website.

At this point if you try to view the new website using http://localhost:5000 you’ll probably get an error, probably stating access is denied. As this example has our source outside of the inetpub folder, we will need to change IIS permissions.

From the Internet Information Services (IIS) Manager control panel

  • Right mouse click on the sample website
  • Select Edit Permissions
  • Select the Security tab
  • Click the Edit button
  • Now click the Add… button
  • If you’re on a domain controller you may need to change Locations… to your machine name, then within the Enter the object names to select, type in IIS_IUSRS and press Check Names, if all went well this will underline the text and no errors will be displayed, now press OK
  • Keep pressing OK on subsequent dialogs until you’re back to the IIS control panel

If you try refreshing the webpage, it’ll probably display Access Denied. We need to allow anonymous access to the site in this case.

From the Internet Information Services (IIS) Manager control panel

  • Select Application Pools
  • Double click on the sample application
  • Change .NET Framework version to No Managed Code

From the Internet Information Services (IIS) Manager control panel

  • Select the sample web site and from the right hand pane of IIS double click on Authentication
  • Right mouse click on Anonymous Authentication and select Application pool identity then press OK

Refreshing the browser should now display the React logo and sample application should be running.

React and serve

During development of our React application, we’ll be using something like

yarn start

When we’re ready to deploy our application, we’ll use

yarn build

Which, in the case of React Typescript, will transpile to JavaScript and package files ready for deployment.

We can also serve the files within the build folder using the serve application.

Installing serve

To install serve, execute

yarn global add serve

This will add server to the global location. Normally (without the global command) packages etc. are installed local to the folder you’re working in. In the case of global packages, these will be installed in C:\Users\{username}\AppData\Roaming\npm\bin on Windows.

To check the location on your installation run

yarn global bin

Running serve on our build

Once serve is installed we can run it using

serve -s build

Note: Obviously if the global location is not in your path you’ll need to prefix the command with the previously found location