Storybook: Storybookμ—μ„œ μ ˆλŒ€ 경둜둜 κ°€μ Έμ˜¬ 수 μ—†μŠ΅λ‹ˆλ‹€.

에 λ§Œλ“  2018λ…„ 07μ›” 24일  Β·  25μ½”λ©˜νŠΈ  Β·  좜처: storybookjs/storybook

버전

  • @ storybook / addon-actions : 3.4.8
  • @ storybook / addon-links : 3.4.8
  • @ storybook / addon-storyshots : 3.4.8
  • @ storybook / μ• λ“œμ˜¨ : 3.4.8
  • @ storybook / λ°˜μ‘ : 3.4.8
  • λ°˜μ‘ : 16.4.2
  • TypeScript : 2.9.2

행동

λ‹€μŒ ꡬ성 μš”μ†Œλ₯Ό λ§Œλ“€ λ•Œ μŠ€ν† λ¦¬ 뢁에 였λ₯˜κ°€ ν‘œμ‹œλ©λ‹ˆλ‹€.

# src/components/organisms/ParentComponent/index.tsx
import * as React from 'react';
import ChildrenComponent from 'src/components/molecules/ChildrenComponent/index';

const ParentComponent: React.SFC<{}> = ({ ...props }) => (
  <ChildrenComponent />
);

였λ₯˜
Module not found: Error: Can't resolve 'src/components/molecules/ChildrenComponent/index' in '/AppRoot/src/components/organisms/ParentComponent'

이것은 μ ˆλŒ€ κ²½λ‘œλ‘œλ‘œλ“œ ν•œ κ²ƒμœΌλ‘œ λ³΄μ΄λ―€λ‘œ λ‹€μŒμ„ μˆ˜ν–‰ν•˜λ©΄ μ •μƒμ μœΌλ‘œ μž‘λ™ν•©λ‹ˆλ‹€.
import ChildrenComponent from '../../molecules/ChildrenComponent/index';

κ·ΈλŸ¬λ‚˜ κ°€λŠ₯ν•œ ν•œμ΄ 방법을 ν”Όν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. μƒλŒ€ 경둜둜 μ§€μ •ν•˜λŠ” 것 외에 였λ₯˜μ—†μ΄ μŠ€ν† λ¦¬ 뢁을 μ‹œμž‘ν•  μˆ˜μžˆλŠ” 방법이 μ—†μŠ΅λ‹ˆκΉŒ?

μ ˆλŒ€ 경둜의 μ μš©μ€ tsconfig.json 에 λŒ€ν•œ λ‹€μŒ μ„€λͺ…을 κΈ°λ°˜μœΌλ‘œν•©λ‹ˆλ‹€.

"compilerOptions": {
  "outDir": "build/dist",
  "rootDir": "src",
  "baseUrl": "."
}

λ˜ν•œ μ΄λ²ˆμ—λŠ” μŠ€ν† λ¦¬ 뢁에 컴파일 된 build/dist 디렉토리가 μ•„λ‹Œ 컴파일 된 src 디렉토리에 tsx ν™•μž₯자둜 μž‘μ„±λœ stories νŒŒμΌμ„ κ°€μ Έμ˜΅λ‹ˆλ‹€.

./storybook/config 에 μ„€μ •λ˜μ–΄ μžˆμ§€λ§Œ build/dist ν•˜λ©΄ λΉ„μŠ·ν•œ κ²°κ³Όκ°€ μƒμ„±λ©λ‹ˆλ‹€.

이 ν”„λ‘œμ νŠΈλŠ” μ›μž λ””μžμΈμ„ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— λŒ€λž΅ λ‹€μŒκ³Ό 같은 디렉토리 ꡬ쑰λ₯Ό 가지고 μžˆμŠ΅λ‹ˆλ‹€.

β”œβ”€β”€ components
β”‚    β”œβ”€β”€ molecules
β”‚    β”‚   β”œβ”€β”€ ChildrenComponent
β”‚    β”‚   β”‚   β”œβ”€β”€ index.tsx
β”‚    β”‚   β”‚   └── index.stories.tsx
β”‚    β”œβ”€β”€ organisms
β”‚    β”‚   β”œβ”€β”€ ParentComponent
β”‚    β”‚   β”‚   β”œβ”€β”€ index.tsx
β”‚    β”‚   β”‚   └── index.stories.tsx

κ΄€λ ¨ 문제

κ΄€λ ¨ λ¬Έμ œμ™€ 같은 κ²ƒμ΄μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.
κ·ΈλŸ¬λ‚˜ 그것은 해결책에 λ„λ‹¬ν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.

333, # 3438

Digression

이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” λ°λŠ” 두 가지 방법이 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ κ°€μž₯ λ¨Όμ € μš”μ²­ν•˜κ³  싢은 것은 "μŠ€ν† λ¦¬ 뢁으둜 μ ˆλŒ€ 경둜 ꡬ성 μš”μ†Œ κ°€μ Έ 였기"이고, 두 λ²ˆμ§ΈλŠ” κ°€μ Έμ˜¨ tsx νŒŒμΌμ„ μ ˆλŒ€ 경둜둜 κ°€μ Έ μ˜€λŠ” js 파일둜 μ»΄νŒŒμΌν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. μƒλŒ€ 경둜둜. 그런 λ‹€μŒ κ°€μ Έμ˜¨ js νŒŒμΌμ„ μŠ€ν† λ¦¬ 뢁의 μƒλŒ€ κ²½λ‘œμ™€ ν•¨κ»˜ μ μš©ν•©λ‹ˆλ‹€.

ν›„μžμ— κ΄€ν•΄μ„œλŠ” μ—¬κΈ°μ„œμ΄ 문제λ₯Ό λ“£λŠ” 것이 μ μ ˆν•˜μ§€ μ•Šλ‹€κ³  μƒκ°ν•˜μ§€λ§Œ, μ•Œκ³  κ³„μ‹œλ‹€λ©΄ κ·Έ 방법에 λŒ€ν•΄μ„œλ„ 물어보고 μ‹ΆμŠ΅λ‹ˆλ‹€.

μ‹œκ°„ λ‚΄ μ€˜μ„œ κ³ λ§ˆμ›Œ.

react question / support typescript

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λˆ„κ΅°κ°€ 이걸 5 번 λ™ν™”μ±…μœΌλ‘œλ³΄κ³  κ³„μ‹œλ‹€λ©΄

const path = require('path');

module.exports = ({ config }) => {
  config.resolve.modules.push(path.resolve(__dirname, "../src"));
  return config;
};

λͺ¨λ“  25 λŒ“κΈ€

일반 μ•±μ—μ„œ μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ λͺ¨λ₯΄κ² μ§€λ§Œ (섀정은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?), cwd (-> cwd/src/components/.... 라고 κ°€μ •)λ₯Ό resolve.modules λ„£μœΌλ©΄ ν™•μž₯ webpack.config μ—μ„œ μ•„λ§ˆλ„ 문제λ₯Ό ν•΄κ²°ν•  κ²ƒμž…λ‹ˆλ‹€ (λ‚˜λŠ” Angular μ•±μœΌλ‘œ ν™•μΈν–ˆμ§€λ§Œ μ‹€μ œλ‘œλŠ” μ€‘μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€)

λ‚΄ .storybook/webpack.config.js νŒŒμΌμ€ λ‹€μŒκ³Ό 같이 μ„€λͺ…λ©λ‹ˆλ‹€.
여기에 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js');

module.exports = (baseConfig, env) => {
    const config = genDefaultConfig(baseConfig, env);

    config.module.rules.push({
        test: /\.(ts|tsx)?$/,
        exclude: /node_modules/,
        include: [/stories/, /src/],
        loader: 'ts-loader'
    });
    config.resolve.extensions.push('.ts', '.tsx');

    return config;
};

λ‹€μŒκ³Ό 같이 μΆ”κ°€ν•΄λ³΄μ‹­μ‹œμ˜€.

const path = require('path');

// blah blah code

module.exports = (baseConfig, env) => {

  // blah blah code

  config.resolve.modules = [
    ...(config.resolve.modules || []),
    path.resolve('./'),
  ];
}

μ œλŒ€λ‘œ μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€ !!
λ‚˜λŠ” λ‹Ήμ‹ μ—κ²Œ μΆ©λΆ„νžˆ 감사 ν•  수 μ—†λ‹€ !!!!!!!

u-r-welcome

@ igor-dv λΉ„μŠ·ν•œ λ¬Έμ œκ°€ 있으며 κ·€ν•˜μ˜ μ œμ•ˆ (μœ„)κ³Ό resource.request 경둜λ₯Ό μˆ˜μ •ν•˜λŠ” NormalModuleReplacementPlugin을 μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€. λ‘˜ λ‹€ μΌν•˜μ§€ μ•Šμ•˜λ‹€

λ‹€λ₯Έ μ œμ•ˆμ΄ μžˆμŠ΅λ‹ˆκΉŒ?

μ½”λ“œ 예제 / webpack.config.jsλ₯Ό κ³΅μœ ν•΄ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ?

.storybook / webpack.config.js

const path = require ( 'path');`
// const webpack = require ( 'webpack');
const genDefaultConfig = require ( '@ storybook / react / dist / server / config / defaults / webpack.config.js');

module.exports = (baseConfig, env) => {
const config = genDefaultConfig (baseConfig, env);
config.module = {
κ·œμΉ™ : [
{
ν…ŒμŠ€νŠΈ : /.tsx$/,
λ‘œλ” : [ "ts-loader"],
포함 : path.resolve (__ dirname, '../app/xv/')
},
{
ν…ŒμŠ€νŠΈ : /.scss$/,
λ‘œλ” : [
'μŠ€νƒ€μΌ λ‘œλ”',
'css-loader',
'sass-loader? includePaths [] ='+ encodeURIComponent (path.resolve (__ dirname, '../app/'))
]
},
{
ν…ŒμŠ€νŠΈ : /.css$/,
λ‘œλ” : 'style-loader! css-loader'
},
{
ν…ŒμŠ€νŠΈ : /.less$/,
λ‘œλ” : 'style-loader! css-loader! less-loader'
},
{
ν…ŒμŠ€νŠΈ : /.js|.ts$/,
μ œμ™Έ : [path.join (__ dirname, 'app / components'), / node_modules /],
λ‘œλ” : 'ng-annotate-loader'
},
{
ν…ŒμŠ€νŠΈ : /.js$/,
μ œμ™Έ : [path.join (__ dirname, 'app / components'), / node_modules /],
λ‘œλ” : 'babel-loader? presets [] = es2015 & presets [] = stage-1 & presets [] = react & cacheDirectory'
}
]
};

config.resolve.modules = [
    ...(config.resolve.modules || []),
    path.resolve('./'),
];

return config;
// ,
// plugins: [
//     new webpack.NormalModuleReplacementPlugin(/xv/, function(resource) {
//         resource.request = resource.request.includes('xv/') ? '../../app/' + resource.request : resource.request;
//     })
// ]

}`

// μ½”λ“œ

`import * as React from 'react';

'xv / util / decorators'μ—μ„œ {autobind} κ°€μ Έ 였기;

import '../ styles / ActionIcon.scss';`

// 였λ₯˜

`./app/xv/ui/components/ActionIcon.tsx의 였λ₯˜

λͺ¨λ“ˆμ„ 찾을 수 μ—†μŒ : 였λ₯˜ : '/ Users / lukasanderson / workspace / NeXgen-UI / app / xv / ui / components'μ—μ„œ 'xv / util / decorators'λ₯Ό ν•΄κ²°ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

@ ./app/xv/ui/components/ActionIcon.tsx 31 : 0-46
@ ./.storybook/stories/actionIcons.js
@ ./.storybook/config.js
@ multi ./node_modules/@storybook/react/dist/server/config/polyfills.js ./node_modules/@storybook/react/dist/server/config/globals.js (webpack) -hot-middleware / client.js? reload = true ./. storybook / config.js`

/ xv /λŠ” 일반적인 μ›ΉνŒ© 개발 (μŠ€ν† λ¦¬ 뢁이 μ•„λ‹Œ) λΉŒλ“œμ—μ„œ ν”„λ‘œμ νŠΈμ˜ κΈ°λ³Έ (루트 / μ•± / xv / *)에 λ§€ν•‘λ©λ‹ˆλ‹€.

ν˜•μ‹ν™” μ£„μ†‘ν•©λ‹ˆλ‹€

NormalModuleReplacementPlugin으둜 μ •κ·œμ‹ λŒ€μ²΄μ˜ λ‹€μ–‘ν•œ λ³€ν˜•μ„ μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€. μΌλΆ€λŠ” μ ˆλŒ€ 경둜λ₯Ό μ²˜λ¦¬ν•˜μ§€ μ•ŠλŠ” μŠ€ν† λ¦¬ 뢁에 λŒ€ν•œ μœ μ‚¬ν•œ μŠ€λ ˆλ“œ / λ¬Έμ œμ—μ„œ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

예:

plugins: [ new webpack.NormalModuleReplacementPlugin(/xv/, function(resource) { resource.request = resource.request.replace(/xv/, '../../app/'); }) ]

이 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

`./.storybook/stories/actionIcons.js의 였λ₯˜

λͺ¨λ“ˆμ„ 찾을 수 μ—†μŒ : 였λ₯˜ : '/Users/lukasanderson/workspace/NeXgen-UI/.storybook/stories'μ—μ„œ '../../app//ui/components/Tooltip'을 ν•΄κ²°ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

@ ./.storybook/stories/actionIcons.js 5 : 0-47
@ ./.storybook/config.js
@ multi ./node_modules/@storybook/react/dist/server/config/polyfills.js ./node_modules/@storybook/react/dist/server/config/globals.js (webpack) -hot-middleware / client.js? reload = true ./.storybook/config.js
`

이 λ³€κ²½ 사항 (λŒ€μ²΄ λ¬Έμžμ—΄μ— / xv / μΆ”κ°€)

plugins: [ new webpack.NormalModuleReplacementPlugin(/xv/, function(resource) { resource.request = resource.request.replace(/xv/, '../../app/xv/'); }) ]

μ€€λ‹€

`./.storybook/stories/actionIcons.js의 였λ₯˜

λͺ¨λ“ˆμ„ 찾을 수 μ—†μŒ : 였λ₯˜ : '/Users/lukasanderson/workspace/NeXgen-UI/.storybook/stories'μ—μ„œ '../../app/xv//ui/components/Tooltip'을 ν•΄κ²°ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

@ ./.storybook/stories/actionIcons.js 5 : 0-47
`

μ ˆλŒ€ κ²½λ‘œμ— λŒ€ν•œ μ˜¬λ°”λ₯Έ 경둜 λŒ€μ²΄κ°€μžˆμ„ λ•Œ μƒλŒ€ κ²½λ‘œκ°€ 엉망 일뿐만 μ•„λ‹ˆλΌ κ²½λ‘œκ°€ 'μ˜¬λ°”λ₯Έ'것이고 였λ₯˜κ°€ μ§€μ†λ©λ‹ˆλ‹€.

ERROR in ./.storybook/stories/actionIcons.js Module not found: Error: Can't resolve '../../app/xv/ui/components/Tooltip' in '/Users/lukasanderson/workspace/NeXgen-UI/.storybook/stories'

μž‘μ—… 디렉토리 (cwd)λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ?

뿌리/

  • .storybook
  • μ•±
    -xv
    --- ui
    ---- λΆ€ν’ˆ
    --- μœ ν‹Έλ¦¬ν‹°

NeXgen-UI (일λͺ… ν”„λ‘œμ νŠΈ 루트)μ—μ„œ μŠ€ν† λ¦¬ 뢁을 μ‹œμž‘ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ import { autobind } from 'xv/util/decorators'; 있으면 resolve.modules 에 path.resolve('./app') 을 μΆ”κ°€ν•΄μ•Όν•©λ‹ˆλ‹€.

μ’‹μ•„, 이제이게

`
config.resolve = {

    modules: [

        ...(config.resolve.modules || []),

        path.resolve('./app'),

        path.resolve('./')

    ]
};

return config;

`

그리고 같은 것을 μ–»κ³  μžˆμŠ΅λ‹ˆλ‹€.

`./app/xv/ui/components/ActionIcon.tsx의 였λ₯˜

λͺ¨λ“ˆμ„ 찾을 수 μ—†μŒ : 였λ₯˜ : '/ Users / lukasanderson / workspace / NeXgen-UI / app / xv / ui / components'μ—μ„œ 'xv / util / decorators'λ₯Ό ν•΄κ²°ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
`

config.resolve.extensions.push('.ts', '.tsx'); 도 μΆ”κ°€ν•΄μ•Όν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

@ igor-dv λ‚˜λŠ” κ·Έμ—κ²Œλ„ 같은 였λ₯˜λ₯Ό μ£Όμ—ˆλ‹€. 이것에 λŒ€ν•œ 도움을 μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€

πŸ€” 그럼 λ³΅μ œν’ˆμ„ 봐야 ν•  것 κ°™μ•„μš”. 곡용 μ €μž₯μ†Œκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

μ €μ—κ²ŒλŠ” λ‹€μŒκ³Ό 같이 λ‚΄ μ›ΉνŒ© κ΅¬μ„±μ—μ„œ __dirname λ₯Ό path.resolve 에 μΆ”κ°€ν•˜μ—¬ μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€. (μ €λŠ” create-react-app + TypeScript 섀정을 μž‘μ—… μ€‘μž…λ‹ˆλ‹€) :

config.resolve.modules = [
  ...(config.resolve.modules || []),
  path.resolve(__dirname, "../"),
  path.resolve(__dirname, "../src")
];

λ‚΄ 파일 ꡬ쑰, 그에 따라 μ‘°μ • :

```
/뿌리
/.storybook
webpack.config.js
/ src

λ‚΄κ°€ 깨닫지 λͺ»ν•œ 어리석은 점은 resolve.modules ꡬ성에 μ„ ν–‰ ../ λ₯Ό μΆ”κ°€ν•˜λŠ” 것을 μžŠμ—ˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

μ €μ—κ²Œ μ ν•©ν•œ 것은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

// .storybook/webpack.config.js
module.exports = {
  ...,
  resolve: {
    modules: [path.resolve(__dirname, "../src"), "node_modules"],
  }
}

이것은 λ‚΄ μŠ€ν† λ¦¬ 뢁 μ›ΉνŒ© ꡬ성이 κΈ°λ³Έ .storybook λ””λ ‰ν† λ¦¬μ—μ„œ ν•œ 디렉토리 κΉŠμ΄μ— 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

λˆ„κ΅°κ°€ 이걸 5 번 λ™ν™”μ±…μœΌλ‘œλ³΄κ³  κ³„μ‹œλ‹€λ©΄

const path = require('path');

module.exports = ({ config }) => {
  config.resolve.modules.push(path.resolve(__dirname, "../src"));
  return config;
};

당신은 μ•„λ¦„λ‹€μš΄ μ‚¬λžŒ @ kexinlu1121. μ™„λ²½ν•˜κ²Œ μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€. κ°μ‚¬ν•©λ‹ˆλ‹€.

@glocore 의 μ†”λ£¨μ…˜μ€ 그것이 μž‘λ™ν•˜λŠ” 데 ν•„μš”ν•œ νžŒνŠΈμ˜€μŠ΅λ‹ˆλ‹€. 감사!

μ ˆλŒ€ κ°€μ Έ μ˜€κΈ°κ°€ start-storybook μ—μ„œ μž‘λ™ν•˜μ§€λ§Œ λΉŒλ“œ ν•  λ•ŒλŠ” μž‘λ™ν•˜μ§€ μ•ŠλŠ” λΉ„μŠ·ν•œ λ¬Έμ œκ°€μžˆμ—ˆμŠ΅λ‹ˆλ‹€. λˆ„κ΅°κ°€ μ°Έκ³ λ₯Ό μ›ν•˜λ©΄ 여기에 μ°Έκ³  용으둜 λ„£κ² μŠ΅λ‹ˆλ‹€.

μ ˆλŒ€ κ°€μ Έ μ˜€κΈ°μ— @src 을 μ‚¬μš©ν•˜κ³  있으며 λ‹€μŒ 쀄을 μΆ”κ°€ν•˜μ—¬ μž‘λ™ν•˜λ„λ‘ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

# /root/.storybook/webpack.config.js

const path = require("path");

module.exports = ({ config }) => {
  // ...

  // Add absolute path.resolve so storybook can handle absolute import (eg. @src/resources/...)
  config.resolve.alias = {
    ...config.resolve.alias,
    "@src": path.resolve(__dirname, "../src"),
  };

  return config;
};

μ»¨ν…μŠ€νŠΈλ₯Ό μœ„ν•΄ λ‚΄ ν”„λ‘œμ νŠΈ λ””λ ‰ν† λ¦¬λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

/root
  .storybook/
    webpack.config.js
  src/
    components/

λ„μ›€μ΄λ˜κΈ°λ₯Ό λ°”λžλ‹ˆλ‹€ :)

@wzulfikar μ†”λ£¨μ…˜μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€!

CLIλ₯Ό μ‚¬μš©ν•œ 후이 λ¬Έμ œκ°€ λ°œμƒν–ˆμœΌλ©° .storybook / main.jsλ₯Ό λ‹€μŒκ³Ό 같이 μˆ˜μ •ν•˜μ—¬ ν•΄κ²°ν•  μˆ˜μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

const path = require('path');

module.exports = {
  ...other settings....,

  webpackFinal: async (config) => {
    config.resolve.modules = [
      ...(config.resolve.modules || []),
      path.resolve(__dirname, "../src"),
    ];

    return config;
  },

}

μ•ˆλ…•ν•˜μ„Έμš”
React / TSλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
.storybook / main.js와 같은 λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

const path = require('path');

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/preset-create-react-app",
    "@storybook/addon-knobs",
  ],
  webpackFinal: async (config) => {

    config.resolve.alias = {
      ...config.resolve.alias,
      'fs': path.resolve(__dirname, 'fsMock.js'),
      'child_process': path.resolve(__dirname, 'fsMock.js'),
      'net': path.resolve(__dirname, 'fsMock.js'),
      'tls': path.resolve(__dirname, 'fsMock.js'),
      // "src/types": path.resolve(__dirname, "../src/types"),
      // "src/components": path.resolve(__dirname, "../src/components"),
    };

    config.resolve.modules = [
      ...(config.resolve.modules || []),
      path.resolve(__dirname, "../src"),
    ];

    // config.resolve.extensions.push('.ts', '.tsx');

    return config;
  },
}

λ‚΄ ꡬ쑰

.storybook
src
β”œβ”€β”€ components
|     index.ts
β”‚   β”œβ”€β”€ ChildrenComponent
β”‚    β”‚  β”œβ”€β”€ index.tsx
β”‚    β”‚  └── index.stories.tsx
β”‚   β”œβ”€β”€ ParentComponent
β”‚    β”‚    β”œβ”€β”€ index.tsx
β”‚    β”‚    └── index.stories.tsx
β”œβ”€β”€ stories

ParentComponent ꡬ성 μš”μ†Œ

import React from "react";
import { ChildrenComponent } from "src/components";
import { ItemType } from "src/types";

export default ({ item }: { item: ItemType }) => {
  return (
    <p className="hello">
      <ChildrenComponent type={item.type} />
      <span className="ellipsis">{item.title}</span>
    </p>
  );
};

λ¬Έμ œλŠ” src/components μ—μ„œ λΉ„λ‘―λ©λ‹ˆλ‹€. μ™œλƒν•˜λ©΄ μ œκ°€ src/components/ChildrenComponent ν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

λ‚˜λŠ” 그것을 μ΄ν•΄ν•˜μ§€ λͺ»ν•œλ‹€ λ‚˜λŠ” μ—¬κΈ°μ—μ„œ λͺ¨λ“  것을 μ‹œλ„ν–ˆκ³  # 333 # 3291 및 λ‹€λ₯Έ λ§Žμ€

였λ₯˜μ˜ 슀크린 μƒ·
image

λˆ„κ΅¬λ“ μ§€ λ„μšΈ 수 μžˆμŠ΅λ‹ˆκΉŒ?

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰