TypeScript comes with a useful feature called parameter properties for turning a constructor parameter into a class property with the same name and value. However, for some reason, when using TypeScript with Storybook and Rollup, constructor properties are not transpiled to class properties.
Example code:
my_class.ts
class Params {
constructor(
public property: number
) {}
}
In a development Storybook environment (spun up with yarn storybook
), Params.property
is undefined
and cannot be accessed.
Here are my configuration files:
rollup.config.js
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
const packageJson = require('./package.json');
export default {
input: 'src/index.ts',
output: [
{
file: packageJson.main,
format: 'cjs',
sourcemap: true,
},
{
file: packageJson.module,
format: 'esm',
sourcemap: true,
},
],
plugins: [
peerDepsExternal(),
resolve(),
commonjs(),
typescript({
tsconfig: './tsconfig.json',
}),
],
};
package.json
{
"name": "cursor-ui",
"version": "0.1.0",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.16.0",
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-node-resolve": "^13.0.6",
"@rollup/plugin-typescript": "^8.3.0",
"@storybook/addon-actions": "^6.4.9",
"@storybook/addon-essentials": "^6.4.9",
"@storybook/addon-links": "^6.4.9",
"@storybook/react": "^6.4.9",
"@types/react": "^17.0.35",
"babel-loader": "^8.2.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"rollup": "^2.60.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.31.0",
"styled-components": "^5.3.3",
"themeprovider-storybook": "^1.8.0",
"typescript": "^4.5.2"
},
"peerDependencies": {
"react": "^16.8.0",
"react-dom": "^16.8.0",
"styled-components": ">= 5"
},
"dependencies": {},
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"build": "rollup -c"
},
"main": "lib/index.js",
"module": "lib/index.esm.js",
"types": "lib/index.d.ts",
"files": [
"src",
"lib"
]
}
tsconfig.js
{
"compilerOptions": {
"target": "es5",
"rootDir": "./src",
"outDir": "./lib",
"lib": ["dom", "dom.iterable", "esnext"],
"declaration": true,
"declarationDir": "./",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"downlevelIteration": true
},
"include": ["src"],
"exclude": ["node_modules", "lib"]
}
.storybook/main.js
module.exports = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-links', '@storybook/addon-essentials', 'themeprovider-storybook/register'],
};
As far as I'm aware, Storybook uses webpack under the hood. Is there some configuration that needs changing? Or is the problem caused by something else?
Note: After compiling the library (using yarn build
) the output appears to be correct with the class properties present. The problem only occurs during development.
This issue is caused by a known bug in Storybook. As a workaround, add the following code snippet to .storybook/main.js
:
babel: async options => {
return {
...options,
plugins: options.plugins.filter(x => !(typeof x === 'string' && x.includes('plugin-transform-classes'))),
};
},
Please refer to the linked GitHub issue for more details and explanations.