I’ve gotten a little behind on my blogging over the month of August, but hope to stay active and consistent during September, time permitting.
Before getting into what the changes from versions 1.1.1 to 1.1.3 of the yo generator for SPFx projects gave us, it is good to review what 1.1.1 gave us. For this I refer mostly to Andrew Connell’s post of June 21st. There were 3 key points to that release that I think are pertinent to this discussion. First is that it was there that we got the first developer release of the Extensions. If you have not looked at these and what they can do I will explain more later in this post as well as in subsequent posts. The next point is that there is a new flag in the manifests file: ‘safeWithCustomScriptDisabled’, defaulting to false. The comments in the file state the following: ‘This property should only be set to true if it is certain that the webpart does not allow arbitrary scripts to be called’.
The other interesting piece is that, while Microsoft has not open sourced the generator, it is possible to peek into the inner workings. (See bottom of this post for how to do this.) Along with a great deal of refactoring between versions, there there are references in the source code to spo and onprem. What makes these interesting is that they hint at a differentiation between components and webparts targeted to onprem versus those targeted to Office 365. This is potentially hugely problematic, particularly for hybrid deployments. In other words there would need to be separate code bases for any webpart or component intended for both environments.
1.1.1 to 1.1.3 Changes with Webparts
Now to the meat of the matter. The first difference that will be noticeable to the user is that there are different prompts when creating a new SPFx projects. They both start off asking for a solution name, but then 1.1.3 diverges from 1.1.1 in the next couple of prompts. 1.1.3 asks where to place the files, a new folder or the current one. From what I can tell it really does not matter in that it will generate the new files in whatever folder from which you are calling the generator. The next prompt is this: ‘Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites?’. This, thankfully and exceptionally, does what it says it seems to say it will do. I can see where this can be a very useful feature especially since the power is still in the admin’s hands and does not force deployment to all sites, only gives him or her the option of doing so. After that the two generator's prompts are the same, asking for what type of project to create, webpart or component, name, description and finally what framework to use.
To recap here are the prompts from each:
|Solution Name||Solution Name|
|Where to place files||Does not seem to do what it suggests it will do, and only asks once if putting different types into the same folder|
|Option to deploy to all sites|
|Type of component||Type of component|
|Component Name||Component Name|
|Component Description||Component Description|
|Framework to Use||Framework to Use||Only in case of FieldCustomizer type|
I was able to easily create projects using both generators easily since I use nvm as suggested by AC, so I was able switch between node versions which had different packages installed. (See my blog post on the presentation I did with Tri-SPUG and the attached slides http://sharepointguy.com/my-blog/presentation-to-triangle-spug.) The other thing I did to compare the two versions was to do a diff of the resulting projects. There were only two files which differed: the package-solution.json, and manifest.json. The package-solution.json naturally differed in such things as id name, but also in that it had a skipFeatureDeployment property to accommodate the new feature to skip deployment on a site by site basis. In my case it was true since I accepted the default of true. Here it is in my diff tool of choice:
The manifest.json had a new property named ‘requiresCustomScript’ defaulting to false, in lieu of the ‘safeWithCustomScriptDisabled’ property in the 1.1.1 version. The comments for this new entry are as follows: ‘If true, the component can only be installed on sites where Custom Script is allowed. Components that allow authors to embed arbitrary script code should set this to true. https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f’. This is a subtle nuance from the ‘safeWithCustomScriptDisabled’ property. Again, here it is in a diff tool:
For what it is worth each project I created with the –skip-install parameter. For more information on this see https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f’.
1.1.1 to 1.1.3 Changes with Extensions
Changes to the SPFx generator from versions 1.1.1 to 1.1.3 are not significant other than the changes with Webparts as noted above. This was a little disappointing to me in that with Extensions introduced in version 1.1.1, I would have expected very material changes to the generated code files (.ts) in version 1.1.3.
The introduction of Extensions to the SharePoint Framework allows developers to customize the application itself in some of the ways we were used to doing with Features and Solutions. Here is the initial promo piece from Microsoft: https://dev.office.com/blogs/announcing-availability-of-sharepoint-framework-extensions-developer-preview. There are three types of Extensions:
- Application Customizer
- With this type of extension a developer can override the rendering of a specific region of the page. For example in the above referenced introduction, one can see how to override the rendering of the PageHeader using a React component. The base class for all application customizers is BaseApplicationCustomizer. This capability is much like what we had with Delegate Controls previously.
- Field Customizer
- This type of extension allows a dev to display a field in some customized way. The example Microsoft presents is that of confidential contact information. In teir example the customizer blurs the field, unless and until the user hovers over it. The base class for customizations of this type is BaseFieldCustomizer.
- List View Command Set
- As the name suggests, this type allows the dev to add commands to the item level menu, or context menu for the list when one or more items are selected. The base class for all customizations of this type is BaseListViewCommandSet.
One other item worth noting is that with 1.1.3 there is a React component, OpenCassDialog, that is available to devs to display dialog boxes with which custom actions can be associated.
How to peek inside the generator
If you want to view inside a generator, or any other globally installed package, you need first to open the folder where the packages are stored and that depends on whether you installed node by downloading a specific version from the NodeJs site, or via nvm; in both cases it will be in your user folder’s
AppData\Roaming subfolder. If the former, installing node via a downloaded package, then the packages will be under the npm\node_modules folder; if the latter then there will be a subfolder named nvm, with subfolders for each version installed, each with a node_modules folder containing the packages. So, for example, since I use nvm my global packages are all under the folder C:\Users\Robert\nvm\Vx.x.x\node_modules.
The reason there are so many more packages here than what is installed globally is that there are also the packages upon which the global packages are dependent The SharePoint generator is in a subfolder named @microsoft. To see the SharePoint generator for version 7.7.3, I need to go to C:\Users\Robert\AppData\Roaming\nvm\v7.7.3\node_modules\@microsoft\generator-sharepoint. With this information you can inspect the code the generator runs, compare the changes to the SPFx generator from versions 1.1.1 to 1.1.3 (assuming you are using nvm), or otherwise tinker with it.
This is also a good way to see the changelog when you update a package.