The term ‘ducks’ refers to the folder and files that you have to create for managing redux state using the re-ducks pattern.

Every duck needs to have six to eight files in it, and in Visual Studio Code (VS Code), it’s painful to manually create them every single time you add a new duck to your project.

/* A typical duck structure from re-ducks */ /state

/ducks

/quack

- actions.js

- index.js

- operations.js

- reducers.js

- selectors.js // Optional, still generated

- test.js

- types.js

- utils.js // Not generated

Setup

You will need to have the following tools installed to create an extension for VS Code:

From the terminal, install Yeoman and the Visual Studio Code Extension generator.

npm install -g yo generator-code

We will use Yeoman to create a project template for developing the extension using Microsoft’s preferred structure and settings.

Open a terminal at your project folder and run yo code to start the generator for the extension. Select the, “New Extension (TypeScript),” option.

Answer all of the questions asked by the Yeoman code generator.

The Yeoman generator will produce a ‘duck-generator’ project with the following structure:

/duck-generator

/src

/test

- extension.test.ts

- index.ts

- extension.ts

- package.json

- tsconfig.json

- tslint.json

- CHANGELOG.MD

- README.MD

- vsc-extension-quickstart.md

These are the key files in the project template:

package.json — Describes the extension and where to find its entry point and activation trigger.

— Describes the extension and where to find its entry point and activation trigger. tsconfig.json — The config file for the TypeScript compiler.

— The config file for the TypeScript compiler. tslint.json — The TypeScript linting rules.

— The TypeScript linting rules. CHANGELOG.MD — The change logs for the extension. This will show in the ‘Changelog’ section in the extension gallery.

— The change logs for the extension. This will show in the ‘Changelog’ section in the extension gallery. README.MD — The description of your extension. This will show in the ‘Details’ section in the extension gallery.

— The description of your extension. This will show in the ‘Details’ section in the extension gallery. src/** — Stubbed code for the extension. We will delete and make changes to files in this directory.

Development dependencies

The default template includes the Mocha test framework, which is set up to behave more like integration tests than unit tests, per the documentation:

…This documentation focuses on VS Code integration tests. For unit testing, you can use any popular testing framework, like Mocha or Jasmine.

Instead of using Mocha or Jasmine, I am going to be using Jest since I am most familiar with it.

Install the tools to work with Jest in TypeScript via NPM:

npm install --save-dev jest ts-jest @types/jest

Packages:

jest — The unit testing framework.

— The unit testing framework. ts-jest — A preprocessor that will allow running jest tests written in TypeScript.

— A preprocessor that will allow running jest tests written in TypeScript. @types/jest — The TypeScript definitions for the jest testing framework. This package will provide IntelliSense when writing jest tests in TypeScript.

The Duck Generator

We’re going to create a class that will contain the logic for creating ducks.

Start by creating a file called duck-generator.ts in the src directory. Open the file and stub the functions. For simplicity, let’s make them all public functions.

Tests for this class can be found here.

When the extension executes, it will call the DuckGenerator.execute() function to start the flow of prompting for a name, validating the input, creating an absolute path to the local directory then finally creating the files for the duck.

Let’s implement these functions, starting with the simplest ones first.

The constructor will accept two parameters that we will pass in from the main extension file. This will allow us to write tests for the DuckGenerator without having to worry about mocking the import statements or modules from the vscode sdk module.

Note: Since we don’t want to import the entire vscode sdk, we will create a custom interface ( VSCodeWindow ) that will provide IntelliSense for the sdk’s Window namespace.

The toAbsolutePath function.

The validate function.

The prompt function.

The create function.

The execute function.

I decided to leave the unit tests code out of the article because I thought that it would make the article too code heavy. If you want to see the tests for this file, they can be found here.

Utility, Interface and Error

We will add a utility module with a function we can use to determine where the workspace folder is in the current context of a project. We put this code into its own module so that we can test it independently of the generator and extension entry point.

Create a folder called utils and add a file to it called workspace-util.ts . Export a function from it that will allow us to call from the extension entry point to get the workspace root.

Tests for this module is here.

The DuckGenerator implemented an IDisposable interface so that when the extension is destroyed, a dispose function will be called. Even though we are not going to use it, let’s add it so that if we did bring in any resources from the sdk or node that needed cleanup later, we can do it in the dispose function.

When a user tries to create a duck that already exists, we throw an error on type DuckExistError , which is a custom error that we need to create.

Tests for this error is here.

The Extension

The entry point for the extension is in the extension.ts file that was created with the Yeoman project template. Let’s edit it to call our DuckGenerator when the extension is activated.

We did not add any functionality to the entry point file. Its main purpose is to act as a driver of sorts for the code we have written and tested, along with code that has been provided by the vscode sdk, to make the extension work.

Wrapping up

That is it, the extension is ready to be tested, packaged and published to the Visual Studio Code Extension Gallery.

If you want to test the extension locally, just select the, “Extension Debug,” launch settings and press debug (play button) or F5 .

You can package the extension by install the vsce package from NPM.

npm install -g vsce // package locally, run from extension project root

vsce package

If you want to publish the extension, check out the publishing guide from Microsoft: https://code.visualstudio.com/docs/extensions/publish-extension.

The code for this article can be found on GitHub: https://github.com/vanister/duck-generator/tree/medium-article.

I published this extension to the gallery: https://marketplace.visualstudio.com/items?itemName=vanister.duckgenerator.

Enjoy making and publishing extensions!