Quantcast
Channel: Node.js Tools for Visual Studio
Viewing all articles
Browse latest Browse all 4630

Created Unassigned: Empty properties in DTE ProjectItem object is a problem [771]

$
0
0
#Background:

Node.js project is classified as `OAProject` type, which is same as WinJS (Windows 8.x Store app) project.

With Winjs project, in order to set file nesting using Visual Studio shell, we use the following [code in Web Essentials extension](https://github.com/madskristensen/WebEssentials2013/blob/df6b379e34437136ad28977ee49838c0337542d4/EditorExtensions/Shared/Helpers/ProjectHelpers.cs#L453-474):

```c#
if (Path.GetFullPath(parentFileName) == Path.GetFullPath(fileName) || !File.Exists(fileName))
return null;

fileName = Path.GetFullPath(fileName); // WAP projects don't like paths with forward slashes

var item = GetProjectItem(parentFileName); // return projectItem

if (item == null || item.ContainingProject == null || string.IsNullOrEmpty(item.ContainingProject.FullName))
return null;

var dependentItem = GetProjectItem(fileName);

if (dependentItem != null && item.ContainingProject.GetType().Name == "OAProject" && item.ProjectItems != null)
{
// WinJS

// check if the file already added ( adding second time fails with ADDRESULT_Cancel )
if (dependentItem.Kind != Guid.Empty.ToString("B"))
return dependentItem;

ProjectItem addedItem = null;

try
{
addedItem = dependentItem.ProjectItems.AddFromFile(fileName);

// create nesting
if (Path.GetDirectoryName(parentFileName) == Path.GetDirectoryName(fileName))
addedItem.Properties.Item("DependentUpon").Value = Path.GetFileName(parentFileName);
}
catch (COMException) { }

return addedItem;
}
...
...
// handle other types: Website and WebApplication projects
```

Which looks weird, because in case of Web Application project ([L482](https://github.com/madskristensen/WebEssentials2013/blob/df6b379e34437136ad28977ee49838c0337542d4/EditorExtensions/Shared/Helpers/ProjectHelpers.cs#L482)), its rather straightforward:

```c#
item.ProjectItems.AddFromFile(fileName); // This adds the file and take care of nesting; one liner solution
```

But that ugly solution for WinJs is working at least!

On the contrary, in case of Nodejs, when the third party compilers (CoffeeScript, TypeScript, Less, SCSS, Sweet.js etc.) emits files in project directory, the projectItem gets the file in Enumeration, but `dte.Solution.FindProjectItem(fileName)` returns null because projectItem.Document is null. We tested this in debug mode. This is a deal breaker.

#What are we trying to achieve:

Nesting: suppose you have a less file in node.js project under `<project-roo>\Content\LESS` directory. Using Web Essentials, when the less is compiled (on save OR on build) the resultant `.css`, `.min.css`, `.css.map` and `.min.css.gz` files are stored in the same directory. In case of WinJS project, the associated projectItem for each generated file gets Document, which help DTE system find these projectItem. With empty Document, FindProjectItem( _ ) returns null, even though Project.ProjectItem**s**' enumeration contains the file.

I came up with a workaround, to file the parent projectItem of the source (less) file's projectItem, that is the folderItem namely LESS. Then we enumerate this immediate parent folder item and match the Name property using LINQ.

```C#
if (dependentItem == null && item.ContainingProject.Object.GetType().Name == "NodejsProjectNode")
{
// Node.js project

var parent = item.Collection.Parent as ProjectItem;
dependentItem = parent.ProjectItems.Cast<ProjectItem>().FirstOrDefault(p => p.Name == Path.GetFileName(fileName));

if(dependentItem == null)
return null;

ProjectItem addedItem = null;

try
{
addedItem = dependentItem.ProjectItems.AddFromFile(fileName);

// create nesting
if (Path.GetDirectoryName(parentFileName) == Path.GetDirectoryName(fileName))
addedItem.Properties.Item("DependentUpon").Value = Path.GetFileName(parentFileName);
}
catch (COMException) { }

return addedItem;
}
```

Unfortunately, it didn't work either because this time `item.Collection` is empty for the less source file, which means we can't fetch its parent folderItem..

Please fix this issue, so we can add nested items like WebApplication (using `AddFileFrom`) OR at least by properly initiating Document property when the files arrive in the project directory/sub-directory and projectItem.Collection to get its immediate ancestry.

This, so we avoid the worst and most expensive solution; to iterate the whole project hierarchy and find for the generated files under the same folder as the source file.

More discussion at: https://github.com/madskristensen/WebEssentials2013/pull/741.

Thanks in anticipation.


Viewing all articles
Browse latest Browse all 4630

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>