WebReflection / uland

A µhtml take at neverland
ISC License
108 stars 2 forks source link

[Help wanted]Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. #2

Closed shanghaikid closed 4 years ago

shanghaikid commented 4 years ago

Hi there, I really appreciate your wonderful projects, thank you.

Today, I want to try uland a little bit.

image image image But I got his error. image

Everything is ok when I create the component from the html. Is there some mistake I made ?

WebReflection commented 4 years ago

Everything is ok when I create the component from the html. Is there some mistake I made ?

what does this mean?

WebReflection commented 4 years ago

anyway, this works well to me https://codepen.io/WebReflection/pen/PoNYxMa?editors=0010

shanghaikid commented 4 years ago

Thank you for the reply, your demo link work well. But it failed to run after compiled by rollup.

image index.js image

image

@WebReflection

WebReflection commented 4 years ago

this is how I use rollup https://github.com/WebReflection/uland/blob/master/rollup/es.config.js but in general, if you have issues with rollup, I believe rollup repository is where you should open an issue, as the library here is bundled with rollup, it works via unpkg, so there's not much I can do.

shanghaikid commented 4 years ago

Ok, fine, thanks.

WebReflection commented 4 years ago

P.S. you can ignore the include-paths part of the configuration, or see the rollup babel version https://github.com/WebReflection/uland/blob/master/rollup/babel.config.js

shanghaikid commented 4 years ago

Thanks, actually there is no error during rollup compiling. my babel.config.js is exactly as yours. anyway, I am trying to figure it out. I want to build an UI lib using uland. Maybe I should go back to hyperhtml, that one I haven't see this kind of issue.

WebReflection commented 4 years ago

@shanghaikid all my libraries use the same configuration ... here some step you can try:

npx modulestrap --babel --ungap uland-button
cd uland-button
npm i --save uland

now open your editor and put this inside esm/index.js

import {Component as $, html, useState} from 'uland';

const Button = $(props => {
  const [count, setCount] = useState(0);
  const onClick = () => setCount(count + 1);
  return html`<button onclick=${onClick}>
    ${props.title} ${count}
  </button>`;
});

export {Button};

now npm run build

and then put this inside the test/index.html file

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>uland-button</title>
  <script src="../index.js"></script>
  <script type="module">
  const {render, Button} = ulandButton;
  render(document.body, Button({title: 'test'}));
  </script>
</head>
<body></body>
</html>

Now spin any server and reach localhost:XXXX/test/ to see it working.

Currently, unpkg produces a bad version of the library/module, so maybe you can try dropping it from the equation.

WebReflection commented 4 years ago

P.S. if you don't want to see warnings for the modern JS version, use this es.config.js inside rollup folder:

import {nodeResolve} from '@rollup/plugin-node-resolve';
import {terser} from 'rollup-plugin-terser';
import includePaths from 'rollup-plugin-includepaths';
export default {
  input: './esm/index.js',
  plugins: [
    includePaths({
      include: {
        '@ungap/custom-event': 'node_modules/@ungap/degap/custom-event.js',
        '@ungap/weakset': 'node_modules/@ungap/degap/weakset.js'
      }
    }),
    nodeResolve(),
    terser()
  ],
  context: 'null',
  moduleContext: 'null',
  output: {
    exports: 'named',
    file: './es.js',
    format: 'iife',
    name: 'ulandButton'
  }
};

also, try to see if neverland gives you less troubles

WebReflection commented 4 years ago

P.S.2 it's also possible that the failure is caused by the fact you are using 2 different versions of the module: one bundled, and one from unpkg, and this breaks because the Hole class won't be recognized.

You should always use the same module/bundling strategy, also because otherwise you include the library twice, which is unnecessary, or you can export all utilities from your main entry point, so that all components and the rest of the code will use the exact same version of the library.

This is likely true for every other library in general, as using two modules from two different worlds inevitably use two different internals, and it breaks, as all instances won't be recognized (wire in hyperHTML case, Hole, in uhtml and lighterhtml, hence uland, and neverland).

I hope this explains better why you have such error.

shanghaikid commented 4 years ago

Thank you very much. it works as I export the render function from the uland. image

So that means if I build a UI lib by uland, we need to export the render function ? The button is not standalone. ok, it is not a big deal.

Thank you for your time.

WebReflection commented 4 years ago

Which browser are you targeting, if I might ask? I could have a better solution, the same I use for uce, the solution explained in this post https://medium.com/@WebReflection/some-web-components-hint-75dce339ac6b

WebReflection commented 4 years ago

So, in case this can help solving some portability ... uland-lib exposes uland through customElements registry, and you can use a tiny helper to bring it in:

import when from 'once-defined';
export default when('uland-lib')
  .then(({Component, render, html, useState, ...}) => Component(props => {
    const [count, setCount] = useState(0);
    const onClick = () => setCount(count + 1);
    return html`<button onclick=${onClick}>
      ${props.title} ${count}
    </button>`;
  }));

This makes your components asynchronous, but you can import these via import('./button.js') ... not sure it's an ideal solution, but it works well in wickedElements case, but also in the uce one

shanghaikid commented 4 years ago

We are targeting modern browsers, no IE any more. I will try your solution later, thanks my javascript hero.