live-codes / livecodes

Code Playground That Just Works!
https://livecodes.io
MIT License
785 stars 66 forks source link

Feature: Use NPM packages from private registries. #542

Closed Nelladel closed 4 months ago

Nelladel commented 5 months ago

Type of feature

✨ Feature

Current behavior

Now NPM, Unpkg, JSdeliver, CDNs... can be used to import dependencies. I would like to do the same with private ones.

Suggested feature

We are developing a small component library. For the documentation, we're evaluating different playground options, and Livecodes is a promising candidate. However, we're failing to see how could the following issue be resolved:

Ideally, we would like to use an NPM package which is published to a private NPM Artifactory registry.

As I see it, the way of working would be to -somehow- use the import property of the playground's options with the private URL (i.e.: https://privaterepostory:1234/npm/@project/library@semantic-version).

However, if this is not supported, I would like to know what options are there? Could I include a step in the librarie's pipeline where the required bundle files are extracted (.js & .css) and left in a folder of the containing documentation application? Maybe that way, the playground could somehow import those static files from the parent application's directory on load, or after load...

Do I have to create a private CDN for this?

To summarise: I have full control over the package's lifecycle and source code, and I would like to include examples of our library's usage on livecodes embedded playgrounds.

Thanks!

Additional context

No response

Code of Conduct

Contributing Docs

Nelladel commented 5 months ago

In addition, the content from the private artifactory is hosted on HTTP instead of HTTPS. This means that whenever I try to import the .js file through a normal <script> tag (which is another option I was thinking about), I get a mixed-content error:

Mixed Content: The page at 'https://livecodes-sandbox.pages.dev/v8/?markup=html&style=css&script=javascript&isEmbed=false&isLoggedIn=false&appCDN=unpkg' was loaded over HTTPS, but requested an insecure script 'http://private-repo-IP:port/artifactory/library/artifact/bundle.esm.js'. This request has been blocked; the content must be served over HTTPS.

hatemhosny commented 5 months ago

Thank you @Nelladel for your interest in LiveCodes

Yes, LiveCodes playground does support importing unpublished libraries. In fact, this is an important use case provided for library authors.

This is documented in docs about module resolutions. Also you can provide type definitions for editor intellisense. See docs about custom types.

However, this is a quick summary:

You need to have your modules hosted on a URL that is accessible to the playground (e.g. https://my-website.com/path/to/library.js)

of course you can just import from this URL. e.g.

import myMod from 'https://my-website.com/path/to/library.js';

However, you can specify an import map to map your desired library name to this URL, and then use it like this:

import myMod from 'my-lib';

This can be achieved by using the SDK options.config.imports, like that:

import { createPlayground } from 'livecodes';

const config = {
  imports: {
    'my-lib': 'https://my-server.com/path/to/library.js',
  },
  // other configurations ...
};

createPlayground('#container', { config });

You can use any valid URLs, including Data URLs

I hope this helps. Please let me know if you have any more questions.

Nelladel commented 5 months ago

Hi @hatemhosny ,

Thanks for the fast response. I managed to code a crude proxy API which converts HTTP to HTTPS with a self-signed and trusted certificate. Now the config.imports is "working" (no more mixed-content errors).

I would now like to use the contents of the library in the Angular template, as you would with any other library I download from NPM (npm i @project/library).

If the playground creation looks like this:

  public ngOnInit(): void {
    createPlayground("#livecodes", {
      template: "angular",
      config: {
        imports: {
          'swc': 'https://localhost:5001/proxy?url=http%3A%2F%2F1.2.3.4%3A8082%2Fartifactory%2Flibrary%2Fartifact%2Fbundle.esm.js',
        }
      }
    })
  }

What would I have to do to actually use it inside my Angular project in livecodes?

For instance, I would normally just do: import '@project/library'; and then use the library components in the HTML of the Angular components.

Thanks!

hatemhosny commented 5 months ago

hi @Nelladel

I would not recommend using template and config properties together. The template is just a shortcut for quickly loading a starter template. If you want to load custom content, it is better to skip the template and provide a full config for your project.

To get the the config object of any project as JSON (e.g. after you load the angular template in the app): app menu -> Export -> Export Project (JSON)

You can then use this config object.

This is the full documentation for the config object: https://livecodes.io/docs/configuration/configuration-object

You may add the editor contents in the config object properties: markup, style and script You would usually specify language and content for each.

This is an example of how to create an embedded playground and run Angular: https://livecodes.io/?x=id/buyw6nn3m4p

You may edit the content and add your imports