(Typescript) Reusing components from another packa...
# package-development
k
So Question: Is there a way to configure / define something so @jumoo/usync-assets imports will work from a child project ?
Again! So i have a package lets call it 'uSync'. that has a custom modal dialog, that we pass some data and it renders a view based on that data (its' change details, but i don't think the that matters much here). I also have another package lets call that 'uSync.Complete' that uses uSync and its own views where i want to launch up that custom dialog from the first package. so the first package exports the dialog/token so it can be consumed by another package. the second package, connects to the thing.
Copy code
ts
const detailsModal = this.#modalManagerContext?.open(this, USYNC_DETAILS_MODAL, {
   data: {
      item: action,
   },
});
All stadard and all 'working' at a typescript level. problem comes from how the package(s) are bundled i think. because in Umbraco we get :
Copy code
index.js:27  Uncaught (in promise) DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "usync-details-modal" has already been used with this registry
    at https://localhost:44302/umbraco/backoffice/c5264d27ed374c283a729f998d59bceda50d8626/external/lit/index.js:27:101
    at _ (https://localhost:44302/App_Plugins/uSync/details-modal-element-CIinhEQ3.js:5:42)
    at https://localhost:44302/App_Plugins/uSync/details-modal-element-CIinhEQ3.js:44:5
I think that is because with VITE building the uSync.Complete package it will include the elements of the uSync package we have used. and that means things are being defined twice in umbraco If i tell vite to treat the usync package as an external resource in the vite.config :
Copy code
ts
external: [/^@umbraco/, /^@jumoo\/usync-assets/],
then i get a diffrent error in the browser .. because it doesn't know how to import @jumoo/usync-assets
Copy code
entry-point-extension-initializer.js:41  Uncaught (in promise) TypeError: Failed to resolve module specifier "@jumoo/usync-assets/dialogs". Relative references must start with either "/", "./", or "../"
throwing a question out there is is this what import map ? does ?
So i think i know what i have to do (if i am right) - but it would be good to get confirmation. 1. I need to export my package in more a "lib" style format (e.g like a node_module with folder and files in them) 2. I need to put importmap into my umbraco-package.json so that we can map the
@jumoo/usync-assets
imports to folders e.g
Copy code
json
"importmap": {
   "imports": {
      "@jumoo/usync-assets/dialogs": "/App_Plugins/uSync/lib/dialogs/index.js"    
   }
}
this probibly means i don't want vite to do anything clever with my build? because i want the library to be predictable ? so the other packages can look it up ? is this the right way to be heading ?
Another (and probibly way worse) method i am looking at is just making vite output each file into the app_plugins.
Copy code
ts
rollupOptions: {
    external: [/^@umbraco/],
    output: {
    manualChunks: (f) => {
            if (f.indexOf('src') > 0) {
               let path =    f.substring(f.indexOf('src') + 4);
               path = path.substring(0, path.length - 3);
               console.log(path);
               return path;
            }
    },
        chunkFileNames: '[name].js',
  },
  onwarn: () => {},
},
this outputs everything into a folder structure directtly into the app_plugins, but with the added advantage of external libraries being bundles (so i don't have to rebuild them esp my autogenerated API folder).
then in theory ? i can do the import map direct to the right files ?
Reader ... That's a stupid idea 😔
n
I have nothing to contribute other than highlighting how useful these threads are 😃
j
I started looking into making this nicer, but didn't get very far. There's no nice solution that I can see. TL;DR; - Do exactly what the
@umbraco-cms
"package" does. Umbraco itself gets built with a single dependency graph that can be nicely managed by Vite and NPM. Packages, on ther other hand, are built separately, and as soon as you need to share code between packages, a lot of the niceness of dependency management with Vite and NPM goes away. I think using the "external" approach with your consuming package, and an import map in your lib package is the best approach - what you need will already have been provided/registered by the other package (assuming uSync.Complete depends on it via NuGet) - then this works the same way as the
@umbraco-cms
stuff. You don't need paths to be predictable - the point of the map is that your library package itself registers an alias for where
@jumoo/whatever
lives, so your consuming packages can just import
@jumoo/whatever
and it'll get mapped to the correct file. I'd let Vite do its thing (it works fine for the
@umbraco-cms
packages).
k
yes, i did get a bit further, and i got the mapping working quite well following how the
@Umbraco-cms
package does it. (which is a bit different that the page thing in that it does preserve the library paths much more (its closer to just a
tsc build
) the issue where i got a bit stuck, and had to park it just for now was external dependencies within the package you then want to share, (in my case signalR). because if you build it like the core umbraco package these are not merged into your final code. if you look at how the core does this it builds and minifies the the external packages in the /external folder of the library, and then references them from there. and i sort of got that going, but to be honest there are now only 20 working days until may 30th, so i moved on to some functionality building stuff!
j
Interesting. I haven't had to worry about that yet. Rather than try and have a shared dependency I'd be inclined to build it into the base package, and solve the problem by providing abstractions in that base package.
import { browserNotificationService } from "base-package";
k
Yes that is what the core are doing (for example with lit in the external folder) it's doable, but I ran out of time (did I mention 20 days 😅)
**sorry, worried i sounded to dismissive there, am happy your thinking about this, and i will almost certainly use what you've said *
j
Not at all, understand the time pressure - and the complexity. For me, the DX needs to be just right or I really struggle to maintain focus so I spend an inordinate amount of time thinking about these things before I actually get anywhere.
3 Views