Sp-dev-docs: Using a shared ts file between two or more SPFx projects

Created on 19 Jul 2017  路  4Comments  路  Source: SharePoint/sp-dev-docs

Category

  • [x] Question
  • [ ] Typo
  • [x] Bug
  • [x] Additional article idea

Expected or Desired Behavior

I would like to place a TS file outside of the project scope, in a different folder, and importing it from there in 2 or more SPFx projects.

example folder structure:
Root

  • SPFxProj1
  • SPFxProj2
  • SharedCode

    • Utilities.ts

Want to use Utilities.ts in both SPFx projects.

I don't mind it being bundled in the web part, but wouldn't want to have to go to the trouble of setting it up as an npm package.

Observed Behavior

When I do it, VSCode works fine, finds the TS file and shows the correct auto-complete for types, but gulp serve breaks and says module cannot be found.

Problems are:

  1. gulp serve fails on webpack cannot find module
  2. since none of the SPFx framework packages are installed globally, there are type mismatch when I need to reference core classes in Utilities.ts (like: IWebPartContext for example)

Steps to Reproduce

Create a root folder
Create 2 separate SPFx project under it
Create "SharedCode" folder under the root
Create a Utilities.ts file under SharedCode, with code similar to this:

import { IWebPartContext } from "../SPFxProj1/node_modules/@microsoft/sp-webpart-base";
export default class Utilities {
    public static GetUserName(ctx: IWebPartContext): string {
        return ctx && ctx.pageContext && ctx.pageContext.user && ctx.pageContext.user.displayName || 'Anonymous user';
    }
}

Use it inside SPFxProj1 and SPFxProj2
You will see SPFxProj2 complains about type mismatch.
Try to run gulp serve on SPFxProj1, you will see gulp serve issues a webpack error.

Most helpful comment

@andrewconnell have to admit you made me take a third look at it, and I figured with npm init to create the package in a relative folder, I can then define the dependency to a relative folder, while keeping all of them within the same source control the way I want it.

Now, this makes a lot more sense. I will start changing my code to do it this way.

Thanks for that, again nothing for the product team to see here.

(Only thing I don't like is having to "npm update" each project when I have a new version)

All 4 comments

IMHO, I'd rather not see the SPFx team do anything in this area as this isn't a SPFx thing... again IMHO. It's no different than creating a class library (*.dll) in a .NET project.

This is a common scenario in JavaScript libraries distributed with NPM... why not just include it in your own NPM module and publish that to the NPM JS registry? If it contains code you don't want others to have access to, make it a private module. The other option (which I prefer) is to install it straight from a private repo...

This approach is ideal IMHO because it's true code reuse and it's refactored away from both other projects, plus it is independently versioned.

For instance, here's a snippet from a package.json from a private project I'm working on that uses a private repo:

  "dependencies": {
    "amqplib": "0.4.2",
    "moment": "2.14.1",
    "request": "2.74.0",
    "voyager-shared": "github:andrewconnell/voyager-shared"
  },

The voyager-shared repo is in a private repo in my GitHub account. Authentication to GitHub is handled using SSH.

In case anyone is interested, I just figured what I was missing.
It turns out to be a type script compiling issue. I just needed a tsconfig.json in my SharedCode folder, and to compile it (using tsc command) to produce the JS file for it.

While I understand where you are coming from @andrewconnell, I do see value in this. See, not every utility function needs to become a package in my opinion, and if my source control is not in GitHub I don't see why I would need to place that specific shared code in GitHub. I assume not everyone out there are using GitHub as their source control, and would like all their code stored at one central location.

In any case, there is nothing for the team here to consider, since it is doable. I just still didn't figure out how to make that build as a part of the gulp task, but I am sure it is an easy change to the gulpfile.js

@andrewconnell have to admit you made me take a third look at it, and I figured with npm init to create the package in a relative folder, I can then define the dependency to a relative folder, while keeping all of them within the same source control the way I want it.

Now, this makes a lot more sense. I will start changing my code to do it this way.

Thanks for that, again nothing for the product team to see here.

(Only thing I don't like is having to "npm update" each project when I have a new version)

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues

Was this page helpful?
0 / 5 - 0 ratings

Related issues

acksoft picture acksoft  路  3Comments

byrongits picture byrongits  路  3Comments

waldekmastykarz picture waldekmastykarz  路  3Comments

bengtmoss picture bengtmoss  路  3Comments

zerovectorspace picture zerovectorspace  路  3Comments