Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q: wrapping requirejs amd module (durandaljs interop) #54

Open
jkone27 opened this issue Jul 11, 2022 · 2 comments
Open

Q: wrapping requirejs amd module (durandaljs interop) #54

jkone27 opened this issue Jul 11, 2022 · 2 comments

Comments

@jkone27
Copy link

jkone27 commented Jul 11, 2022

is there a way to wrap within a web-component a requirejs/amd module?

i am using a very old durandaljs (then aureliajs) app, and it uses requirejs and amd module loading.
https://github.com/BlueSpire/Durandal
https://www.infoq.com/articles/durandal-javascript-framework/

i was thinking i could turn that to interop with F# and Fable.Lit and progressively migrate away from it completely

index.html

<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" data-main="app/main"></script>
    </head>
    <body>
        <div id="applicationHost"></div>
    </body>
</html>

Main.js

requirejs.config({
    paths: {
        'text': 'https://cdnjs.cloudflare.com/ajax/libs/require-text/2.0.12/text.min',
        'durandal':'https://cdn.jsdelivr.net/npm/[email protected]/js',
        'plugins' : 'https://cdn.jsdelivr.net/npm/[email protected]/js/plugins',
        'transitions' : 'https://cdn.jsdelivr.net/npm/[email protected]/js/transitions',
        'knockout': 'http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.5.0',
        'jquery': 'https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min',
        } 
    });
    
define(function (require) {
    var system = require('durandal/system');
    var app = require('durandal/app');

    system.debug(true);

    app.title = 'Durandal Starter Kit';

    app.configurePlugins({
        router:true,
        dialog: true
    });

    app.start().then(function() {
        app.setRoot('shell');
    });
});

and the main view: Shell.js

define(function (require) {
    var app = require('durandal/app');
    var ko = require('knockout');
    return {
        name: ko.observable(),
        sayHello: function () {
            app.showMessage('Hello ' + this.name() + '! Nice to meet you.', 'Greetings');
        }
    };
});

And Shell.html.. they use Knockout.js for 2-ways bindings...
https://knockoutjs.com/index.html

was just curious which approach would you go to use Fable.Lit on this one, if any idea

thank you so much, i am quite new to js for now i have managed to transpile to ts and back to js but took me a while, i was checking also fable alternatives as F# is my fav lang :)

@jkone27
Copy link
Author

jkone27 commented Jul 11, 2022

also i never used vite (was doing all with babel for what i achieved for now), could this be useful? - https://github.com/linsk1998/vite-plugin-amd ?

@AngelMunoz
Copy link
Collaborator

is there a way to wrap within a web-component a requirejs/amd module?

There is no need to wrap web components at all, they are standard browser features so you can just import the file that registers the web component directly

you can see this in the codepen https://codepen.io/AngelMunoz/pen/XWEKxLO you can import them directly in your index.html or if you you truly want to make it part of requirejs you'd need to do something like this

requirejs.config({
    paths: {
        '@material/mwc-snackbar': 'https://cdn.skypack.dev/@material/mwc-snackbar',
        // other imports
        } 
    });
// Shell.js
define(function (require) {
    require('@material/mwc-snackbar'); // import to register the web component
    // other code
});

For Fable.Lit based Web components, depending on how you setup your project, you can include the imports in a similar fashion to this project, you can import the fable bundle to your index.html or compile the fable sources, put them in an internal cdn and consume them via requirejs or index.html

the key point here is that once you register a web component by importing on the browser somehow it is not globally available and it is not required to be in any kind of bundler, be it webpack, vite, require, etc.

module Components.MyElement

[<LitElement("my-element")>]
let private Element() =
  LitElement.init() |> ignore
  html $"<div>I'm Web Component</div>"

let register() = ()

to use it from F# you'd do something like this

module Main

open Components

MyElement.register() // this ensures the web component gets registered within the browser

to use it from Javascript you'd do something like this

// for bundlers and other things that don't apply dead code elimination
import 'fable-output/MyElement.fs.js' // this is enough

// for bundlers and tools that apply dead code elimination (trimming, tree-shaking)
// you can import it in the following ways
import { register } from '../fable-output/MyElement.fs.js'
// or 
import { register } from 'fable-output/MyElement.fs.js' 

register();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants