spfx-fast-serve 2.0: new architecture, better extensibility, support of the latest SPFx

In the last few weeks, I was working on spfx-fast-serve v2.0 release. What is spfx-fast-serve?

A command line utility, which modifies your SharePoint Framework solution, so that it runs continuous serve command as fast as possible.

New architecture

At the very beginning, this tool was more like an experiment to see what is possible and also to see the potential limitations. During last year I fixed a bunch of bugs, added support for library components. However, the code was not as good as it should be. It was just a javascript file with all the logic. I see that the usage of spfx-fast-serve is growing, thus decided that it's a good chance to make it better. 

In a new version, everything is done using TypeScript with a lot better architecture. Different commands are responsible for different solution modifications - package.json update, gulpfile update, write webpack.js to disk, etc.  It will be a lot easier to maintain and to upgrade between different SPFx versions. It also easier for potential contributors to make changes.

Better extensibility

A common request for spfx-fast-serve was "how to prevent it to open a browser" or "how to change webpack configuration so that it..." etc. Some solutions also extend default SPFx webpack configuration, so they had to modify webpack.js accordingly. This is inconvenient, because next time you run $ spfx-fast-serve for an update, your webpack.js will be overwritten. 

spfx-fast-serve 2.0 introduced a new extensibility model. Now it adds a file called webpack.extend.js (by the way, all files are currently under a separate folder called fast-serve). It's supposed that you put all of your solution-related webpack modifications into this file.

Below is the file content: 

/*
* User webpack settings file. You can add your own settings here.
* Changes from this file will be merged into the base webpack configuration file.
* This file will not be overwritten by the subsequent spfx-fast-serve calls.
*/

// you can add your project related webpack configuration here, it will be merged using webpack-merge module
// i.e. plugins: [new webpack.Plugin()]
const webpackConfig = {

}

// for even more fin-grained control, you can apply custom webpack settings using below function
const transformConfig = function (initialWebpackConfig) {
  // transform the initial webpack config here, i.e.
  // initialWebpackConfig.plugins.push(new webpack.Plugin()); etc.

  return initialWebpackConfig;
}

module.exports = {
  webpackConfig,
  transformConfig
}

You should use webpackConfig variable to add solution-related webpack settings. For example, if you use pretty imports, you should add the below code:

const webpackConfig = {
  resolve: {
    alias: {
      "@src": path.resolve(__dirname, "..", "src")
    }
  }
}

Later on, the above webpackConfig will be merged with the base config using the webpack-merge module. 

If it's not enough and you cannot use "merge" mechanism, then you can use transformConfig function. It works the same as SPFx's "mergeConfig.additionalConfiguration" - it accepts the base config as a parameter, then in a function body you can do whatever you need and return back the updated config. 

Below is the line from webpack.js, which merges all changes and produces the resulting webpack configuration:

module.exports = webpackMerge(extend.transformConfig(createConfig()), extend.webpackConfig);

Now, when you run spfx-fast-serve for the next time, webpack.js file will be overwritten with a newer version, but your user webpack.extend.js file will remain untouched. 

Configuration file

spfx-fast-serve also writes config.json file to a disk:

{
  "$schema": "https://raw.githubusercontent.com/s-KaiNet/spfx-fast-serve/master/schema/config.1.0.schema.json",
  "cli": {
    "isLibraryComponent": false,
    "usePnpm": false,
    "useRestProxy": false
  },
  "serve": {
    "open": true,
    "openUrl": "<custom open url>",
    "fullScreenErrors": true,
    "loggingLevel": 'minimal' | 'normal' | 'detailed'
  }
}

The cli contains parameters you used last time when running spfx-fast-serve. It means that on the subsequent runs you don't have to supply the same set of parameters. If you use another parameter in a command line, your config.json will be overwritten. This file is important because webpack.js relies on configuration values from this file. 

The serve is supposed to control different webpack behavior. Currently, it supports

  • open - whether to open a browser when running serve or not.
  • openUrl - which URL to open if open is true. If empty, a local workbench will be opened.
  • fullScreenErrors - enables full-screen error information in a browser in case if your code has problems. Corresponds to devServer.overlay property.
  • loggingLevel - can be 'minimal' | 'normal' | 'detailed'. In minimal mode outputs only new build event, in detailed prints chunks information and some other technical things. 

SPFx 1.12+ support

The initial release of spfx-fast-serve supported SPFx starting from 1.4.1. Since then I haven't changed a lot to support all versions up to SPFx 1.11. However in SPFx 1.12, the build pipeline was changed, certificate handling was changed, thus I had to make changes to the webpack.js to make it work with the latest SPFx. Hopefully, such big releases don't happen frequently. As said from 1.4.1 to 1.11 there was nothing difficult except TypeScript versions and a few modifications. 

Migration guide

Basically, you just need to install the latest version, run it, then transfer all modifications you did (if any) from the original webpack.js to the fast-serve/webapck.extend.js:

  1. Run $ npm install spfx-fast-serve -g - this will install the latest spfx-fast-serve
  2. Run $ spfx-fast-serve in the project folder (don't forget other CLI options if you initially used them)
  3. Delete webpack.js file. If you have any custom modifications inside webpack.js, you should manually move them to a new fast-serve/webpack.extend.js file (read "Better extensibility" section above about webpack.extend.js).
  4. Run $ npm i
  5. Run $ npm run serve

Now you're ready to spfx-fast-serve 2!

Title image credits - Business vector created by freepik - www.freepik.com