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

create-elm-webcomponent #336

Open
1602 opened this issue Dec 23, 2018 · 10 comments
Open

create-elm-webcomponent #336

1602 opened this issue Dec 23, 2018 · 10 comments

Comments

@1602
Copy link
Contributor

1602 commented Dec 23, 2018

I wanted to resume discussion on creation of web-components with create-elm-app.

Desired goal: use zero-configuration setup to build a web-component rather than app.

In order to achieve this goal my immediate development needs I've forked create-elm-app and made a few non-compatible changes, here's a link to diff. Gist of what has changed:

  • entry point changed from src/index.js to src/custom-element.js
  • added to-string-loader in order to be able to get css as string, so that it can be inlined in component using const css = require('./main.css').toString();

Current workflow looks like this:

  1. develop app normally using create-elm-app workflow, using src/index.js as an entry point calling Elm.Main.init({ node: document.getElementById('root') })
  2. as soon as I'm ready to package result as a component I create another entrypoint src/custom-element.js containing something like this:
const Elm = require('./Main');
const css = require('./main.css').toString();

customElements.define('my-webcomponent',
    class extends HTMLElement {

        constructor() {
            super();

            const appRoot = document.createElement('div');
            const appStyles = document.createElement('style');
            appStyles.textContent = css;

            const shadowRoot = this.attachShadow({mode: 'open'});
            shadowRoot.appendChild(appStyles);
            shadowRoot.appendChild(appRoot);
            this.appRoot = appRoot;
        }

        connectedCallback() {
            const app = Elm.Elm.Main.init({ node: this.appRoot });
            this.app = app;
        }
});
  1. build web-component using elm-webcomponent build (modified version of elm-app), which results in build/custom-element.js file containing my app bundled as web-component.

I'm looking for direction for further development here, i.e. how would I need to adjust my copy to make these change into mainstream (if there's a need for that). Or maybe there are any better ideas on achieving this goal?

@halfzebra
Copy link
Owner

Hello again!

Happy to hear that you are interested in discussing the setup for making WebComponents. 👍

I might be wrong, but it looks like all of the desired changes could have been done using an override for Webpack config.

If we are to push this idea further, then I see two options:

  • make a plugin, which people could use in elmapp.config.js (I think this does not require any changes in this repo)
  • extend the functionality so we could support create-elm-app and create-elm-webcomponent if there is interest in the community towards that idea.

What do you think?

@1602
Copy link
Contributor Author

1602 commented Dec 24, 2018

Neat! I somehow missed this feature, which indeed allows to reconfigure app in a way that produces desired effect to build a webcomponent. At least it looks so from the first glance, I'm going to experiment with it to see what comes up.

The only issue I see with this solution is that I couldn't target both app and webcomponent, but I think I could use a workaround with env variable BUILD_TARGET=webcomponent, for now.

So, I believe building plugin to extend webpack config is a way to go. I'd be thankful if you point me to an example of existing plugin, as I've no idea how to implement that kind of plugin (or maybe some guide / doc).

@halfzebra
Copy link
Owner

It's a recent addition to Create Elm App, which is not very obvious.
I merely mean that for the starters you could make a function that modifies the original Webpack config.

We are trying to get away from environment variables, so the plan is to make some kind of support for the plugin system, where each plugin modifies Webpack config and enables additional features.

Try achieving the desired result with configureWebpack and if that is possible, then you could probably publish your configureWebpack as an NPM module, which other people will be able to use in their apps.

What do you think about that?

@1602
Copy link
Contributor Author

1602 commented Dec 24, 2018

Yep, that works. I will be working on that npm module, then.

@1602
Copy link
Contributor Author

1602 commented Dec 24, 2018

I've pushed my first take on this plugin here: https://github.com/1602/create-elm-app-webcomponent-plugin

I hope I get this idea of using plugin right, also looking for suggestion regarding naming of the plugin. Perhaps name should resemble the fact that this is a plugin for create-elm-app for building webcomponent.

@halfzebra
Copy link
Owner

Good stuff! I think it looks really promising! 👍

What do you think about dropping the "create-" and maybe "-plugin" parts out of the name?

@1602
Copy link
Contributor Author

1602 commented Dec 28, 2018

Sure, thanks for the naming suggestion. I've published elm-app-webcomponent npm package, gh repo.

@halfzebra
Copy link
Owner

Great news! 🎉

Would you like to have a dedicated section on this in the documentation?

@1602
Copy link
Contributor Author

1602 commented Dec 30, 2018

Yep, that would simplify discovery of this solution for others. Thank you!

@janwirth
Copy link
Contributor

neat.

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

3 participants