SAP/ui5-tooling

Shims no longer bundled after migration to v3

dfenerski opened this issue · 4 comments

Hi, I am creating this issue because the 'get a slack invite' website seems to crash on email submission..
So - I've followed the migration guide and attempted to build an app with a dedicated library using the -a flag. Earlier this used to mount all shims under the /resources dist directory, but now only some? shims are mounted. I cannot seem to find any info regarding shims & this behavior in the new tooling version. What am I missing?

Expected Behavior

Shims in libraries should be in the dist of the consuming app

Current Behavior

None or only some shims are bundled in the dist

Steps to Reproduce the Issue

{...}

Context

  • UI5 Module Version (output of ui5 --version when using the CLI): 3.0.5
  • Node.js Version: 16.9.1
  • npm Version: 8.19.3
  • OS/Platform: Win11
  • Browser (if relevant): not relevant
  • Other information regarding your environment (optional): nothing

Follow-up: ui5 tree lists the shims that do get bundled. So if it is in the dep graph, it gets properly bundled.

ui5 build --excludeTask=* --includeTask="problematicLib" --verbose yielded the following line for a shim that does not get bundled: Module rxjs neither provides a project nor an extension. Skipping dependency resolution as well as Warning - Dependency rxjs is available at multiple paths:

Log statement is here

The app has depDependency to rxjs so that only the TS types are available. The lib has dependency to rxjs so that it gets installed, shimmed and bundled there. This is the project logic.

If my understanding is correct, the first occurrence of rxjs is in the root, and therefore the tooling prefers it, but the shim is defined in the library, so it does not get copied around as multiple apps consume the lib. Is there a way to adjust this behavior?

Another follow-up: disabling devDependency analysis here and here solved my problem. I think this confirms the issue as I understand it in the comment above - the tooling refuses to bundle when a shim is duplicated twice in a consumer app and in an underlying lib. However I think the use case is legit - the lib shims & marks as dependency once; any consumer app specifies the lib as dep and the shims as devDependency for type usage only.

Am I wrong? Can this behavior be tweaked?

Additional question, perhaps a sillier one - why are depDependencies even bundled & shipped to the browser? Isn't their point to be dev only ?

Any information on those questions is appreciated. Thanks in advance.

Hi @dfenerski ,

Would be able to elaborate a little bit more?

What I understand so far is that you have couple projects an app and some library that is dependency of that app.
The rxjs is a dependency of the library, but in the app is used only when developing (devDependencies), so you'd have TS definitions available for it. And you'd end up with a structure like this:

App structure

app/
  \_ node_modules/
    \_ library/
      \_ node_modules/
        \_ rxjs/

app's package.json

{
  "name": "app",
  ...
  "dependencies": {
    "lib": "^X.Y.Z"
  },
  "devDependencies": {
    "rxjs": "^X.Y.Z"
  }
}

library's package.json

{
  "name": "lib",
  ...  
  "dependencies": {
    "rxjs": "^X.Y.Z"
  }
}

library's shim for rxjs (eventually) in ui5.yaml

specVersion: "3.0"
kind: extension
type: project-shim
metadata:
  name: rxjs
shims:
  configurations:
    rxjs:
      specVersion: "3.0"
      type: module
      metadata:
        name: rxjs
      resources:
        configuration:
          paths:
            /resources/: ""

If I understand correctly your complaint, you'd expect that dependencies for the library would be in the dist/ folder of the app when buliding the app.

Did I understand it correctly?

Thanks for reaching out @d3xter666, that's pretty much it.

What essentially happens is that app reuses a dependency of library instead of installing it on its own, so that node_modules / the dist bundle are slimmer, the shim is not redefined & any other client apps app1, app2, etc can easily import it (shared shim). As the project runs on TS, type definitions for this reused dependency are installed as devDependency only.

I.e app uses rxjs also at runtime & not only during development time: the library uses sap.ui.loader.config to provide import shim which points sap.ui.define(['rxjs']) to resources/library/shimmed_modules/rxjs.

Therefore:

  • rxjs is installed, shimmed & bundled only once
  • any consumer app of library automatically has the shim available & can use simple imports without having to redefine it or bundle the dependency again

If we were to stick with the default dependencies-only bundling, each consumer app would have to install rxjs, define its own local version of the shim (the local install will map the OSS to local virtual path) & only then be able to sap.ui.define(['rxjs']).

Looking for a way to standardize/automate this process in a multi-app/lib context led me to this issue, it could very well be that I've missed something in the process.