Serenity 8.1.5 Release Notes (2023-12-14)

New Method of Restoring Node Types from Package/Project References

Serenity feature packages such as Serenity.Extensions and Serenity.Pro.DataAuditLog are primarily shipped as NuGet packages. These packages contain scripts and TypeScript types that may need referencing from your projects.

Since these feature packages lack corresponding NPM packages, referencing them via package.json is typically not feasible. While we could offer NPM package counterparts, maintaining synchronization with NuGet package versions in your project would pose a challenge.

Another issue arises when utilizing feature packages or your own features as project references. In such cases, you would need to publish to NPM for every change or employ file: style references in package.json to their project folders.

Serenity has previously addressed these issues automatically by scanning your project and NuGet package references, creating necessary mock types under your node_modules/ folder by copying them from the dist/ folder of the relevant packages or projects. This results in files such as:

  • node_modules/@serenity-is/serenity.extensions/dist/index.d.ts
  • node_modules/@serenity-is/serenity.pro.dataauditlog/dist/index.d.ts

This feature might go unnoticed by Serenity users, as the node_modules folder is not visible in Visual Studio.

When the npm install command is executed, the NPM command clears the node_modules folder and reinstalls dependencies referenced in package.json. However, during this process, our mock types installed via the dotnet build process are lost.

To address this issue, we introduced a special script in package.json that runs the RestoreTypings target using dotnet:

//...
"scripts": {
    "prepare": "dotnet build -target:RestoreTypings"

This ensures that after the npm install process completes, the custom target RestoreTypings in the Serenity.Web project runs and restores mock types.

However, some issues could still occur. For instance, source generators in Serenity.Pro.Coder may run in the interval between npm install and RestoreTypings, potentially breaking the generated code if the index.d.ts files of mock types are momentarily absent.

To enhance the user experience, we have devised a better solution. Instead of creating mock package files directly under node_modules/@serenity-is/serenity.extensions, etc., Serenity will now create similar directories under node_modules/.dotnet/:

  • node_modules/.dotnet/serenity.extensions/package.json
  • node_modules/.dotnet/serenity.extensions/dist/index.d.ts
  • node_modules/.dotnet/serenity.pro.dataauditlog/package.json
  • node_modules/.dotnet/serenity.pro.dataauditlog/dist/index.d.ts

Notably, placing them under a folder starting with a dot (.) is advantageous, as NPM considers such folders as system/hidden, avoiding interference during installs.

These folders are named based on project/package names, with auto-generated package.json files containing JSON like the example below:

{
  "name": "@serenity-is/extensions",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js"
    }
  },
  "main": "dist/index.js",
  "import": "dist/index.js",
  "types": "dist/index.d.ts"
}

Moreover, these packages are automatically placed under the dependencies section of your project's package.json file:

{
  "name": "startsharp.web",
  "dependencies": {
    //...
    "@serenity-is/extensions": "./node_modules/.dotnet/serenity.extensions",
    "@serenity-is/pro.dataauditlog": "./node_modules/.dotnet/serenity.pro.dataauditlog",

Serenity updates your package.json file, adding these dependencies automatically. If a dependency has a manually specified version or a file: reference not starting with ./node_modules/.dotnet, Serenity avoids touching them to respect your preferences.

This approach ensures that every time your project builds, these dependencies are checked against your project/package references and updated if necessary. Defining package dependencies in package.json also allows TypeScript to analyze them, providing better import X from... suggestions during editing when a type is not in your import statements.

Upon the initial Git clone or manual deletion of the node_modules folder for any reason, the .dotnet folder might be lost. Therefore, include the following script in your package.json:

"scripts": {
    "preinstall": "dotnet build -target:RestoreNodeTypes"
}

Remove the prepare script and replace it with the preinstall script above.

Additionally, we recommend removing existing NPM version-based @serenity-is/corelib and @serenity-is/sleekgrid dependencies in package.json. Let Serenity automatically create those dependencies from your package reference versions. This way, you won't have to manually update their versions in package.json after updating NuGet packages like Serenity.Corelib and Serenity.SleekGrid.

It is also advisable to modify the path mapping for @serenity-is/* modules in your tsconfig.json file, as shown below:

//...
"paths": {
      "@/*": [ "./Modules/*" ],
      "@serenity-is/*": [ "./node_modules/@serenity-is/*/dist/index", "./node_modules/.dotnet/serenity.*/dist/index" ]
//...
}

This ensures that even if the regular package folders under node_modules/@serenity-is/ are momentarily removed during npm install, TypeScript and source generators can still locate the types under node_modules/.dotnet/ folders.

[BREAKING CHANGE] Serenity.Scripts is Obsolete

The Serenity.Scripts package is obsolete and should be replaced with Serenity.Corelib in your project file. This corresponds to the @serenity-is/corelib NPM package.

Update the ~/Serenity.Scripts/Serenity.Corelib.js line in your appsettings.bundles.json to ~/Serenity.Corelib/index.global.js.

Some Legacy Scripts are Removed from Serenity.Assets

We have removed jQuery.blockUI.js and toastr.js from the Serenity.Assets package, as they are no longer in use. Please remove them from appsettings.bundles.json if you still have them listed.