nickbalestra / cycle-scripts-es-webpack

2 stars 0 forks source link

Trying to add custom-elements v1 integration with Cycle.js app #1

Open kristianmandrup opened 7 years ago

kristianmandrup commented 7 years ago

Hi guys,

I'm trying to get custom elements v1 working with Cycle.js. Been on a major quest but almost got it now.

TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

I need a native-shim

This shim allows elements written in, or compiled to, ES5 to work on native implementations of Custom Elements.

ES5-style classes don't work with native Custom Elements because the HTMLElement constructor uses the value of new.target to look up the custom element definition for the currently called constructor. new.target is only set when new is called and is only propagated via super() calls. super() is not emulatable in ES5. The pattern of SuperClass.call(this)`` only works when extending other ES5-style classes, and does not propagatenew.target`.

This shim allows the native HTMLElement constructor to work by generating and registering a stand-in class instead of the users custom element class. This stand-in class's constructor has an actual call to super(). customElements.define() and customElements.get() are both overridden to hide this stand-in class from users.

Then I'm using document-register-element polyfill, with or without @webcomponents/custom-elements

Basically my main problem now is to get a babel-plugin-transform working with your script. Could you please document or advice how to do this. Thanks

I need to use babel-plugin-transform-custom-element-classes

.babelrc

// include before transform-es2015-classes 
{
  "plugins": [
    "transform-custom-element-classes",
    "transform-es2015-classes"
  ]
}

I checked babel-loader options but doesn't match with your config (webpack 2+)

      use: {
        loader: 'babel-loader',
        options: {
          presets: ['env'],
          plugins: [require('babel-plugin-transform-object-rest-spread')]
        }
      }

Your start script:

// start.js
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel',
        query: {
          presets: ['es2015']
          // <= add plugins here!?
        },
        exclude: /node_modules/
      }
    ]
Module build failed: TypeError: Falsy value found in plugins
    at /Users/kristianmandrup/repos/cycle-apps/my-awesome-cycle-app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:163:15

So I tried changing start script to and installing the plugins inside node_modules/cycle-scripts via npm

        loader: 'babel',
        query: {
          presets: ['es2015'],
          plugins: [require('babel-plugin-transform-custom-element-classes'), require('babel-plugin-transform-es2015-classes')]
        },

In my app:

// not sure which combination to use for Babel ES6!? :O

import './native-shim'
import '@webcomponents/custom-elements'
// import installCE from 'document-register-element/pony'
// installCE(global, 'auto')

// ...

// create a class with custom methods
// overrides, special behavior
class MyGreetings extends HTMLElement {
  show() {
    alert(this.textContent);
  }
}

// define it in the CustomElementRegistry
customElements.define('my-greetings', MyGreetings)

// using it later via h
div([
  h('my-greetings'),
  // ...
])
kristianmandrup commented 7 years ago

Maybe this hack will make it simpler... :)

kristianmandrup commented 7 years ago

Basically all described in this blogpost on Custom Elements v1 - hello world where he uses the babel transform. So, how can I add a babel transform plugin to my cycle script!?

Let's add a script that comes with: es6, babel, webpack and custom elements :)

custom elements - hello world