Open krbaio3 opened 3 years ago
any updates ? faced the same issue
Facing the same issue in mdx.
Hi @ThibaudAV!
do you need more info?
I started to look at it but several things seem to be misconfigured or suspect in the example repos
Especially here :
https://github.com/krbaio3/sb-lib-issue/blob/master/tsconfig.json#L15 https://github.com/krbaio3/sb-lib-issue/blob/master/stories/Mybutton.stories.ts#L5
the path should match and it should not point to the dist
folder no ?
with
"@css/pattern-lib": ["projects/pattern-lib/src/public-api.ts"]
tsconfig.json
and
import { ButtonComponent } from '@css/pattern-lib';
Mybutton.stories.ts
and with this version of storybook ^6.3.0-beta.10
it works on my side :)
This configuration also seems suspicious to me https://github.com/krbaio3/sb-lib-issue/blob/master/.storybook/tsconfig.json#L2 I wonder if
{
"extends": "../tsconfig.json",
"exclude": [
"../src/test.ts",
"../src/**/*.spec.ts",
"../projects/**/*.spec.ts"
],
"include": ["../src/**/*", "../projects/**/*"],
"files": ["./typings.d.ts"]
}
is not enough. but this does not change the way storybook works
I ran into this same issue. Storybook is not able to find the component annotations in this function. https://github.com/storybookjs/storybook/blob/7064642e1aee7786c77fe735c064c0c29dbcee01/app/angular/src/client/preview/angular-beta/utils/NgComponentAnalyzer.ts#L128
@manbearwiz what Storybook and Angular version are you using?
I can recreate that error with sb6.3.4 + ng11.2.14. I was able to resolve by using sb6.1.21 + ng11.2.14. Haven't yet bisected to determine which specific version between those introduced the bug.
Edit: Confirmed upgrading from sb6.1 to sb6.2.0 recreates the error.
I see a flag was added from sb6.2, angularLegacyRendering
. Tried enabling that but get the same Cannot read property 'selector' of undefined
error.
Hello. The same problem. It seems that angular in aot mode is removing the annotation from the component (maybe that's not the point). Important note - the component is included as a package in node_modules
However, in the component itself, this information is present. I made a simple replacement
var ngComponentMetadata = component.decorators[0].args[0]; //NgComponentAnalyzer_1.getComponentDecoratorMetadata(component);
And its works.
storybook 6.3.4, angular 12.1.1
In addition
Here is class, imported from node_modules/primeng looks like: There is no annotations property, but decorators exist
And here class from "project src" looks like Here annotations property is present
Any idea on which upcoming version will have fix for this issue ?
I would submit a patch from @KondakovArtem observations, but I didn't get past the yarn test
in the Contribution Guide. Maybe because I'm on windows... idk
Anyway, here is an ugly solution if anyone needs a workaround other than accessing the library components directly (not built), which I personally don't like. I want the devs to access components using the built library entry points.
package.json
{
"scripts": {
"build-storybook": "npm run docs:json && build-storybook",
"postinstall": "node postinstall" // <-- add this line
}
}
Create the postinstall script, or add this piece of code if you already have one.
postinstall.js
var fs = require('fs')
// Workaround to fix function getComponentDecoratorMetadata from storybook 6.3.7.
// See https://github.com/storybookjs/storybook/issues/14828.
// TODO: Remove this as soon as issue is solved in a future release.
var file = './node_modules/@storybook/angular/dist/ts3.9/client/preview/angular-beta/utils/NgComponentAnalyzer.js'
fs.readFile(file, 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
var result = data.replace(
' return (decorators || []).find(function (d) { return d instanceof core_1.Component; });',
'if (!decorators) return component.decorators[0].args[0]; return (decorators || []).find(function (d) { return d instanceof core_1.Component; });'
);
fs.writeFile(file, result, 'utf8', function (err) {
if (err) return console.log(err);
});
});
I do recommend you freeze your storybook at 6.3.7 or whatever version your using which doesn't have the fix yet. This might break or break your code in different versions. That replace is working nicely for me.
Good afternoon, Here is my solution to this problem. The script runs before launching the storybook. The script replaces the contents of the NgComponentAnalyzer.js file in and creates a backup nearby. You can compare what has been changed Yes it works on 6.3.7.
Again. this is an ugly solution but it works
"storybook:fix": "ts-node -P tsconfig.gen.json storybook-fix.ts",
import fs from 'fs-extra';
import { resolve } from 'path';
import { createHash } from 'crypto';
const FIX_CONTENT = `"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getComponentDecoratorMetadata = exports.getComponentPropsDecoratorMetadata = exports.isComponent = exports.isDeclarable = exports.getComponentInputsOutputs = void 0;
var core_1 = require("@angular/core");
/**
* Returns component Inputs / Outputs by browsing these properties and decorator
*/
exports.getComponentInputsOutputs = function (component) {
var _a, _b;
var componentMetadata = exports.getComponentDecoratorMetadata(component);
var componentPropsMetadata = exports.getComponentPropsDecoratorMetadata(component);
var initialValue = {
inputs: [],
outputs: [],
};
// Adds the I/O present in @Component metadata
if (componentMetadata && componentMetadata.inputs) {
(_a = initialValue.inputs).push.apply(_a, componentMetadata.inputs.map(function (i) { return ({ propName: i, templateName: i }); }));
}
if (componentMetadata && componentMetadata.outputs) {
(_b = initialValue.outputs).push.apply(_b, componentMetadata.outputs.map(function (i) { return ({ propName: i, templateName: i }); }));
}
if (!componentPropsMetadata) {
return initialValue;
}
// Browses component properties to extract I/O
// Filters properties that have the same name as the one present in the @Component property
return Object.entries(componentPropsMetadata).reduce(function (previousValue, _a) {
var _b, _c;
var propertyName = _a[0], value = _a[1][0];
var valProto = value.prototype || value.__proto__ || {};
if (value instanceof core_1.Input || valProto.ngMetadataName === 'Input') {
var inputToAdd = {
propName: propertyName,
templateName: (_b = value.bindingPropertyName) !== null && _b !== void 0 ? _b : propertyName,
};
var previousInputsFiltered = previousValue.inputs.filter(function (i) { return i.templateName !== propertyName; });
return __assign(__assign({}, previousValue), { inputs: __spreadArrays(previousInputsFiltered, [inputToAdd]) });
}
if (value instanceof core_1.Output || valProto.ngMetadataName === 'Output') {
var outputToAdd = {
propName: propertyName,
templateName: (_c = value.bindingPropertyName) !== null && _c !== void 0 ? _c : propertyName,
};
var previousOutputsFiltered = previousValue.outputs.filter(function (i) { return i.templateName !== propertyName; });
return __assign(__assign({}, previousValue), { outputs: __spreadArrays(previousOutputsFiltered, [outputToAdd]) });
}
return previousValue;
}, initialValue);
};
exports.isDeclarable = function (component) {
if (!component) {
return false;
}
var decoratorKey = '__annotations__';
var decorators = Reflect.getOwnPropertyDescriptor(component, decoratorKey)
? Reflect.getOwnPropertyDescriptor(component, decoratorKey).value
: component[decoratorKey];
return !!(decorators || []).find(function (d) { return d instanceof core_1.Directive || d instanceof core_1.Pipe || d instanceof core_1.Component; });
};
exports.isComponent = function (component) {
if (!component) {
return false;
}
var decoratorKey = '__annotations__';
var decorators = Reflect.getOwnPropertyDescriptor(component, decoratorKey)
? Reflect.getOwnPropertyDescriptor(component, decoratorKey).value
: component[decoratorKey];
return (decorators || []).some(function (d) { return d instanceof core_1.Component; });
};
/**
* Returns all component decorator properties
* is used to get all \`@Input\` and \`@Output\` Decorator
*/
exports.getComponentPropsDecoratorMetadata = function (component) {
var decoratorKey = '__prop__metadata__';
var propsDecorators = Reflect &&
Reflect.getOwnPropertyDescriptor &&
Reflect.getOwnPropertyDescriptor(component, decoratorKey)
? Reflect.getOwnPropertyDescriptor(component, decoratorKey).value
: component[decoratorKey];
if (!propsDecorators) {
var propsDecorators = {};
for (var key in component.propDecorators) {
if (component.propDecorators.hasOwnProperty(key)){
propsDecorators[key] = [component.propDecorators[key][0].type]
}
}
}
return propsDecorators;
};
/**
* Returns component decorator \`@Component\`
*/
exports.getComponentDecoratorMetadata = function (component) {
var decoratorKey = '__annotations__';
var decorators = Reflect &&
Reflect.getOwnPropertyDescriptor &&
Reflect.getOwnPropertyDescriptor(component, decoratorKey)
? Reflect.getOwnPropertyDescriptor(component, decoratorKey).value
: component[decoratorKey];
if (!decorators) {
return component.decorators[0].args[0];
}
return (decorators || []).find(function (d) { return d instanceof core_1.Component; });
};`;
const FIX_FILE = 'NgComponentAnalyzer.js';
const PATH = `node_modules/@storybook/angular/dist/ts3.9/client/preview/angular-beta/utils`;
const CHECK_HASH = ['0be5cd4bed1d63d21a865a14707131ff', 'e0c243b9118ecf34576a8ed5d2f5e238'];
(async () => {
console.log('Start fixing storybook...');
let path = resolve(PATH, FIX_FILE);
if (!fs.existsSync(path)) {
path = resolve('../../', PATH, FIX_FILE);
if (!fs.existsSync(path)) {
throw new Error('Missing fixing file');
}
}
const code = await fs.readFile(path, 'utf-8');
const hash = createHash('md5').update(code).digest('hex');
const fixHash = createHash('md5').update(FIX_CONTENT).digest('hex');
console.log(hash);
if (hash === fixHash) {
console.log('Storybook is already fixed');
return;
}
if (!CHECK_HASH.includes(hash)) {
throw new Error(
`File ${path} was modified by developers. New hash is ${hash}, prev hash ${CHECK_HASH}`,
);
}
console.log('Fixing is done');
await fs.writeFile(`${path}_backup`, code);
await fs.writeFile(path, FIX_CONTENT);
})();
OlΓ©!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.4.0-alpha.32 containing PR #15874 that references this issue. Upgrade today to the @next
NPM tag to try it out!
npx sb upgrade --prerelease
Closing this issue. Please re-open if you think there's still more to do.
Unfortunately I still run into this issue with Storybook 6.4.0-alpha.32, Angular 12 and webpack 5:
Cannot read property 'selector' of undefined TypeError: Cannot read property 'selector' of undefined at Object.push../node_modules/@storybook/angular/dist/ts3.9/client/preview/angular-beta/ComputesTemplateFromComponent.js.exports.computesTemplateFromComponent (http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:101518:30) at prepareMain (http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:102991:52) at http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:102981:39 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:102978:20 at cleanArgsDecorator (http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:103013:12) at http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:102975:30 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:102978:20 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:103050:17 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:100467:21 at http://localhost:6006/vendors-node_modules_storybook_addon-actions_dist_esm_preset_addArgs_js-generated-other-entry-b72747.iframe.bundle.js:102975:30
These are the packages that are installed.
"@storybook/addon-actions": "^6.4.0-alpha.32", "@storybook/addon-essentials": "^6.4.0-alpha.32", "@storybook/addon-links": "^6.4.0-alpha.32", "@storybook/addon-storysource": "^6.4.0-alpha.32", "@storybook/angular": "^6.4.0-alpha.32", "@storybook/builder-webpack5": "^6.4.0-alpha.32", "@storybook/manager-webpack5": "^6.4.0-alpha.32",
I noticed that internally Storybook or angular seems to be using Typescript 3.9 (See first line of stack trace: ...storybook/angular/dist/ts3.9/) while at project level Typescript 4.3.5 seems to be installed. Could this mismatch be a cause of the issue?
Well, the issue was solved for me on Angular 11 LTS. However after suffering a lot with this issue and other issues I realized trying to consume from a compiled library creates LOTS of issues on storybook, so I'd highly recommend against that. This will only make your workflow unnecessarily more complex. So I edited out some private info from the develpment workflow my team will follow and made it generic for you guys.
Notice how we are not consuming from a library when it comes to developing the components on storybook. We are consuming directly from the library source code and webpack does a good job at compliling it for the storybook purposes. Unfortunately I can't share the code, but find me on the Storybook Discord server if you need any help.
Thnx for your reply. We are also running this directly against the source, but no luck with Angular 12.2.2. Previously when we were on Angular 9 with Webpack4 storybook worked correctly.
Also still experiencing issues with our angular library project, Any chance this can be opened again?
@saulodias @ThibaudAV any ideas why the fix didn't work?
So doing tests with a basic component, when loading it into SB directly it works but when loading from the library it does not seem to get the meta data.
Component in SB folder
Component in Libs
Just ran into the issue, the bug is still present in the latest stable release of SB
@wesself coule you provide a reproduction repository ? π I would like to try to make a fix to this issue but I have trouble reproducing it reliably π
You guys will have this and probably other issues if you try to render your library components by pointing to a compiled library. Storybook doesn't work well with that, and like I said, this introduces one unnecessary step to your development workflow. I'm able to reproduce the issue when I import the file directly from the library.
I don't recommend this approach. Please, import your component directly from its source code.
I recommend you create an alias in your root folder tsconfig.json
for your entry points and point them to the entry point public-api
.
{
"compilerOptions": {
"paths": {
"my-lib": ["projects/my-lib/src/public-api"]
}
}
}
If you import your components from "my-lib"
like that you shouln't have this problem.
See: Angular Library + Storybook
I was able to get it loaded with the changes you recommended, thx for this sample @saulodias. Is this the recommended way to load libs into Storybook or should this issue ultimately be fixed?, @ThibaudAV do you still want a copy of my test repo, I would be able to undo the change and send you a broken version.
Thank you very much for you work Saulodias, it has been very helpful! But I don't think this should be closed because it raises a certain number of questions.
Screenshot 1:
Screenshot 2:
That's just so sad in 2021 we still can't even make SB work with Angular
@wesself yes i would like the repo with the broken version. see if i find something. but i don't promise anything ^^
@ThibaudAV here is a sample https://github.com/wesself/storybookLibSample
@wesself didn't you forget to push the .storybook
folder and .gitignore? ^^
If you allow me to add a branch I can open a pull request. After my quick test and adding the missing config the two stories works fine
@ThibaudAV so after cleaning and adding the .stories back was also able to get it working, pushed a new change, not sure what config I have fixed to have this working now. So from me, it's not reproducible now.
Thanks @wesself ! Closing this until we get a reproduction π
I'm having same issue. Did you @krbaio3 or someone else find out what was the problem? Thanks!
My config npm 8.1.1 node v14.18.1 @storybook/addon-actions: 6.3.12 @storybook/addon-essentials: 6.3.12 @storybook/addon-links: 6.3.12 @storybook/angular: 6.3.12
We took some time with @ThibaudAV to investigate the issue and we have come to the conclusion that this issue is environment specific, meaning that it's only reproducible on Windows. Maintainers should investigate with a reproduction. Would you be able to provide one @jakubnovota ?
Otherwise as a 'workaround' you could try to add:
"postinstall": "ngcc"
In your package.json
scripts. I got this issue resolved by tweaking settings around for a while, thanks again to Thibaud.
in that case, shouldn't this be in open state instead of close?
As indicated by @shilman , it's closed until someone makes a reproduction. I haven't been able to reproduce it since it happened sadly
Great Caesar's ghost!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.5.0-alpha.11 containing PR #17156 that references this issue. Upgrade today to the @next
NPM tag to try it out!
npx sb upgrade --prerelease
w00t!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.4.16 containing PR #17156 that references this issue. Upgrade today to the @latest
NPM tag to try it out!
npx sb upgrade
Most definitely reproduces on 6.5.0-alpha.44
- When the component is located outside of the ./stories
directory
I am at Angular 13 with Storoybook 6.4.19 and getting the same error. My stories are outside .stories folder
I'm getting the same error as @anuragpathak21. Angular v13.2
, Storybook v6.4.19
. My components are in an Angular library within an empty workspace. The component stories are outside the .stories
folder.
I'm getting the same error. Angular 12.2
, Storybook 6.4.20
.
In my own case, I was getting that error because I accidentally installed the dependencies inside the library and just having the node_modules folder throws me that error.
I'm getting the same error here: Angular 13.3 Storybook 6.5.5
@shilman There are too many people mentioning that it's still occurring, I think this issue should be re-opened
Hi guys, I'm facing the same error (TypeError: Cannot read properties of null (reading 'selectors')) while I'm not using Storybook, just Angular with some packages, so I think the issue can be related to not just Storybook. My current project uses Angular 13.1.2, and the error occurs with one component during local development.
Hi guys, I'm facing the same error (TypeError: Cannot read properties of null (reading 'selectors')) while I'm not using Storybook, just Angular with some packages, so I think the issue can be related to not just Storybook. My current project uses Angular 13.1.2, and the error occurs with one component during local development.
I had the same problem, downgrading npm version worked for me
Hi, I'm facing the same issue with Angular 15.2.0 and storybook 7.0.6
Facing this issue with Storybook@7.0.7
and Angular@15.x
in an Angular Library project. Is there a reliable workaround for this issue with Storybook 7 yet?
Hi, I am also facing the same issue with Angular 15.2.6 and Storybook 7.0.7 in an Angular Library project. Kindly provide me with some help to resolve this
I'm able to reliably reproduce this. This issue seems to occur when working in an Angular project with multiple projects in the workspace and dependencies being installed in the individual projects (likely due to npm 7 installing peer dependencies by default now). I'm not sure why the peer dependencies being installed causes this, but hopefully this helps narrow in on the root cause.
Steps to reproduce:
ng new my-workspace --no-create-application
cd my-workspace
ng generate library my-lib
npx storybook@next init
npm run storybook
npm install
in the project folder
cd projects/my-lib
npm install
cd ../../
npm run storybook
rm projects/my-lib/node_modules
cd projects/my-lib
npm install --legacy-peer-deps
cd ../../
npm run storybook
TL;DR: short term fix is to remove node_modules from project folders and install dependencies with the --legacy-peer-deps
if necessary
Are there any updates on this since we have repro steps now?
@ThibaudAV can we remove the needs reproduction
tag?
Describe the bug When I generate a component in an angular library (ng11), and I am going to use it in a storybook, it shows me the error of:
Cannot read property 'selector' of undefined.
To Reproduce https://github.com/krbaio3/sb-lib-issue
System System: OS: macOS 11.3.1 CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz Binaries: Node: 15.14.0 - ~/.nvm/versions/node/v15.14.0/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 7.11.2 - ~/.nvm/versions/node/v15.14.0/bin/npm Browsers: Chrome: 90.0.4430.93 Firefox: 88.0 Safari: 14.1 npmPackages: @storybook/addon-actions: ^6.2.9 => 6.2.9 @storybook/addon-essentials: ^6.2.9 => 6.2.9 @storybook/addon-links: ^6.2.9 => 6.2.9 @storybook/angular: ^6.2.9 => 6.2.9
Additional context
Create an angular project:
ng new design-system --create-application=false --prefix=ds --style=scss
Create a angular-lib:
ng generate library pattern-lib --prefix=pl
Change the
name
ofdesign-system/projects/pattern-lib/package.json
to@css/pattern-lib
Change the
path
property ofdesign-system/tsconfig.json
frompattern-lib
to@css/pattern-lib
Generate the component
ng generate component button --project=pattern-lib
My button component is:
Change tsconfig properties of
design-system/projects/pattern-lib/tsconfig.lib.json
. Add this property:Generate the lib dist:
ng build
Init the storybook with
npx -p @storybook/cli sb init --type angular
Generate my custom story:
MyButton.stories.ts
I run:
npm run storybook
If I run with this code, (import { ButtonComponent } from 'projects/pattern-lib/src/public-api';) the storybook works.
But, if I change the import (commented) import { ButtonComponent } from '@css/pattern-lib'; the storybook fails, with the error Cannot read property 'selector' of undefined