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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions