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.