lit icon indicating copy to clipboard operation
lit copied to clipboard

While upgrading to Lit 3.1.1 from Lit 2.2.5, it gives me the below error while browsing

Open SreekumarSekharan opened this issue 2 years ago • 17 comments

Which package(s) are affected?

Lit Core (lit / lit-html / lit-element / reactive-element)

Description

The issue seems to be in @lit\decorators\property.js. It complains that

    Uncaught TypeError: e.constructor.createProperty is not a function
        at property.js:6:682
        at property.js:6:768
        at Object.decorateElement (property.js:6:776)
        at Object.<anonymous> (property.js:6:776)
        at Array.forEach (<anonymous>)
        at Object.decorateClass (property.js:6:776)
        at _decorate (property.js:6:776)
        at simple-element.ts:5:27
        at app.ts:7:122

My files have the following entries babel.config.json package.json tsconfig.json

I also have the main source files as below src/app.ts

    import '@webcomponents/webcomponentsjs'
    import 'core-js/modules/es.global-this'
    import 'whatwg-fetch'
    import { SimpleElement }  from './simple-element'
    customElements.define("simple-element", SimpleElement);
    let simpleElement;
    window["simpleElement"] = () => simpleElement ? simpleElement : simpleElement = document.getElementById("simple-element");
    //simple-element.ts
    import { html, LitElement } from 'lit';
    import { property, customElement } from 'lit/decorators.js';

    @customElement("simple-element")
    export class SimpleElement extends LitElement {
      private _runMode: String = '';
      
      @property({ type: String })
      get runMode(){
        return this._runMode;
      }

      set runMode(rMode){
        const oldValue = this._runMode;
        this._runMode = rMode;
        this.requestUpdate("disabled", oldValue);
      }

      render() {
        return html`
          <div>
            This is from a simple element with param 
              <h2>${this.runMode}<h2>
          </div>
        `;
      }
    }

Could you please look into the details and provide some feedback to me?

Reproduction

The content should show up as while browsing http://127.0.0.1:8080/ which I can see if I use the old version of @lit\decorators\property.js.

Workaround

No work around, or stick to the old version of lit

Is this a regression?

Yes. This used to work, but now it doesn't.

Affected versions

Failing in 3.1.0, worked in 2.2.5

Browser/OS/Node environment

Browser: Chrome / Edge OS: Windows 10 Node version: 20.10.0 npm version: 10.2.3

SreekumarSekharan avatar Jan 24 '24 11:01 SreekumarSekharan

As noted in the comment in https://stackoverflow.com/q/77865115/19498660 the thing that stands out is the placement of the decorator on the getter rather than the setter.

Based on the error message, it looks like the legacy decorator is being used rather than the standard decorator, despite the babel config.

We're going to need a better reproduction than just a paste of files to be able to help further.

Consider using something like https://stackblitz.com/ or at least a cloneble repository with a command to run and see the error.

augustjk avatar Jan 24 '24 23:01 augustjk

Issue is resolved now! I had to add/change some configurations. I will comment on it once I get some time

SreekumarSekharan avatar Jan 25 '24 11:01 SreekumarSekharan

@SreekumarSekharan Hey! I'm actually just running into this as well, could you share what you did to fix it? Thank you!

IgnacioBecerra avatar Feb 16 '24 02:02 IgnacioBecerra

@SreekumarSekharan Please share what your fix was, having the same issue.

brian-patrick-kyndryl avatar Mar 21 '24 19:03 brian-patrick-kyndryl

If you're using decorators with Babel, see https://lit.dev/docs/components/decorators/#decorators-babel

The Lit 3 upgrade guide's section on standard decorators may also be helpful https://lit.dev/docs/releases/upgrade/#standard-decorator-migration

augustjk avatar Mar 21 '24 20:03 augustjk

I followed the migration guides form lit. It was a pain to get the accessor keyword working. Everything works though up until I remove "experimentalDecorators": true from tsconfig.json.

The strange thing is it loads fine in our Storybook environment (webpack), but we have issues after bundling our npm package with rollup.

Example configs:

tsconfig.json

{
  "compilerOptions": {
    "target": "es2019",
    "module": "es2020",
    "lib": ["es2020", "DOM", "DOM.Iterable"],
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "inlineSources": true,
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    // "experimentalDecorators": true,
    "useDefineForClassFields": false,
    "forceConsistentCasingInFileNames": true,
    "noImplicitOverride": true,
    "typeRoots": ["./node_modules/@types"],
    "plugins": [
      {
        "name": "ts-lit-plugin",
        "strict": true,
        "rules": {
          "no-nullable-attribute-binding": "warn",
          "no-incompatible-type-binding": "warn",
          "no-unknown-attribute": "off",
          "no-unknown-slot": "off"
        }
      }
    ]
  },
  "include": ["src/**/*.ts", "declarations.d.ts"],
  "exclude": ["src/**/*.test.ts"]
}

rollup.config.js

import multiInput from 'rollup-plugin-multi-input';
import resolve from '@rollup/plugin-node-resolve';
import terser from '@rollup/plugin-terser';
import del from 'rollup-plugin-delete';
import typescript from 'rollup-plugin-typescript2';
import babel from '@rollup/plugin-babel';
import renameNodeModules from 'rollup-plugin-rename-node-modules';
import postcss from 'rollup-plugin-postcss';
import litcss from 'rollup-plugin-postcss-lit';
import InlineSvg from 'rollup-plugin-inline-svg';
import copy from 'rollup-plugin-copy';

export default {
  input: ['./src/**/index.ts'],
  output: {
    dir: 'dist',
    format: 'es',
    sourcemap: true,
    preserveModules: true,
    preserveModulesRoot: 'src',
  },
  plugins: [
    del({ targets: 'dist/*' }),
    multiInput.default(),
    resolve({ dedupe: ['@lit/reactive-element', 'lit-html'] }),
    renameNodeModules(),
    copy({
      targets: [
        { src: 'package.json', dest: 'dist' },
        { src: 'README.md', dest: 'dist' },
        { src: 'src/root.css', dest: 'dist' },
        { src: 'src/assets', dest: 'dist' },
        { src: 'src/scss', dest: 'dist' },
      ],
    }),
    InlineSvg(),
    typescript(),
    babel({ extensions: ['.ts'] }),
    postcss({
      inject: false,
    }),
    litcss(),
    terser(),
  ],
};

.babelrc.json

{
  "presets": ["@babel/preset-env", "@babel/preset-typescript"],
  "plugins": [["@babel/plugin-proposal-decorators", { "version": "2023-11" }]]
}

brian-patrick-kyndryl avatar Mar 21 '24 20:03 brian-patrick-kyndryl

I'm not sure if this is how the typescript rollup plugin works but if you're already doing a typescript pass, can't you just keep experimental decorators true and let typescript compile out the decorators? Assuming you're using babel for downleveling/older browser support, only keep @babel/preset-env and don't use @babel/plugin-proposal-decorators. Depending on your tsconfig target, maybe you don't even need to use babel. I guess babel might add in polyfills that TS wouldn't.

augustjk avatar Mar 21 '24 21:03 augustjk

I did originally keep experimental decorators true, and was not using Babel in roll-up at all. It was mainly needed in Storybook/webpack for decorators. I was trying to remove the flag because I was seeing issues with some of our components not behaving correctly, like click events not working, queryAssignedElements variables throwing undefined errors, and some other weird things around reactivity.

For now I have just rolled back to Lit 2.x since I was unable to resolve the weirdness.

brian-patrick-kyndryl avatar Mar 21 '24 21:03 brian-patrick-kyndryl

@brian-patrick-3 for the most part, Lit 3 should be a seamless upgrade from Lit 2. It has very few breaking changes. If you keep experimentalDecorators: true and other tsconfig settings, things should work the same.

Can you share the exact errors you are getting? Event listeners, for instance, shouldn't go through decorators usually, so those failing is odd.

justinfagnani avatar Mar 21 '24 22:03 justinfagnani

I'm pretty sure the issue is related specifically to the rollup config, since the issue only occurred when using our npm package, and was fine in Storybook. For reference, here is what I was dealing with post 3.x upgrade.

Our Accordion component, which we use in our Global Filter pattern, was having some problems.

  1. On load, our query for child accordion-items would throw an undefined error. Other components that use @queryAssignedElements like Button were also throwing undefined errors.
  2. After adding optional chaining ?, it would load, but it was still not updating the children. I'm thinking a slotchange event handler might solve this in particular.
  3. The click functionality to expand collapse individual accordion items, or all at once, was not working at all and throwing no errors.

All of this worked fine in 2.x in both Storybook (webpack) and rollup, but in 3.x our rollup output was giving these issues while Storybook handled it fine.

brian-patrick-kyndryl avatar Mar 22 '24 00:03 brian-patrick-kyndryl

@brian-patrick-3 Do you have the actual errors available? Like stack traces?

justinfagnani avatar Mar 22 '24 19:03 justinfagnani

@brian-patrick-3 Do you have the actual errors available? Like stack traces?

No sorry, I've rolled back so won't be able to get them.

brian-patrick-kyndryl avatar Mar 22 '24 19:03 brian-patrick-kyndryl

i ran into this same issue. it was working with 2.x

proto.constructor.createProperty is not a function
TypeError: proto.constructor.createProperty is not a function
    at legacyProperty (http://localhost:6006/vendors-node_modules_lit_react_development_index_js-node_modules_storybook_addon-essentials_d-40a4fe.iframe.bundle.js:8089:23)
    at http://localhost:6006/vendors-node_modules_lit_react_development_index_js-node_modules_storybook_addon-essentials_d-40a4fe.iframe.bundle.js:8194:15
    at Object.decorateElement (http://localhost:6006/main.iframe.bundle.js:15336:2837)
    at Object.<anonymous> (http://localhost:6006/main.iframe.bundle.js:15336:1693)
    at Array.forEach (<anonymous>)
    at Object.decorateClass (http://localhost:6006/main.iframe.bundle.js:15336:1566)
    at _decorate (http://localhost:6006/main.iframe.bundle.js:15335:308)
    at ./shared/webcomponents/zaptic-checkbox.ts (http://localhost:6006/main.iframe.bundle.js:15361:16)
    at options.factory (http://localhost:6006/runtime~main.iframe.bundle.js:686:31)
    at __webpack_require__ (http://localhost:6006/runtime~main.iframe.bundle.js:28:33)

tsconfig:

        "experimentalDecorators": true,

babelrc

...
  "plugins": [
        ["@babel/plugin-transform-typescript", { "allowDeclareFields": true }],
        ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }],
        ["@babel/plugin-proposal-class-properties"]
    ],
...

laszlo-zaptic avatar May 16 '24 15:05 laszlo-zaptic

@laszlo-zaptic what version of @babel/plugin-transform-typescript are you using?

I believe you'll need v7.24.0 or newer because of https://github.com/babel/babel/issues/16292

You'll also need need to use decorators version 2023-11:

    ["@babel/plugin-proposal-decorators", {"version": "2023-11", "decoratorsBeforeExport": true}],

justinfagnani avatar May 16 '24 15:05 justinfagnani

@laszlo-zaptic what version of @babel/plugin-transform-typescript are you using?

I believe you'll need v7.24.0 or newer because of babel/babel#16292

You'll also need need to use decorators version 2023-11:

    ["@babel/plugin-proposal-decorators", {"version": "2023-11", "decoratorsBeforeExport": true}],

edit: seems to be using SB's babel version

i tried this version saw it in the migration docs but it still wasn't working. the strange thing is that we have the same ts and babel config for our storybook and project but only storybook stopped working. "@babel/plugin-proposal-decorators": "^7.24.1", is used. copying the exact line you suggested i'm getting a new error

ReferenceError: /home/laci/develop/zaptic/shared/webcomponents/zaptic-checkbox.ts: Unknown helper applyDecs2311
    at loadHelper (/home/laci/develop/zaptic/node_modules/@storybook/builder-webpack5/node_modules/@babel/helpers/lib/index.js:179:27)
    at Object.ensure (/home/laci/develop/zaptic/node_modules/@storybook/builder-webpack5/node_modules/@babel/helpers/lib/index.js:236:3)
    at File.addHelper (/home/laci/develop/zaptic/node_modules/@storybook/builder-webpack5/node_modules/@babel/core/lib/transformation/file/file.js:148:15)
    at PluginPass.addHelper (/home/laci/develop/zaptic/node_modules/@storybook/builder-webpack5/node_modules/@babel/core/lib/transformation/plugin-pass.js:31:22)
    at createLocalsAssignment (/home/laci/develop/zaptic/node_modules/@babel/plugin-proposal-decorators/node_modules/@babel/helper-create-class-features-plugin/lib/decorators.js:1039:44)
    at transformClass (/home/laci/develop/zaptic/node_modules/@babel/plugin-proposal-decorators/node_modules/@babel/helper-create-class-features-plugin/lib/decorators.js:974:54)
    at visitClass (/home/laci/develop/zaptic/node_modules/@babel/plugin-proposal-decorators/node_modules/@babel/helper-create-class-features-plugin/lib/decorators.js:1252:21)
    at PluginPass.Class (/home/laci/develop/zaptic/node_modules/@babel/plugin-proposal-decorators/node_modules/@babel/helper-create-class-features-plugin/lib/decorators.js:1284:9)
    at newFn (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/visitors.js:159:14)
    at NodePath._call (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/path/context.js:46:20)
    at NodePath.call (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/path/context.js:36:17)
    at NodePath.visit (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/path/context.js:82:31)
    at TraversalContext.visitQueue (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/context.js:86:16)
    at TraversalContext.visitQueue (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/context.js:91:21)
    at TraversalContext.visitMultiple (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/context.js:61:17)
    at TraversalContext.visit (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/context.js:107:19)
    at traverseNode (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at NodePath.visit (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/path/context.js:88:52)
    at TraversalContext.visitQueue (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/context.js:86:16)
    at TraversalContext.visitSingle (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/context.js:65:19)
    at TraversalContext.visit (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/context.js:109:19)
    at traverseNode (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at traverse (/home/laci/develop/zaptic/node_modules/@babel/traverse/lib/index.js:52:34)
    at transformFile (/home/laci/develop/zaptic/node_modules/@storybook/builder-webpack5/node_modules/@babel/core/lib/transformation/index.js:82:31)
    at transformFile.next (<anonymous>)
    at run (/home/laci/develop/zaptic/node_modules/@storybook/builder-webpack5/node_modules/@babel/core/lib/transformation/index.js:24:12)
    at run.next (<anonymous>)
    at transform (/home/laci/develop/zaptic/node_modules/@storybook/builder-webpack5/node_modules/@babel/core/lib/transform.js:22:33)
    at transform.next (<anonymous>)
    at step (/home/laci/develop/zaptic/node_modules/gensync/index.js:261:32)
    at /home/laci/develop/zaptic/node_modules/gensync/index.js:273:13
    at async.call.result.err.err (/home/laci/develop/zaptic/node_modules/gensync/index.js:223:11)
    ```

laszlo-zaptic avatar May 16 '24 15:05 laszlo-zaptic