How to add a second Web Part to a SharePoint Framework project?


When generating a new SharePoint Framework project using the SharePoint Yeoman generator you can automatically add a new Web Part. But what if you wanted to add another one?

yo SharePoint!

SharePoint Framework ships with a Yeoman generator that takes care of scaffolding SharePoint Framework project. By running the generator and answering a few questions, the generator creates a new project for you with one Web Part built using React, Knockout or no framework at all. Using the generator is a great and easy way to create a new project until you will want to add a new Web Part.

SharePoint Framework Yeoman generator scaffolding a SharePoint Framework project

Some Yeoman generators are meant only for the scaffolding of the initial project structure. Other generators contain subgenerators that you can call on existing projects. These subgenerators can perform a number of tasks: from reconfiguring the projects to adding new artifacts. While it seems like the SharePoint Yeoman generator is only meant to create new SharePoint Framework projects, there is more to it than meets the eye.

Adding a new Web Part to an existing SharePoint Framework project

In order to add a new Web Part to your existing SharePoint Framework project all you need to do, is call the SharePoint Yeoman generator on your existing SharePoint Framework project.

Executing the SharePoint Yeoman generator on an existing SharePoint Framework project

The generator will detect that it’s running on an existing project and instead of scaffolding the whole project it will skip directly to adding a new Web Part. After answering the standard questions about the Web Part’s title, description and framework, the SharePoint Framework Yeoman generator will add the new Web Part to the project and will register it with the project’s configuration so that the Web Part is built into a new bundle.

One more thing

In the developer preview release of the SharePoint Framework Yeoman generator there is a bug causing the Web Part being added not entirely correctly. If you would try building the project after adding another Web Part you would see a number of errors in the bundle task. Here is what you need to fix after adding the second Web Part using the SharePoint Framework Yeoman generator:

Localization configuration

In the config/config.json file the generator overwrites the path of the localizedResources/mystrings property. To fix it, copy the property and adjust the path so that there is one property for each Web Part pointing to its localization files, eg.

{
  "entries": [
    {
      "entry": "./lib/webparts/helloWorld/HelloWorldWebPart.js",
      "manifest": "./src/webparts/helloWorld/HelloWorldWebPart.manifest.json",
      "outputPath": "./dist/hello-world.bundle.js"
    },
    {
      "entry": "./lib/webparts/helloWorld2/HelloWorld2WebPart.js",
      "manifest": "./src/webparts/helloWorld2/HelloWorld2WebPart.manifest.json",
      "outputPath": "./dist/hello-world-2.bundle.js"
    }
  ],
  "externals": {
    "@microsoft/sp-client-base": "node_modules/@microsoft/sp-client-base/dist/sp-client-base.js",
    "@microsoft/sp-client-preview": "node_modules/@microsoft/sp-client-preview/dist/sp-client-preview.js",
    "@microsoft/sp-lodash-subset": "node_modules/@microsoft/sp-lodash-subset/dist/sp-lodash-subset.js",
    "office-ui-fabric-react": "node_modules/office-ui-fabric-react/dist/office-ui-fabric-react.js",
    "react": "node_modules/react/dist/react.min.js",
    "react-dom": "node_modules/react-dom/dist/react-dom.min.js",
    "react-dom/server": "node_modules/react-dom/dist/react-dom-server.min.js"
  },
  "localizedResources": {
    "mystrings": "webparts/helloWorld/loc/{locale}.js",
    "mystrings2": "webparts/helloWorld2/loc/{locale}.js"
  }
}

Localization files

By default, the newly added localization strings are defined in the mystrings module which collides with the one created initially by the SharePoint Framework Yeoman generator. To fix the issue, in the newly added mystrings.d.ts file (eg. ./src/webparts/helloWorld2/loc/mystrings.d.ts) change the name of the exported module to mystrings2 and the name of the interface to IStrings2:

declare interface IStrings2 {
  PropertyPaneDescription: string;
  BasicGroupName: string;
  DescriptionFieldLabel: string;
}

declare module 'mystrings2' {
  const strings: IStrings2;
  export = strings;
}

For consistency, change the name of the mystrings.d.ts file to mystrings2.d.ts.

Web Part code

The newly added Web Part refers to the old localization files. To fix it, you need to update the name of the mystrings module to mystrings2 in the Web Part’s code file:

import {
  BaseClientSideWebPart,
  IPropertyPaneSettings,
  IWebPartContext,
  PropertyPaneTextField
} from '@microsoft/sp-client-preview';

import styles from './HelloWorld2.module.scss';
import * as strings from 'mystrings2';
import { IHelloWorld2WebPartProps } from './IHelloWorld2WebPartProps';

// omitted for brevity

Next time you build your project, you will see two bundles in the output folder and the Web Part Toolbox in the Workbench will show two Web Parts that you can add to the page.

Screenshot two custom Web Parts displayed in the Workbench's Toolbox

The newly added Web Part, just as expected, will use its own set of resource strings:

Newly added Web Part using its own set of resource strings

Summary

When generating SharePoint Framework projects using the SharePoint Framework Yeoman generator, it automatically adds one Web Part to the project. You can easily add a new Web Part by re-running the generator on the existing project. Despite a small bug in the developer preview, using the generator is still easier than adding a second Web Part manually.

Others found also helpful: