While upgrading to Lit 3.1.1 from Lit 2.2.5, it gives me the below error while browsing
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
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.
Issue is resolved now! I had to add/change some configurations. I will comment on it once I get some time
@SreekumarSekharan Hey! I'm actually just running into this as well, could you share what you did to fix it? Thank you!
@SreekumarSekharan Please share what your fix was, having the same issue.
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
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" }]]
}
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.
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-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.
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.
- On load, our query for child accordion-items would throw an
undefinederror. Other components that use@queryAssignedElementslike Button were also throwingundefinederrors. - After adding optional chaining
?, it would load, but it was still not updating the children. I'm thinking aslotchangeevent handler might solve this in particular. - 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-3 Do you have the actual errors available? Like stack traces?
@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.
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 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}],
@laszlo-zaptic what version of
@babel/plugin-transform-typescriptare 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)
```