Skip to content

ScriptLibrary web-resource is always named <prefix>_main.js (name property ignored) #86

Description

@tompivny

A ScriptLibrary project's emitted web resource is always <prefix>_main.js, no matter what I set for ScriptLibraryMainFile. While digging in, I hit two more problems that seem related (the main default also makes the build grab a random node_modules/**/main.js, and old wrong-named artifacts are never cleaned up).

I think I've found the root causes and I have a workaround running, but I'm not sure what the correct fix is — could be the SDK is meant to be used differently, or these are genuine defects. Filing so maintainers can confirm and decide the right direction.

Three separate defects below — keeping them in one issue since they share one reproduction and one trigger chain (Bug 1 produces the main name that then feeds Bugs 2 and 3).

Bug 1 — ScriptLibraryMainFile seems to be ignored

Expected

Setting ScriptLibraryMainFile (or ScriptLibraryName) in the consuming .csproj controls the emitted web-resource name.

Actual

Web resource is always <prefix>_main.js. My ScriptLibraryMainFile value is ignored.

What I think is going on (not 100% sure)

build/…ScriptLibrary.propstasks/…ScriptLibrary.props:

<ScriptLibraryMainFile Condition="'$(ScriptLibraryMainFile)'==''">main</ScriptLibraryMainFile>
<ScriptLibraryName     Condition="'$(ScriptLibraryName)'==''">$(ScriptLibraryMainFile)</ScriptLibraryName>

For an SDK-style project (<Project Sdk="TALXIS.DevKit.Build.Sdk/1.5.1">), the SDK .props appear to be injected at the top of the project, before my <PropertyGroup> body. So at props-evaluation time it looks like:

  1. ScriptLibraryMainFile still empty → defaulted to main.
  2. ScriptLibraryName derived from that default → main, and its Condition="'$(ScriptLibraryName)'==''" is now permanently false.

My body then sets ScriptLibraryMainFile = … afterward, but ScriptLibraryName is already main and never re-derived. Downstream targets (GetScriptLibraryOutputs, CopyScriptLibraryMainToOutput) read ScriptLibraryName, so they all see main.

I could be misreading the import order, so please sanity-check this.

Temporary workaround

Set the derived property directly, no .js suffix (SDK appends .js):

<PropertyGroup>
  <ProjectType>ScriptLibrary</ProjectType>
  <ScriptLibraryName>myprefix_mylibraryname</ScriptLibraryName>
</PropertyGroup>

A body-level assignment to ScriptLibraryName is unconditional and runs after props, so it wins. Works for us, but feels like it's routing around the intended mechanism.

Bug 2 — main glob matches node_modules/**/main.js

Symptom

With ScriptLibraryName=main (the default from Bug 1), the deployed script is a random node_modules file, not the rollup bundle.

What I found

tasks/…ScriptLibrary.targets, CopyScriptLibraryMainToOutput:

<_ScriptLibraryMainFile Include="$(TypeScriptDir)/**/$(ScriptLibraryName).js" />

The ** descends into TS/node_modules and matches every dependency's main.js. Our TS/node_modules has 6 such files, e.g.:

node_modules/resolve/test/module_dir/zmodules/bbb/main.js
node_modules/terser/main.js

These get copied to $(TargetDir) as main.js, and GetScriptLibraryOutputs returns that. The deployed main.js was ~645 B of terser source (import { minify } …), not the ~175 KB project bundle.

Bug 3 — stale artifacts from a previous name are never cleaned up

Symptom

After the name changes (e.g. once Bug 1 is worked around, or any rename), the old artifacts linger and both wrong + right web resources get packed.

What I found

In Solution.ScriptLibraries.targets + the supporting tasks, the write steps only add, never reconcile:

  • EnsureWebResourceDataXml returns early if the .data.xml exists (EnsureWebResourceDataXml.cs:26-29) — never overwrites. Orchestration also only feeds it missing files.
  • AddRootComponentToSolution dedupes but only appends (AddRootComponentToSolution.cs:41-61) — never removes.
  • No cleanup/reconcile target anywhere.

Consequences:

  • Old <prefix>_main.js.data.xml stays in WebResources/.
  • Old <RootComponent type="61" schemaName="<prefix>_main.js" /> stays in Solution.xml.

So a one-time misconfiguration leaves permanent orphans that must be deleted by hand.

Possible directions (open)

  • A reconcile step that removes type="61" RootComponents and WebResources/*.data.xml whose schema name no longer matches a current ScriptLibrary output.
  • At minimum, document that renaming a ScriptLibrary requires manual removal of the old web-resource artifacts.

Not sure how aggressive a cleanup is safe here (could stomp intentionally hand-added web resources), so leaving the approach open.


Happy to test patches or provide a full minimal repro repo if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions