IgniteUI / igniteui-angular

Ignite UI for Angular is a complete library of Angular-native, Material-based Angular UI components with the fastest grids and charts, Pivot Grid, Dock Manager, Hierarchical Grid, and more.
https://www.infragistics.com/products/ignite-ui-angular
Other
569 stars 162 forks source link

Migration from 17 to 18 failed: Adding global CSS rule to ensure non-specified sizes for components #14346

Closed lalo-mx closed 3 months ago

lalo-mx commented 3 months ago

Description

Migration from 17.1.10 to 18 failed: s.startsWith is not a function

Steps to reproduce

  1. Upgrade from 17.1.10 to 18.0.0

Result

What is the actual result after following the steps to reproduce?

Error log


> Updates Ignite UI for Angular from v17.2.x to v18.0.0.
    Applying migration for Ignite UI for Angular to version 18.0.0
    Adding global CSS rule to ensure non-specified sizes for components remain the previous default (Large).
            Please refer to the migration guide (https://www.infragistics.com/products/ignite-ui-angular/angular/components/general/update-guide) for more information.
× Migration failed: s is not defined
  See "C:\dummy\Temp\ng-h21rOY\angular-errors.log" for further details.
[error] TypeError: s.startsWith is not a function
    at C:\dummy\igniteui-angular\migrations\update-18_0_0\index.js:96:274
    at Array.filter (<anonymous>)
    at updateMainCSSFile (C:\dummy\igniteui-angular\migrations\update-18_0_0\index.js:96:260)
    at C:\dummy\igniteui-angular\migrations\update-18_0_0\index.js:134:5
    at Generator.next (<anonymous>)
    at fulfilled (C:\dummy\igniteui-angular\migrations\update-18_0_0\index.js:11:58)

Expected result

What is the expected result after following the steps to reproduce? Error do not happens

Attachments

Attach a sample if available, and screenshots, if applicable.

lalo-mx commented 3 months ago

The errors happens with complex file references in angular.json of the configuration in project.architect.build.options.styles, for example

{ "input": "src/lazy-style.scss", "inject": false },

https://angular.io/guide/workspace-config#style-script-config


"styles": [
  "src/styles.css",
  "src/more-styles.css",
  { "input": "src/lazy-style.scss", "inject": false },
  { "input": "src/pre-rename-style.scss", "bundleName": "renamed-style" },
]
lalo-mx commented 3 months ago

@jackofdiamond5 The migration is not crashing anymore with version 18.0.1 but the migration is still not executing.

    No styles file found in angular.json for project: [object Object]
    Could not find the CSS file: undefined

https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/migrations/update-18_0_0/index.ts#L95

For some reason s is not an instance of object, an example of the serialized object:

Serialized styles:

{"input":"src/styles.scss","bundleName":"styles","inject":true}

With some debugging

    context.logger.error(`Styles files: ${JSON.stringify(s)}, typeof ${typeof s}, s instanceof Object ${!!(s instanceof Object)}`);

Result:

    Styles files: {"input":"src/styles.scss","bundleName":"styles","inject":true}, typeof object, s instanceof Object false
lalo-mx commented 3 months ago

More debugging

context.logger.error(`input in s ${!!('input' in s)}`);

Result:
input in s true
valadzhov commented 3 months ago

Hi @lalo-mx, There's no designated migration for 18.0.1 to be executed when updating, that's why no migration is being run. Can you try to execute it manually like this: ng g igniteui-angular/migrations/migration-collection.json:migration-38

lalo-mx commented 3 months ago

Hi @valadzhov ExcEuted manually like you suggested and it shows an error in the terminal

 ng g igniteui-angular/migrations/migration-collection.json:migration-38

Result:

    Applying migration for Ignite UI for Angular to version 18.0.0
    Adding global CSS rule to ensure non-specified sizes for components remain the previous default (Large).
            Please refer to the migration guide (https://www.infragistics.com/products/ignite-ui-angular/angular/components/general/update-guide) for more information.
    No styles file found in angular.json for project: [object Object]
    Could not find the CSS file: undefined

Example of styles in angular.json

          "styles": [
              {
                "input": "src/styles.scss",
                "bundleName": "styles",
                "inject": true
              }
            ],
jackofdiamond5 commented 3 months ago

@lalo-mx I was trying to narrow down the reason why instanceof can return false in this case and I made some discoveries. instanceof will look at the prototype of s and check if it has an Object constructor function. In this case it should always be there since in the schematics we are doing a simple JSON.parse on the angular.json which should always return an object that inherits the base Object type. If it doesn't have that Object constructor function in its prototype, instanceof will return false but the only way I managed to do that was by feeding it an Object.create(null) which creates a plain object with no prototype. So I ruled that out and found that another possible reason instanceof could return false is due to different contexts. Like for example, we are doing all of the parsing in an internal utility that is only used in the factory function of the schematic that's being run. And I played around in that utility and could not ever get the instanceof to return false for the elements in the styles array. However, when I moved back to the factory function of the schematic, I found that whatever object was returned from the utility, even the project itself is not considered an object by instanceof. Funnily enough, if I do the parsing inside the factory function, all is good. So my guess is that because of the different context that executes the schematics, the reference of Object in the element's prototype is different and since instanceof will look at that reference and compare it to the currently executing context, it will return false. This would imply that any JSON parsing done outside of a schematic's factory and fed back into the factory would be with a different prototype chain. I will have to do some more testing to figure it out a 100% but this is my best guess as to what is happening atm.

Either way, I made a small change to the check that looks at the object, which is not typeof s === 'object' which should allow the migration to move forward and be applied as intended. This should be out in 18.0.2.