loading...

Cleaner Imports in SPFx Projects

droopytersen profile image Andrew Petersen ・2 min read

SharePoint Framework (SPFx) projects usually consist of multiple web parts, and a variety of shared components, services and utils. This leads to some gnarly imports.

Welcome to Dot City...

import ThemeColorPicker from "../../../ui-toolkit/components/ThemeColorPicker";
import { cachify } from "../../../utils/cache"

I find it very frustrating and disruptive to count folders every time I need a new import! Wouldn't it it be nice if you could just reference files relative to your /src folder?

With 5 minutes of setup, you can get clean imports like this

import ThemeColorPicker from "ui-toolkit/components/ColorPicker/ThemeColorPicker";
import { cachify } from "utils/cache"

SPFx projects are compiled in 2 steps.

  1. TypeScript turns the /src/*.ts files into /lib/*.js
  2. Webpack bundles /lib/*.ts into /dist/yourproject-bundle.js

With minor config changes to each tool, we can achieve the /src relative imports we desire.


TypeScript Setup

First, update the tsconfig.json file at the root of your SharePoint Framework project. Under compilerOptions, set "baseUrl":"src".

{
  ...
  "compilerOptions": {
    "baseUrl": "src",
    ...
   }
}

This is a quick change and immediately we can update our imports and see VS Code help us out with path completion.

VS Code Autocompletion

Immediately after setting the baseUrl, sometimes VS Code will complain about the src relative imports. Restarting VS Code usually does the trick.

Webpack Setup (Gulp)

Because the imports don't start with a ./ anymore, Webpack will think they are node_modules. We need to update the Webpack config to setup some resolve aliases.

SPFx exposes a way to update the webpack.config inside of gulpfile.js (at the root of your project).

Paste this into your gulpfile.js somewhere before build.initialize(gulp)

build.configureWebpack.mergeConfig({
  additionalConfiguration: (generatedConfiguration) => {
    generatedConfiguration.resolve.alias = {
      // TODO: Setup your aliases here!!
      // -- START OF MY ALIASES (remove them if you copy paste this) --
      "ui-toolkit": path.resolve(__dirname, "./lib/ui-toolkit/"),
      "utils": path.resolve(__dirname, "./lib/utils/"),
      // -- END OF MY ALIASES --
    };
    return generatedConfiguration;
  },
});

In the example above, I created two aliases, ui-toolkit and utils. Both are folders directly under /src.

Gotchas

  • You have to create a separate alias for each folder under src that you want to directly reference.
  • You need to reference them from /lib, not /src.

That's it. No more Dot City!

BONUS: VS Code's "auto import" feature seems to work better with this setup too.

import Filmstrip from "ui-toolkit/components/Filmstrip";
import useAsyncData from "ui-toolkit/hooks/useAsyncData"
import { getTenant } from "utils/spUtils";

Discussion

pic
Editor guide