Article
0 comment

Custom SPFx generator: Make Yarn your default package manager

The most straightforward example to make you familiar with how to create a custom SPFx Yeoman generator is to use Yarn instead of NPM as your default package manager. The approach to change the default package manager is simple, and many people already use it as there default package managing solution.

So, instead of adding the ‘–skip-install’ option whenever you start a new project just add this option to a generator.

The first step is, as always, to create a new NPM package.

Create base Yeoman generator setup

To get started first create a new folder on your hard drive somewhere. The naming in case of Yeoman generators is essential because the must first start with ‘generator-‘ followed by a custom string. In my case, I named the folder ‘generator-spfxyarn’.

mkdir generator-spfxyarn
cd generator-spfxyarn

Now the new NPM packages need to be initialised. One possibility is to create a new ‘package.json’ file through the command npm init. This command launches a small dialogue that will ask you some questions you need to answer.

Create package.json through npm init

Create package.json through npm init

After you completed the dialogue, the configuration gets written to the folder.

Another possibility is to create this file from a template file or write all by yourself. I prefer to use this my small ‘package.json’ template.

{
    "name": "generator-spfxyarn",
    "version": "0.1.0",
    "description": "",
    "author": "",
    "license": "ISC",
    "files": [
        "app"
    ],
    "keywords": [
        "yeoman-generator"
    ],
    "dependencies": {
    }
}

This ‘package.json’ file is all you need to get started with a new generator. Well, there a still some dependencies missing but instead of hardcode them in this file it is recommended to add them via NPM.


npm install --save yeoman-generator

The first dependency is ‘yeoman-generator’ npm package, which is the core module and the base of all Yeoman generators.

The second dependency is the SPFx generator or in other words ‘@microsoft/generator-sharepoint’.


npm install --save @microsoft/generator-sharepoint

Now we have at the minimum of NPM packages added to out generator, and we are ready to implement the logic of the generator.

Add additional npm packages for the generator

Add additional npm packages for the generator

Develop the Yeoman Generator logic

In the ‘package.json’ file generated previously there is also a property named “files”, and the stored array there contains an entry contains an entry named “app”. This entry indicates the root folder to store the logic and additional files if required for the custom generator. So if you have more than one generator, which is possible, you also should add these generators to the files.

In this case, we only need to create the folder “app” and inside the folder a new JavaScript file named ‘index.js’.

Base folder structure of Yeoman generator

The minimum of a generator code only consists only in a few lines of code.

// content of app/index.js
'use strict';
// base generator scaffolding
const Generator = require('yeoman-generator');

module.exports = class extends Generator {

    constructor(args, opts) {
        super(args, opts);
    }

}

This code extends the generator object, through ‘class extends Generator’, given by the ‘yeoman-generator’ module. ‘module.exports’ is required to make it available as an npm module.

Inside the class, there is also a constructor override that can be used to get arguments from the command line for example.

It still doesn’t do anything yet, that is part of the next step to make sure that this generator uses another generator. In this case our SharePoint Framework generator.

Besides the constructor, we need to have a function implemented that initialise the parent generator. In other words, we need to initialise the SPFx generator. The keyword here is composability or the method named composeWith and provided by the Yeoman generator API.

// Initialize the generator
initializing() {

    this.composeWith(
        require.resolve(`@microsoft/generator-sharepoint/lib/generators/app`), {
            'skip-install': true
        }
    );

}

So, ‘this.composeWith’ takes two parameters. The first parameter is the path to the generator. The ‘require.resolve’ make sure that the path gets searched in the node modules folder. That’s why the generator ‘@microsoft/generator-sharepoint’ has to be referenced in the dependencies of this custom generator.

The second parameter is optional but is used to pass command line parameter to the generator.

It is the same as you would create a new project from the command line following.


yo @microsoft/sharepoint --skip-install

If you like to use only React you can pass in your preferred framework too. Just add the property ‘framework’ and set the value to ‘none’, ‘react’ or ‘knockout’.

So when this custom generator now gets launched all it does is to start the SPFx Yeoman generator, pass in ‘skip-install’ option and ask you the same questions you will get when you start the generator from the command line manually.

The puzzle piece left is now to handle the installation through yarn instead of NPM.

Make the installation trough Yarn or NPM

In Yeoman generators, there is a specific call order of functions defined.

  1. initialisation() – Your initialisation methods (checking current project state, getting configs, etc.)
  2. prompting() – prompts for additional user import such as you’ve been asked when you create a new SPFx project
  3. configuring() – allows you to save other configuration files, for example, a .editorconfig to the project target folder
  4. writing() – writes all the required source files you need in your project such as add additional configurations to your project. For example reference external frameworks.
  5. install() – Install all NPM dependencies in the project folder, npm install, yarn install, etc.
  6. end() – Say goodbye or finish some things up.

The only function that we need to use is just the ‘install’-method.

Before we can implement this, we need to add one additional NPM package. The name of this package is ‘command-exists’. We use this to check if Yarn is available your computer.

npm install --save command-exists

To use this tool we first need to import a reference at the beginning of the ‘index.js’ file right below the already existing reference to the ‘yeoman-generator’. It works similarly as in C# references.

// base generator scaffolding
const Generator = require('yeoman-generator');

// import command-exists to check if yarn is installed
const commandExists = require('command-exists').sync;

Now everything is set to implement the installation method in the class.

install(){
     // check if Yarn is installed 
    const hasYarn = commandExists('yarn');

    // install all dependencies
    this.installDependencies({
        npm: !hasYarn,
        bower: false,
        yarn: hasYarn
    });
}

So, the ‘command-exists’ check if the ‘yarn’ command is available on your system. It even doesn’t matter if you work on MacOS, Windows or Linux. The check performed by this object is platform independent.

The ‘this.installDependencies’ will install all NPM packages required for SPFx. The JSON object pass to the function supports overall three different package manager.

In the case you have Yarn installed the command exists return ‘true’ and this package manager gets used. If it returns ‘false’ then NPM gets used to like you would expect when you start the project wizard directly.

Testing the custom Yeoman generator

The final step is to test this generator.


npm link

Execute this command on the root folder and your generator will be automatically linked to the global package store or NPM. After this command has successfully finished its work, you are ready to create a new project instance.

Just create a folder outside of your generator and start yo spfxyarn or however you named your generator. Like with the Microsoft provided solution first the files get copied to the project folder and after that Yarn will install the rest of the required components.

After you finished testing npm unlink removes your generator from the global package cache.

Final thoughts

This article just scratched the top of the iceberg, and there are more specifics you should be aware. I hope it helped you the get the first impression that writing Yeoman generator based on SPFx is not a rocket science.

To use it inside your organisation the essential use of this generator is to download the source from a server inside your organisation and use ‘npm link’ to make it usable on your client. I know this is not a convenient way use and install generators.

Another method to install your custom generator is to ‘npm install’ from a git source stored in your organisation. For this, please check out the official documentation of the ‘npm install‘ command.

There are better options I’ll cover in an upcoming blog post.

Get the source code from Github

Like to know more details on how to get started writing Yeoman.

Leave a Reply

Required fields are marked *.


This site uses Akismet to reduce spam. Learn how your comment data is processed.