eik-lib / issues

All Eik issues, bugs, questions etc goes here. Documentation is to be found at https://eik.dev
1 stars 0 forks source link

RFC 6 - Runtime Serverside Mapping #15

Open digitalsadhu opened 1 year ago

digitalsadhu commented 1 year ago

Runtime Serverside Mapping

This RFC outlines a use case that is difficult to support currently and outlines one possible solution for illustration.

The use case

A key feature of Eik is being able to use a package dependency name as a reference to refer to an absolute Eik url (most likely major alias version).

Example:

@fabric-ds/css => https://assets.finn.no/pkg/@fabric-ds/css/v1/fabric.min.css

Our Eik tooling currently is geared up around doing this mapping as part of a build step (Rollup, rebuild etc).

However, there are times when it would be useful to be able to do this mapping server side at runtime.

For example, you might write a server side only application that uses the package @fabric-ds/css. One option is to hard code the link to the library on the Eik server into your document but this risks your app getting outdated if Fabric CSS every bumps major version and you are left with no mechanisms to detect and rectify this.

<!-- Example: we want to avoid this! -->
<head>
  <link rel="stylesheet" href="https://assets.finn.no/pkg/@fabric-ds/css/v1/fabric.min.css" type="text/css" />
</head>

What you ideally want is to be able to refer to @fabric-ds/css and have the absolute URL mapping done automatically in the background.

One possible solution

The first solution that comes to mind is to create methods on the Eik client that take a dependency name, look up the package version in package.json and use that and eik.json values to construct an absolute URL.

(name: string) => absoluteUrl: URL

Even better if the returned URL object has a .toHTML() method to make creating link and script tags simple.

const url = await eik.buildAliasURL('@fabric-ds/css');
<head>
  ${url.toHTML()}
</head>

Other solutions?

@trygve-lie Are there other, better ways of solving this or does this idea have teeth?

trygve-lie commented 1 year ago

The Node Client is intended to help cater for such type of tooling. Currently the Node Client can give you an absolute URL to a asset file in the project one are in with the intention that in the server one call a method on the Node Client and depending on if one are in development mode or not one will get the URL to the file locally or the URL to the same file on the Eik server.

Example:

Local development:

const client = new EikNodeClient({
    development: true,
    base: 'http://localhost:8080/assets'
});
await client.load();

client.file('/js/script.js')  // Returns: http://localhost:8080/assets/js/script.js

In production:

const client = new EikNodeClient({
    development: false,
    base: 'http://localhost:8080/assets'
});
await client.load();

client.file('/js/script.js')  // Returns: https://cdn.eik.dev/pkg/mymodue/2.4.1/js/script.js

Though, this does not cover the case you describe here. As I read you, you want to get hold of the URL to a file which we normally swap out by replacing bare identifiers with an absolute URL to the file on the Eik server in a build step. In other words what I think we want is to get hold of the import mapping which is applied to a project and be able to get the mapping to a file on the Eik server.

The Node Client can do this today. The Node Client can be told to load all the import maps defined in the Eik config in a project and then they can be retrieved by a .maps() method which returns the maps as a string. The intention of this is to be able to load and inject import maps in the HTML so import mapping can happen in the browser and not ahead of time through a build step.

This can be used to achieve what your requesting. But we can probably sweeten the API by adding some extra methods like a .mapping() method or something.

Maybe something like this:

const client = new EikNodeClient({
    development: false,
    base: 'http://localhost:8080/assets',
    loadMaps: true,
});
await client.load();

client.mapping('some-lib')  // Returns: https://cdn.eik.dev/pkg/some-lib/v7/js/script.js
digitalsadhu commented 1 year ago

That works. With custom elements we can use this to pass urls from server side to client via the dom.