μ€ν 리λΆμ μ²μ μ¨λ³΄λλ° κ°μ΄λλ₯Ό λ°λΌνκΈ°λ‘ νμ΅λλ€.
μμ μ ν¨κ» μλνλλ‘ ν μ μμ§λ§ λ΄ κ΅¬μ± μμλ₯Ό κ°μ Έμ€μ λ§μ __exportsκ° μ μλμ§ μμ__μ΄ νμλ©λλ€.
_"λΉ λ₯Έ μμ κ°μ΄λ"_ λλ _"λλ¦° μμ κ°μ΄λ(React)"_λ₯Ό μ¬μ©νλ μκ΄μμ΄ νμ λμΌν λμμ΄ λμ§ μλ μ€λ₯κ° λ°μν©λλ€.
μμΆμ΄ μ μλμ§ μμμ΅λλ€
ReferenceError: λ΄λ³΄λ΄κΈ°κ° μ μλμ§ μμμ΅λλ€.
κ°μ²΄μμ.(http://localhost:6006/static/preview.bundle.js:43176:23)
__webpack_require__μμ (http://localhost:6006/static/preview.bundle.js:679:30)
fnμμ (http://localhost:6006/static/preview.bundle.js:89:20)
κ°μ²΄μμ.(http://localhost:6006/static/preview.bundle.js:43132:76)
κ°μ²΄μμ.(http://localhost:6006/static/preview.bundle.js:43142:30)
__webpack_require__μμ (http://localhost:6006/static/preview.bundle.js:679:30)
fnμμ (http://localhost:6006/static/preview.bundle.js:89:20)
loadStoriesμμ (http://localhost:6006/static/preview.bundle.js:40160:3)
ConfigApi._renderMainμμ (http://localhost:6006/static/preview.bundle.js:41134:20)
λ λλ§ μ (http://localhost:6006/static/preview.bundle.js:41092:17)
ConfigApi.configureμμ (http://localhost:6006/static/preview.bundle.js:41117:9)
κ°μ²΄μμ.(http://localhost:6006/static/preview.bundle.js:40164:68)
Object.defineProperty.valueμμ (http://localhost:6006/static/preview.bundle.js:40165:30)
__webpack_require__μμ (http://localhost:6006/static/preview.bundle.js:679:30)
fnμμ (http://localhost:6006/static/preview.bundle.js:89:20)
Object.window.STORYBOOK_REACT_CLASSESμμ (http://localhost:6006/static/preview.bundle.js:38867:18)
__webpack_require__μμ (http://localhost:6006/static/preview.bundle.js:679:30)
http://localhost:6006/static/preview.bundle.js:725:39μμ
http://localhost:6006/static/preview.bundle.js:728:10μμ
κ·Έ μ€λ₯λλ³λ‘ λμμ΄λμ§ μμΌλ©° μ€λ₯λ₯Ό μ‘°ννλ©΄ μλ
λΆν°μ΄ λ¬Έμ κ° ν¨μΉλμλ€κ³ λ§νλ λͺ κ°μ§ λ¬Έμ κ° λνλ©λλ€.
μ€ν 리λΆμ΄ μ’μνμ§ μλ λ°©μμΌλ‘ λ΄λ³΄λ΄λ κ²μ μλ§λ λ΄ κ΅¬μ± μμμΌ κ²μ
λλ€. κ·Έλ¬λ λ΄κ° μ»λ κ²μ __exportsκ° μ μλμ§ μμκΈ° λλ¬Έμ__ (stacktraceμ μλ§κ³Ό ν¨κ») λλ²κ·ΈνκΈ°κ° μ΄λ ΅μ΅λλ€.
λλ typescriptλ₯Ό μ¬μ©νκ³ μμΌλ©° νλ²ν μ€λλ tscλ‘ μ»΄νμΌνκ³ μμ΅λλ€.
//tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"jsx": "react",
"declaration": true,
"sourceMap": true,
"outDir": "./dist",
"esModuleInterop": true
},
"include": [
"./src/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
κ·Έλ° λ€μ μ»΄νμΌλ jsλ₯Ό μ€ν 리λΆμΌλ‘ κ°μ Έμ΅λλ€.
//index.stories.jsx
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { MatrixEffect } from '../dist/index';
storiesOf('MatrixEffect', module)
.add('100x100', () =>
<MatrixEffect height={100} width={100} />
);
@storybook/react
3.4.0@storybook/addon-actions
3.4.0babel-core
6.26.0react
16.3.0λ΄κ° 무μμ λμΉκ³ μμ΅λκΉ?
(λ§μ½ tsλ₯Ό λ°λ‘ κ°μ Έμ¬ μ μλ λ°©λ²μ΄ μλ€λ©΄ λ μ’μ κ²μ
λλ€. κ·Έλ¬λ 곡μμ μΈ λ¬Έμλ₯Ό μ°Ύμ§ λͺ»νκΈ° λλ¬Έμ μ΄κ²μ΄ μ§κΈκΉμ§ μ»μ κ²μ
λλ€)
ν°λ―Έλμμ export 'MatrixEffect' was not found in '../dist/index'
λ₯Ό λ°κ³ μμ΅λλ€. κ·Έλ¬λ μΌλ° λ
Έλ λ°νμμμ λͺ¨λμ κ°μ Έμ¬ μ μμ΅λλ€(μ¬μ©ν μλ μμ§λ§ μ μ΄λ κ°μ Έμ¬ μ μλ€λ κ²μ μκ³ μμ΅λλ€).
μμ§ κ³΅μ λ¬Έμκ° μκΈ° λλ¬Έμ λμμ΄ λ μ μμ΅λλ€. https://github.com/storybooks/storybook/issues/3270
μ΄κ²μ μ¬μ ν ββμλνμ§ μμ΅λλ€ ...
lerna νλ‘μ νΈμμ μμ¬ μμ 곡κ°μ μΌ ν μ€ν 리λΆμμ λμΌν μ€λ₯ λ©μμ§μ ν¨κ» λ¬Έμ κ° λ°μνμ΅λλ€. λλ μ΄κ²μ΄ ν¨ν€μ§ λ‘λ© λ¬Έμ λ‘ μΈν κ²μ΄λΌκ³ μκ°ν©λλ€. μΆκ° μ‘°μ¬ μ€μ λλ€.
κ°μ λ¬Έμ κ° μλ κ² κ°μ΅λλ€.
λ¬Έμ λ₯Ό μ λλ‘ μ΄ν΄νλ€λ©΄ .jsμμ .ts νμΌμ ν΄κ²°νλ λ° λ¬Έμ κ° μμ΅λκΉ? (νμ§λ§ dist
μμ κ΅¬μ± μμλ₯Ό κ°μ Έμ€λ μ΄μ λ₯Ό μ΄ν΄νμ§ λͺ»ν©λλ€.)
νμ₯ μ€ν λ¦¬λΆ webpack.configμ resolve.extensions
μ .ts
/ .tsx
λ₯Ό μΆκ°ν΄μΌ ν κΉμ?
@igor-dv μλμ, JSλ₯Ό μ¬μ©ν©λλ€. μ΄μ¨λ , λ³μ μλ³μ( variable
to Variable
)λ₯Ό λ³κ²½νλ©΄ μ΄λ»κ²λ μλν©λλ€.
TypeScriptλ₯Ό μ¬μ©νμ§ μκ³ λ°λλΌ JSλ§ μ¬μ©νλ μ΄ μ€λ₯κ° λ°μν©λλ€.
.storybook
webpack.config.js
μμ babel loaderλ₯Ό μ κ±°νλλ° μ΄μ μ λλ‘ μλν©λλ€. λλ Typescriptλ₯Ό μ¬μ©νμ§ μμ΅λλ€.
λΈλΌμ°μ μμ exports is not defined
λ₯Ό μ»μμ§λ§ ν°λ―Έλμμ `"export 'default'('[ComponentName]'λ‘ κ°μ Έμ΄)λ₯Ό '@[namespace]/[μμ μ°Ύμ μ μμ΅λλ€. ν¨ν€μ§ μ΄λ¦]'"
project/packages
μ λ€λ₯Έ ν¨ν€μ§μ μ’
μλ λͺ¨λμ κ°μ Έμ€λ €κ³ νλ©΄ μ€λ₯κ° νμλ©λλ€.λ΄λΆ μ’ μμ±μ package.json κΈ°λ³Έ ꡬμ±μ λΉλλμ§ μμ μμ€λ‘ λ³κ²½νλ©΄ λͺ¨λ κ²μ΄ μλν©λλ€.
κ·Έλμ μ€ν 리λΆμ webpack μ€μ μ λ¬Έμ κ° μκ³ cjsλ₯Ό es λͺ¨λ μ½λλ‘ κ°μ Έμ€λ κ², μλλ©΄ λκ° ...
κ·Έλμ λλ μ€μλ‘ λ΄ λΉλμ ES λͺ¨λ λ²μ μ κ°λ¦¬ν€λ package.json "module" νλλ₯Ό μμ νμμ κΉ¨λ¬μμ΅λλ€. λ€μ μΆκ°νλ©΄ λͺ¨λ κ²μ΄ λ€μ μλν©λλ€. μ¬μ ν μ€ν 리λΆμ cjs λ²μ μ λμ΄μ¬ μ μμ κ² κ°μ§λ§ λ΄ λ¬Έμ λ ν΄κ²°λμμ΅λλ€ π€·π½ββοΈ
μ΄κ²μ babel 7.0.0μ΄ μλ v4.0.0-alpha.20μμ μ¬μ ν λ°μν©λλ€.
@tonyλ λ§μ°¬κ°μ§μ λλ€. κ·Έλλ μ λ Flowλ₯Ό μ¬μ©νκ³ μμ΅λλ€.
@ryanflorence μ€ν 리λΆμ λν λμΌν lerna μ€μ κ³Ό λ΄λ³΄λ΄κΈ° λ¬Έμ κ° μμ΅λλ€.
UI μμμ λΉλ λ²μ μ λ
ΈμΆνλ ν¨ν€μ§κ° μμ΅λλ€.
μ£μ‘νμ§λ§ "module" field that pointed to the ES module version of my builds, adding that back in makes everything work again.
λΌκ³ λ§μνμ€ λ λ μμΈν μ 보λ₯Ό μ κ³΅ν΄ μ£Όμκ² μ΅λκΉ?
μ΄ λ¬Έμ λ .babelrc
νμΌμ μ¬λ°λ₯Έ νλ¬κ·ΈμΈμ μΆκ°νμ¬ ν΄κ²°ν μ μμ΅λλ€. tsconfig
νμΌμ commonjs
νΈν λͺ¨λμ μμ±νλλ‘ κ΅¬μ±λμ΄ μμΌλ―λ‘ μ μ ν νλ¬κ·ΈμΈμ μ¬μ©ν΄μΌ ν©λλ€.
{
"env": {
"test": {
"plugins": ["instanbul"]
}
},
"plugins": ["@babel/plugin-syntax-dynamic-import", "@babel/plugin-transform-modules-commonjs"]
}
μ΄κ²μ λ΄ .babelrc
νμΌμ μλ κ²μ΄λ©° λͺ¨λ κ²μ΄ μ μλν©λλ€. μ νν λμΌν μ΅μ
κ³Ό κ°μ κ°μ§ tsconfig
νμΌμ΄ μμ΅λλ€.
"@babel/core"
"^7.1.0"
"@storybook/react"
^4.0.0-μν.2"
"react"
"^16.4.0"
μ°Έκ³ : μ΄ μ루μ μ λ€λ₯Έ μ’ λ₯μ λͺ¨λμμ μλν©λλ€. https://babeljs.io/docs/en/next/plugins#modules
λμκ² μ΄ λ¬Έμ λ 4.0.0.alphaμ babel-loaderλ₯Ό ν¬ν¨νλλ‘ μ΅κ·Ό λ³κ²½λ μ¬νμΌλ‘ μΈν΄ λ°μν©λλ€. κΈ°λ³Έ μλ² μΉν© ꡬμ±μλ commonjs μ»΄νμΌ(ν¨ν€μ§, μμ
곡κ°)μ΄ ν¬ν¨λ μ μμ΅λλ€.
https://github.com/storybooks/storybook/blob/b2b73596f9dd97b4ba8c03340bd36f868e836772/lib/core/src/server/config/utils.js#L3
λλ₯Ό μν΄ μμ μ κΈ°λ³Έ νλ¬κ·ΈμΈ μ μΈμ μ¬μ©μ μ μ webpack.dev.jsλ‘ μ¬μ μνλ κ²μ λλ€.
// exclude 'babel-loader' so we can override it later
...defaultConfig.module.rules.filter(rule => !(
(rule.use && rule.use.length && rule.use.find(({ loader }) => loader === 'babel-loader'))
)),
{
test: /\.jsx?$/,
include: require('path').resolve('./'),
exclude: /(node_modules|dist)/, // exclude any commonjs files
loader: 'babel-loader',
},
include
λ₯Ό μλ΅ν΄λ λ¬Έμ κ° ν΄κ²°λκ³ λΆμμ©μ΄ μμ΅λλ€.
λ¬΄μ¨ μΌμ΄ μΌμ΄λκ³ μλμ§ μ΄ν΄νλ κ² κ°μμ.
@psychobolt κ° λ§νλ κ²μ 100% λ§μ΅λλ€.
monorepo μ¬μ©μλ₯Ό μν΄ λ μ ν μ μλ€κ³ μκ°ν©λλ€. μμ μΌμ΄ λ°μνμ§ μλλ‘ κΈ°λ³Έ webpack ꡬμ±μ λ§λμμμ€.
include: includePaths,
λ₯Ό μ κ±°νλ©΄ λ¬Έμ κ° ν΄κ²°λ κ²μ΄λΌκ³ μκ°νμ§λ§ λ¬Έμ λ μ±λ₯ λΉμ©μ΄ μΌλ§μΈμ§μ
λλ€.
μ΄ λ¬Έμ λ₯Ό κ°μ₯ μ ν΄κ²°νλ λ°©λ²μ λν μ’μ μ μμ΄ μλ μ¬λμ λꡬμ λκΉ?
μ°λ¦¬λ λν μ΄ λ¬Έμ λ₯Ό μ°μ°ν λ°κ²¬νκ³ κ·Έκ²μ΄ 무μμΈμ§ μμλ΄κΈ° μν΄ κ΅¬μ±κ³Ό μΈμ°λ λ° λ°λμ μ΄μμ΄ κ±Έλ Έμ΅λλ€. π’
@cilice μ΄λ»κ² ν΄κ²°νμ ¨λμ?
@0nn0 https://github.com/storybooks/storybook/issues/3346#issuecomment-425516669 μ΄ μ‘°μΈμ λ°λ₯΄μΈμ :)
stotybook-4.1.4, Lerna νλ‘μ νΈ, React 16.7.0, plain JSμ λμΌν λ¬Έμ κ° μμ΅λλ€. Storybook-4.0.12μμ μλ
4.1.4μμ λμΌν μ€λ₯κ° λ°μνμ΅λλ€. 4.0.10μΌλ‘ λμκ° μ μλν©λλ€(νμ μ€ν¬λ¦½νΈ μμ) babel-webapck
μμ λ ꡬμ±μ μ¬μ©νμ¬ babel-loaderμμ μ»΄νμΌλ μΆλ ₯μ μ μΈνλ©΄ μ΅μ μ€ν λ¦¬λΆ ν¨ν€μ§κ° μλ Lerna λλ monorepo νλ‘μ νΈμμ μ΄ λ¬Έμ λ₯Ό νΌν μ μμ΅λλ€.
@psychobolt μμ ꡬμ±μ μ 곡ν μ μμ΅λκΉ? κ°μ¬ ν΄μ.
https://github.com/storybooks/storybook/issues/3346#issuecomment -425516669 μ°Έμ‘°
μ΄κ²μ΄ λ€λ₯Έ μ¬λμκ² λμμ΄ λ μ§ νμ€νμ§ μμ§λ§ λ€μμ μ€ννμ¬ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
npm i react-scripts -D
@skeet λνμ± μ λ©μμ§κ° μλ μ΄μ κ° κΆκΈνμ΄μ
info => Using base config because react-scripts is not installed.
info => Using default webpack setup based on "create-react-app".
info => Using base config because react-scripts is not installed.
λ°λΌμ react-scriptsλ₯Ό μ€μΉν ν λ€μκ³Ό κ°μ΄ νμλ©λλ€.
info => Loading create-react-app config.
info => Using default webpack setup based on "create-react-app".
info => Loading create-react-app config.
μ°λ¦¬λ λν exports is not defined
λ¬Έμ λ₯Ό λͺ λ² κ²ͺμκ³ μ΄μ μ λ€λ₯Έ μ¬λλ€μ΄ μ μν λ°λ²¨ ꡬμ±μ μ¬μ μνμ¬ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
κ·Έλ¬λ μ΅κ·Όμ μ΄κ²μ λ€μ μ‘°μ¬νκΈ° μμνκ³ κΈ°λ³Έ JS κ·μΉμ λν exclude μμ±μ΄ μ λ κ²½λ‘λ‘ νμΈλλ κ²μ νμΈνμ΅λλ€(μλλ μμ±λ Webpack ꡬμ±μ console.log()
μ
λλ€).
{
test: /\.(mjs|jsx?)$/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: '.cache/storybook',
presets: [
[
'@babel/preset-env',
{ shippedProposals: true, useBuiltIns: 'usage' }
],
'@babel/preset-react',
'@babel/preset-flow'
],
plugins: [
'babel-plugin-macros',
'@babel/plugin-proposal-class-properties',
[
'babel-plugin-react-docgen',
{ DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES' }
]
]
}
}
],
include: ['/Users/matt.hinchliffe/Project/'],
exclude: ['/Users/matt.hinchliffe/Project/node_modules']
}
exclude
μμ±μ΄ RegExpμ¬μΌ νλ€κ³ κ°μ νκΈ° λλ¬Έμ μ΄μν΄ λ³΄μμ΅λλ€! μ°λ¦¬ νλ‘μ νΈμ ꡬ쑰 λλ¬Έμ μ€μ λ‘ λ§μ node_modules
ν΄λκ° μλ€λ κ²μ κΉ¨λ¬μμ΅λλ€. κ·Έλμ μ΄ λΌμΈ μ RegExp( /node_modules/
)λ‘ μ
λ°μ΄νΈνλ €κ³ μλνμ΅λλ€. κ·Έλ¦¬κ³ κ·Έκ²μ κ³ μ³€μ΅λλ€!
μ΄κ²μ μ΄λ―Έ νΈλμ€νμΌλ λͺ¨λμ νΈλμ€νμΌνλ κ²μ λ°©μ§νκ³ νΉν preset-envμ useBuiltins
μ΅μ
μ΄ preset-env
core-js
ν΄λ¦¬νμ μ£Όμ
νλ κ²μ λ°©μ§ν©λλ€( useBuiltins
μ΅μ
λλ μ€μ μ κ±° ν΄λ¦¬νμ΄ νμνμ§ μμ λ°νμμ λμμΌλ‘ νλ νκ²½λ μ΄ λ¬Έμ λ₯Ό λ°©μ§νλ λ° λμμ΄ λ μ μμ΅λλ€.)
λ°λΌμ μ΄ λ¬Έμ λ₯Ό μΌμΌν€λ λͺ κ°μ§ λ€λ₯Έ λ¬Έμ κ° μμ΅λλ€.
node_modules
ν΄λμ μ’
μμ±μ Babelμ μν΄ μλμΉ μκ² λ³νλ μ μμ΅λλ€.useBuiltins
μ΅μ
μ λͺ¨λ μ νμ λν΄ μλͺ»λ νμμΌλ‘ core-js
ν΄λ¦¬νμ μ½λμ μ£Όμ
ν μ μμ΅λλ€(https://github.com/babel/babel/issues/7463 λ° https:// μ°Έμ‘°). github.com/babel/babel/issues/9187)λΆννλ κΈ°μ‘΄ μ μΈ μ΅μ μ νμ₯νλ κ²μ μ½μ§ μμ§λ§ κ°λ₯ν©λλ€ !
λλ κ·Έκ²μ νΌνλ λ°©λ²μ λν μ 보μ ν¨κ» μ΄ λ¬Έμ μ λν μΆμλ ν μ€νΈ μΌμ΄μ€λ₯Ό λ§λ€μμ΅λλ€. νμν κ²½μ° Babelμ λ¬Έμ λ₯Ό μ κΈ°ν κ²μ λλ€.
https://github.com/i-like-robots/broken-webpack-bundle-test-case
μ°λ¦¬λ μ€ν λ¦¬λΆ + lerna + typescriptλ₯Ό μ¬μ©νκ³ μμ΅λλ€. μ°λ¦¬λ₯Ό μν΄ ν΄κ²°λ κ²μ @i-like-robotsμ @psychobolt λ₯Ό νΌν©νλ κ²μ΄μμ΅λλ€.
module.exports = (baseConfig, env, config) => {
config.module.rules = config.module.rules.filter(rule => !(
(rule.use && rule.use.length && rule.use.find(({ loader }) => loader === 'babel-loader'))
));
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
sourceType: 'unambiguous',
presets: [['react-app', { flow: false, typescript: true }]],
},
});
config.resolve.extensions.push('.ts', '.tsx');
return config;
};
μ°λ¦¬λ ruκ° κ·Έκ²μ κ³ μΉ λ κ°μ λ¬Έμ κ° μμ΅λκΉ?
μλ‘ μ€μΉν λ μ΄ μ€λ₯κ° λ°μν©λλ€. μμΈμ΄ 무μμΈμ§μ λν λ¨μκ° μμ΅λλ€( create-react-app
μ μ€μ κ³Ό μ΄ μ€μ μ¬μ΄μ .babelrc
μ μΆ©λν κ°λ₯μ±μ΄ μμ΅λκΉ?).
.babelrc
νμΌμ λ€μ μ€μ μΆκ°νμ¬ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
"sourceType": "unambiguous"
μ΄ μ΅μ
μ λν μΆκ° μ 보: https://babeljs.io/docs/en/options#sourcetype
μ΄ μ΅μ
μ Babel 7 μ΄μμμλ§ μ¬μ©ν μ μμ΅λλ€.
μ¬λλ€μ λ¬Έμ κ° λ¬΄μμΈμ§ μμ ν μ΄ν΄νμ§ λͺ»ν μ± μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄(μ£μ‘ν©λλ€!) -- μ¬κΈ°μ μ΄ ββλ¬Έμ λ₯Ό ν΄κ²°νλ λ΄ webpack ꡬμ±μ μ€λν«μ΄ μμ΅λλ€. μλ§λ λ κ°λ¨ν λ°©λ²μΌ κ²μ λλ€.
const babelLoader = storybookBaseConfig.module.rules[0];
babelLoader.exclude.push(
path.resolve('./lib/components/node_modules'),
/* etc */
);
@tmeasday μ μμ λν΄ μμΈν μ€λͺ ν΄ μ£Όμκ² μ΅λκΉ? μ¦, ν΄λΉ μ½λλ₯Ό μ΄λμ λ°°μΉν μ μμ΅λκΉ?
Storybookμ νλ₯νμ§λ§ μ΄ μ€λ₯λ κ°νμ μ΄κ³ λμ°ν©λλ€. μ΄ μ€λ₯κ° λ°μνκΈ° μμνλ μ΄μ μ λν μ΄μ¨μ΄λ μ΄μ λ₯Ό μ°Ύμ§ λͺ»νλ κ² κ°μ΅λλ€. λλ κ΅¬μ± μμλ‘ μλμ νΌμ°κ³ λΆμ μΌμΌν€κ³ λͺ¨λ κ²μ΄ μ€μ λ‘ λ³κ²½λμ§ μκ³ μλνκΈ° μμν©λλ€. κ·Έλ¬λ λλ μ΄κ²μ μλμν€λ €κ³ ν μκ° λμ κ°ν μμκ³ μ΄κ²μ΄ μ κ³ μ₯λ¬λμ§ κ°μ₯ νλ¦Ών μκ°μ΄ μμ΅λλ€.
λ§μ μ¬λλ€μκ² μν₯μ λ―ΈμΉλ κ²μΌλ‘ 보μ΄λ©° μΌμ€ν νΌμΈ μ΄ λ¬Έμ λ₯Ό μ΄ν΄λ³΄μμμ€.
λ€μμ ν¬ν¨νλ .storybook/weback.config.js
νμΌμ λ§λ€μ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
const path = require('path');
// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
// `mode` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
config.module.rules[0].use[0].options.sourceType = "unambiguous";
return config;
};
sourceType
babel λ¬Έμ λ‘ κ·κ²°λλ κ² κ°μ΅λλ€. .babelrc
νμΌμ μΆκ°νλ €κ³ μλνμ§λ§(@0nn0μμ μ μν λλ‘), μ΄λ μ 체 babel ꡬμ±μ μμ νκΈ° 보λ€λ λ체νλ κ²μ²λΌ 보μκ³ , μ΄λ‘ μΈν΄ μΆκ° λ¬Έμ κ° λ°μνμ΅λλ€.
@JasonTheAdams μμμ μμ±ν μ½λ μ‘°κ°μ .storybook/webpack.config.js
μ λ€μ΄κ° κ²μ
λλ€. νμ μΌκ³Ό λΉμ·νλ€κ³ μκ°ν©λλ€.
λ΄κ° μκ°νλ μΌμ λ€μκ³Ό κ°μ΅λλ€.
λ¬Έμ λ νμ νλ‘μ νΈ(μ: ./lib/components/node_modules
) λ΄μ node_modules
νμΌμ΄ babelμ μν΄ μ»΄νμΌλκ³ μλ€λ κ²μ
λλ€. μ΄λ―Έ NPMμΌλ‘ λ°°μ‘λ νμΌμ΄λ©° μ»΄νμΌν νμκ° μμ΅λλ€. μ΄λ€ κ²½μ°μλ babelμ΄ νμΌμ ꡬ문 λΆμνλ λ°©λ²κ³Ό κ΄λ ¨νμ¬ νΌλμ€λ¬μ΄ λ¬Έμ κ° λ°μν μ μμ΅λλ€.
λ΄ μ κ·Ό λ°©μμ node_modules
ν΄λ λ΄μ νμΌμ μ»΄νμΌνμ§ μλλ‘ babel-loader
μ μ§μνλ κ²μ
λλ€. κΈ°λ³Έμ μΌλ‘ ./node_modules
λ₯Ό 무μνλ―λ‘ νμ νλ‘μ νΈμ node_modules
λ΄λΆ λ₯Ό μ»΄νμΌν©λλ€. κ·Έλμ exclude
λͺ©λ‘μ λͺ κ°μ§ κ²½λ‘λ₯Ό μΆκ°ν©λλ€.
λΉμ μ μ κ·Ό λ°©μμ babelμ sourceType
κ°μ§λ₯Ό μ¬μ©νμ¬ νμΌμ ꡬ문 λΆμνλ λ°©λ²μ μλ €μ£Όλλ‘ babel-loader
λ₯Ό ꡬμ±νλ κ²μ
λλ€. μ΄κ²μ κΈ°λ³Έμ μΌλ‘ babelμ μλͺ»λ ꡬ문 λΆμ νμΌμ ν΄κ²°ν©λλ€. κ·Έλ¬λ babelμ μ¬μ ν ββμ»΄νμΌν νμκ° μλ νμΌμμ μ€ν μ€μ΄λ―λ‘ μνλ κ²μΈμ§ λͺ¨λ₯΄κ² μ΅λλ€.
λλ μ λ¬Έκ°κ° μλλ―λ‘ λ΄ λ§μ ν μμ μκΈμΌλ‘ λ°μλ€μ΄μ§ λ§ λΉμ·ν λ¬Έμ λ₯Ό μ€μ€λ‘ ν΄κ²° ν κ²μΌλ‘ μ΄ν΄ν©λλ€.
@skeet μ μ μ(https://github.com/storybooks/storybook/issues/3346#issuecomment-459308703)μ μ μ©ν ν ν ν¨ν€μ§λ₯Ό λͺ κ°μ§ λ€λ₯Έ ν¨ν€μ§μ μ’ μμ±(νΌμ΄ λλ κ°λ°μκ° μλ)μΌλ‘ μ°Έμ‘°νκΈ° μμνμ λ λ¬Έμ κ° λ°νλμμ΅λλ€. .
@ryanflorence μ μμ μ¬ν(https://github.com/storybooks/storybook/issues/3346#issuecomment-415982589)μμμ κ°μ΄ module
νλλ₯Ό μ’
μμ±μ package.json
μ λ£μΌλ©΄ μμ
μ΄ μλ£λμμ΅λλ€.
main: "dist/index.js",
+ module: "dist/index.js",
@tmeasday μμ μ΅λλ€. λλ μ΄ λ¬Έμ μ λν΄ λ¨Έλ¦¬λ₯Ό μΈλ§€κΈ° μμνλ€. κΉλ€λ‘μ΄ μ μ μ μν©μμ μ€μ λ‘ node_modules
μμμ μ»΄νμΌνκΈ°λ₯Ό _do_ νκΈ°λ₯Ό μνλ€λ κ²μ
λλ€. λ°λ‘ κ·Έκ³³μμ κ΅¬μ± μμ μ체λ₯Ό κ°λ°νκ³ λ³λμ ν¨ν€μ§λ‘ μ·¨κΈνκΈ° λλ¬Έμ
λλ€.
@jcousins-ynapμ΄ λ°ν₯ν @skeet μ μ μμ΄ μλ§λ μ¬κΈ°μμ κ°μ₯ μ’μ μ루μ μΌ κ²μ λλ€. μ°λ¦¬λ Storybookμ΄ νμ ν¨ν€μ§κ° μ΄λ»κ² μ²λ¦¬λλμ§(μ¦, node_modules 무μ) κ°μ νλ κ²μ μνμ§ μμ΅λλ€. λκ΅°κ°κ° νμ λͺ¨λ node_modulesκ° μ»΄νμΌλλ κ²μ μνμ§ μμλ€λ©΄ μ²μλΆν° ν¨ν€μ§ μ’ μμ±μ μ€μΉνμ§ μμμ κ²μ λλ€.
μ΄κ²μ λͺ¨λ babel + webpackμ΄ CommonJSμ ES6 λͺ¨λμ μΈμνλ λ₯λ ₯μ λ¬λ € μλ κ² κ°μ΅λλ€. μλ²½νμ§ μμ κ² κ°μ΅λλ€. "module":
νλλ₯Ό νμ ν¨ν€μ§μ package.json
μ μΆκ°νλ©΄ ν¨ν€μ§κ° μ΄μ μ κ·Όνλ κ°μ₯ μμ ν λ°©λ²μΈ ES6 λͺ¨λμ μ¬μ©νλ€λ κ²μ babelμ λͺ
μμ μΌλ‘ μ립λλ€.
κ΄μ¬μ κ°μ Έμ£Όμ μ κ°μ¬ν©λλ€!
μ¬κΈ°μμ μ°¨μνκ³ μΆμ΅λλ€. Storybook 5, Babel 7.4(core-js 3 ν¬ν¨), TypeScript 3.4 λ° monorepo μ¬μ©. μ΄λ¬ν μ μμ λλΆλΆμ 100% μλνμ§ μμμ§λ§ λ΄κ° κΉ¨λ¬μ κ²μ΄ μμμ΅λλ€. monoreposμ λ³Έμ§μ ν¨ν€μ§κ° μμ€ νμΌμ΄ μλ λ€λ₯Έ ν¨ν€μ§μμ "λΉλλ" νμΌμ κ°μ Έμ€λ κ²μ
λλ€. NPM λ μ§μ€νΈλ¦¬/λ
Έλ λͺ¨λ κ³μΈ΅μμλ μ¬μ€μ΄μ§λ§ κ°λ° μ€μλ μλΉν μ±κ°μλλ€. μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ lib/
λ₯Ό src/
λ‘ μ λ¬νλ Webpack λ³μΉμ μ μνμΌλ©° νΉν λͺ¨λ μ½λκ° μ΄μ ESNext/ESMμ΄κΈ° λλ¬Έμ λͺ¨λ κ²μ΄ μ λλ‘ μλνμ΅λλ€.
ν΄νΉμ λ€μκ³Ό κ°μ΅λλ€.
glob.sync(path.join(__dirname, '../packages/*/package.json')).forEach(filePath => {
const { name } = require(filePath);
config.resolve.alias[`${name}$`] = `${name}/src`;
config.resolve.alias[`${name}/lib`] = `${name}/src`;
});
κ·Έλ¦¬κ³ Babel + TSκ° μλνλλ‘ νκΈ° μν΄ μ νλͺ©μ μΆκ°νλ λμ κΈ°μ‘΄ babel-loaderλ₯Ό λ³κ²½νκΈ°λ‘ νμ΅λλ€. λ΄ λ‘컬 Babel ꡬμ±μ Storybookκ³Ό 100% νΈνλμ§ μμ§λ§ μ체 ꡬμ±μ νΈνλκΈ° λλ¬Έμ λλ€.
const babelConfig = config.module.rules[0];
// Replace Flow with TypeScript
babelConfig.test = /\.(j|t)sx?$/;
babelConfig.exclude.push(/node_modules/);
babelConfig.use[0].options.sourceType = 'unambiguous';
babelConfig.use[0].options.presets[2] = require.resolve('@babel/preset-typescript');
babelConfig.use.unshift({ loader: require.resolve('react-docgen-typescript-loader') });
config.resolve.extensions.push('.ts', '.tsx');
module
νλ μ κ±°λ‘ μΈν΄ λμΌν λ¬Έμ κ° λ°μνμ΅λλ€.
μ΄ μ£Όμμ μ€λͺ
λ λλ‘ babel νλ¬κ·ΈμΈμ @babel/plugin-transform-modules-commonjs
λ₯Ό μΆκ°νλ κ²μ΄ λμμ΄ λμμ΅λλ€. https://github.com/storybooks/storybook/issues/3346#issuecomment -423719241
@elado μμ !
μ΄κ²λ μμ ν λ§νμ΅λλ€. μ§λ ~ 2μΌ λμ μ΄ μ€λ λμ λͺ¨λ μ μκ³Ό λ΄ μ μμ λͺ¨λ μλνλ λ° μ€ν¨νμ΅λλ€. μ무λ μ±κ³΅νμ§ λͺ»νμ΅λλ€ π’
κΆκ·Ήμ μΌλ‘ λ€μκ³Ό κ°μ΄ λ¨μ΅λλ€.
WARNING in ./packages/one/src/index.jsx 2:289-293
"export 'default' (imported as 'Two') was not found in '@my-monorepo/two'
@ ./packages/one/src/index.stories.jsx
@ ./packages sync \.stories\.jsx$
@ ./.storybook/config.js
@ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/config.js
...μ€ν 리λΆμ μμν λμ...
index.js:49 ReferenceError: exports is not defined
at react-is.development.js:18
at Module../packages/one/node_modules/react-is/cjs/react-is.development.js (react-is.development.js:226)
at __webpack_require__ (bootstrap:785)
at fn (bootstrap:150)
at Object../packages/one/node_modules/react-is/index.js (index.js:6)
at __webpack_require__ (bootstrap:785)
at fn (bootstrap:150)
at Object../packages/one/node_modules/prop-types/index.js (index.js:9)
at __webpack_require__ (bootstrap:785)
at fn (bootstrap:150)
...μ€ν λ¦¬λΆ ui(http://localhost:9001)λ₯Ό λ³Ό λ. λ΄ μ΄μΌκΈ°κ° λ‘λλμ§ μμ΅λλ€.
fwiw, λ΄ μ€μ μ λ€μκ³Ό κ°μ΅λλ€.
βββ .storybook/
β βββ addons.js
β βββ config.js
β βββ webpack.config.js
β
βββ packages/
β βββ one
β β βββ src/
β β β βββ index.jsx
β β β βββ index.stories.jsx
β β β βββ index.test.jsx
β β βββ dist/
β β β βββ index.js
β β β βββ index.stories.js
β β β βββ index.test.js
β β βββ package.json
β β
β βββ two
β βββ src/
β β βββ index.jsx
β β βββ index.stories.jsx
β β βββ index.test.jsx
β βββ dist/
β β βββ index.js
β β βββ index.stories.js
β β βββ index.test.js
β βββ package.json
β
βββ .babelrc
βββ .eslintrc.js
βββ jest.config.js
βββ lerna.json
βββ npm-shrinkwrap.json
βββ package.json
addons.js
import '@storybook/addon-knobs/register';
import '@storybook/addon-backgrounds/register';
import '@storybook/addon-storysource/register';
config.js
import { configure } from '@storybook/react';
const req = require.context('../packages', true, /.stories.jsx$/);
function loadStories(){
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
μΉν©.config.js
module.exports = {
module: {
rules: [
{
test: /\.stories\.jsx?$/,
loaders: [require.resolve('@storybook/addon-storysource/loader')],
enforce: 'pre'
}
]
}
};
.babelrc
{
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": [
"@babel/plugin-transform-modules-commonjs"
]
}
package.json(루νΈ)
{
"name": "my-monorepo",
"description": "monorepo containing POC react ui component library",
"version": "1.0.0",
"author": "me",
"scripts": {
"postinstall": "npm run bootstrap",
"bootstrap": "lerna bootstrap",
"storybook": "npm run build && start-storybook --port 9001 --config-dir .storybook --ci",
"test": "npm run lint && npm run test:unit",
"test:unit": "npm run build && NODE_ENV=development BABEL_ENV=test jest --no-watchman",
"test:unit:watch": "npm run test:unit -- --watch",
"test:unit:snapshot": "npm run test:unit -- --updateSnapshot",
"lint": "eslint . --ext .js,.jsx --ignore-path .gitignore",
"lint:fix": "npm run lint -- --fix",
"build": "npm run clean && lerna run build",
"clean": "lerna run clean",
"clean:modules": "lerna clean --yes",
"release": "npm run build && lerna publish",
"start": "npm run storybook"
},
"dependencies": {},
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/plugin-transform-modules-commonjs": "^7.5.0",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
"@storybook/addon-backgrounds": "^5.1.9",
"@storybook/addon-knobs": "^5.1.9",
"@storybook/addon-storysource": "^5.1.9",
"@storybook/react": "^5.1.9",
"babel-jest": "^22.4.1",
"babel-loader": "^8.0.6",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.3.5",
"eslint": "^4.18.2",
"eslint-config-particle": "^2.2.1",
"eslint-plugin-react": "^7.14.2",
"jest": "^22.4.2",
"jest-styled-components": "^6.3.3",
"lerna": "^3.15.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"styled-components": "^4.3.2"
}
}
package.json(νλ)
{
"name": "@my-monorepo/one",
"description": "react component one",
"version": "1.1.0",
"author": "me",
"main": "dist/index.js",
"scripts": {
"test": "cd ../../ && npm test",
"build": "babel ./src --out-dir ./dist --ignore test.jsx,stories.jsx --config-file ../../.babelrc",
"clean": "rm -rf ./dist"
},
"peerDependencies": {
"react": ">=15",
"styled-components": ">=3"
},
"dependencies": {
"@my-monorepo/two": "^1.1.0",
"create-react-class": "^15.6.3",
"prop-types": "^15.7.2"
}
}
package.json(2κ°)
{
"name": "@my-monorepo/two",
"description": "react component two",
"version": "1.1.0",
"author": "me",
"main": "dist/index.js",
"scripts": {
"test": "cd ../../ && npm test",
"build": "babel ./src --out-dir ./dist --ignore test.jsx,stories.jsx --config-file ../../.babelrc",
"clean": "rm -rf ./dist"
},
"peerDependencies": {
"react": ">=15"
},
"dependencies": {
"create-react-class": "^15.6.3",
"prop-types": "^15.7.2"
}
}
κ΅¬μ± μμμ ./src
λλ ν 리 λ΄μ λͺ¨λ νλͺ©μ ESM μ€νμΌ κ°μ Έμ€κΈ°/λ΄λ³΄λ΄κΈ°λ₯Ό μ¬μ©ν©λλ€. @my-monorepo/one
λ @my-monorepo/two
μ λ°λΌ λ€λ¦
λλ€. μ€μΉ μ lerna _links_ μ’
μμ±( lerna bootstrap
μ ν΅ν΄). λͺ¨λ ν¨ν€μ§λ babelμ μ¬μ©νμ¬ λΉλλ©λλ€. μ΅μμ npm run build
λͺ
λ Ήμ κ°λ³ ./dist
λλ ν 리μ κ·Έ λ΄μ©μ μμ±ν©λλ€. npm start
λ λ¨Όμ κ΅¬μ± μμλ₯Ό λΉλν λ€μ μ€ν 리λΆμ μμν©λλ€.
v3μμλ μ΄ λͺ¨λ κ²μ΄ μ μλνμ§λ§ κ΅¬μ± μμλ₯Ό λ¨Όμ λΉλν΄μΌ νλ κ²μ΄ νμ μ½κ° μ΄μνκ² λκ»΄μ‘μ΅λλ€. κ·Έλλ _μ΄μ λ - package.json
κ° "main: "dist/index.js"
λ₯Ό ν¬ν¨νλ―λ‘ μ€ν 리λΆμ΄ μμΌλ©΄ λΉλλ₯Ό μλν λ @my-monorepo/two
λ₯Ό μ°Ύμ μ μλ€κ³ λ³΄κ³ ν κ²μ
λλ€( @my-monorepon/one
μ λ°λΌ λ€λ¦ κ·Έ μμ). κ·Έλ¬λ κ·Έλ μ§ μμΌλ©΄ μ€μ μ λ§μ‘±νμ΅λλ€.
λ΄κ° μμ μ°¨λ¦° ν κ°μ§ : κ΅¬μ± μμμ package.json
νμΌμ "module": "src/index.jsx"
λ₯Ό μΆκ°νμ λ webpack κ²½κ³ λ μ κ±°λμμ§λ§ ν΄λΌμ΄μΈνΈ μΈ‘ ReferenceError: exports is not defined
μ λ¨μ μμμ΅λλ€. λμΌν μ€λ₯λ₯Ό λ³΄κ³ νμ§λ§ ν΄κ²° λ°©λ²μ΄ μλ μ¬λμ μ°Ύμμ΅λλ€.
μ§κΈμ μ€ν λ¦¬λΆ v3λ₯Ό κ³μ μ¬μ©νκ² μ§λ§ μ΄ μ€λ λλ₯Ό κ³μ μ£Όμνκ³ κΈ°κΊΌμ΄ μ μμ μλν κ²μ λλ€ :pray::+1:
@busticated λ λ΄κ° λ³Ό μ μλ 곡μ ν μ μλ 볡μ μ μ₯μκ° μλ κ²μ²λΌ λ€λ¦½λλ€.
@ndelangen μ΄ν΄λ΄ μ£Όμ μ κ°μ¬ν©λλ€ :κΈ°λ: λΆννλ λ΄ μ μ₯μλ κ³΅κ° atmμ΄ μλλλ€. μμ κ΄λ ¨ μΈλΆ μ 보λ₯Ό 곡μ νλ €κ³ νμ§λ§ κ·Έ λμ λμμ΄ λλ κ²½μ° μμ μμ λ₯Ό μμ±νλ €κ³ ν μ μμ΅λλ€. μ‘°κΈ κ±Έλ¦΄ μ μμ΅λλ€. κ·Έλ μ§ μμΌλ©΄ μ μ λ±μ μλνκ² λμ΄ κΈ°μ©λλ€.
@busticated λλ monorepo-repro-repoλ₯Ό μ΄ν΄λ³΄λ κ²μ κΈ°μκ² μκ°ν©λλ€ π
λ€μκ³Ό κ°μ κ°λ₯μ±μ΄ μμ΅λλ€.
λΆννλ ReferenceError: exports is not defined
λ μ°λ¦¬μκ² λ€λ₯Έ κ²μ μλ €μ£Όμ§ μμ΅λλ€. 무μΈκ°κ° μλλλ‘κ° μλλλ€.
@ndelangen ok, μ¬κΈ° μ¬ν λ ν¬κ° μμ΅λλ€ π
https://github.com/busticated/storybook-monorepo-repo
κ°λ¨νκ² λ€μμ μνν μ μμ΄μΌ ν©λλ€.
git clone
npm i && npm start
...κ·Έλ¦¬κ³ λΈλΌμ°μ μμ λ‘λνλ €λ μ€ν 리λΆμ 보μμμ€. κ°λ° λꡬ μ½μμ μ΄λ©΄ exports
μ€λ₯κ° νμλ©λλ€.
λͺ κ°μ§ λ©λͺ¨:
npm run build
λ₯Ό μ€ννμ¬ μ¬μ κ²μ λΉλλ₯Ό ν
μ€νΈν©λλ€.npm@5
λ²μ μμ μλν΄μΌ ν©λλ€ node@8
+/- μΌλΆ μ κΈ νμΌ λ
Έμ΄μ¦"module": "src/index.jsx"
νλλ₯Ό packages/*/packge.json
νμΌμ μΆκ°ν©λλ€. λλ리면 μλ export 'default' (imported as 'Two') was not found
webpack κ²½κ³ κ° νμλ©λλ€.μ΅λν 빨리 보λλ‘ ν κ²μ
μ λ Lernaλ₯Ό μ¬μ©νκ³ μμΌλ©° λ΄λΆ ν¨ν€μ§λ libraryTarget: 'commonjs2'
μΆλ ₯κ³Ό ν¨κ» Webpackμ μν΄ λ²λ€λ‘ μ 곡λ©λλ€. @JasonTheAdams μ견μ κΈ°λ°μΌλ‘ ν μ κ·Ό λ°©μμ΄ μ μκ² ν¨κ³Όμ μ
λλ€. λλ λν babelrc { "sourceType": "unambiguous" }
λ₯Ό μ¬μ©νμ¬ @0nn0 μ루μ
μ ν
μ€νΈνμΌλ©° λν μλνμ§λ§ ν¨ν€μ§ 루νΈμ .babelrc
κ° μμ΄μΌ ν©λλ€.
λͺ κ°μ§ κΈ°λ³Έ μ€μ - λκ΅°κ°μκ² λμμ΄ λ μλ μμ΅λλ€ π(Storybook: 5.1.10, Lerna: 3.16.4, Webpack: 4.39.1, Babel: 7.5.5)
νμΌ: _lerna_repo/.storybook/webpack.config.js_ - κΈ°λ³Έμ μΌλ‘ μ‘΄μ¬νμ§ μμ΅λλ€.
module.exports = async ({ config }) => {
const [ mjsjsx ] = config.module.rules;
const [ babelLoader ] = mjsjsx.use;
babelLoader.options.sourceType = 'unambiguous'
return config;
};
νμΌ: _lerna_repo/stories/index.stories.js_
import defaultExport, { namedExport } from '../packages/examplePackage' // works locally
// import defaultExport, { namedExport } from '<strong i="17">@examplePackage</strong>' // works installed
...
νμΌ: _lerna_repo/packages/examplePackage/package.json_
"name": "@examplePackage",
"version": "0.0.1",
"main": "./dist/index.js"
...
νμΌ: _lerna_repo/packages/examplePackage/dist/index.js_ - Webpackμμ μμ±
module.exports=function(e){var n={};function...
@ndelangen μμ μ λ°μ΄νΈκ° μμ΅λκΉ?
CommonJS μ€νμΌ λͺ¨λμ "κ°μ Έμ€κΈ°"νλ €κ³ ν λ "λ΄λ³΄λ΄κΈ°κ° μ μλμ§ μμμ΅λλ€" μ€λ₯κ° λ°μνμ΅λλ€. λ€λ₯Έ μ¬λλ€μ΄ μ μν λλ‘ Babel sourceType μ΅μ μ "unambiguous"λ‘ μ€μ νλ©΄ νΈλ¦μ μννμ΅λλ€.
μ΄κ²μ μ€μ λ‘ Storybookμ λ¬Έμ κ° μλλ©° λ κ°μ§ λͺ¨λ μ¬μμ μ€κ°μ κ°ν κ²°κ³Όμ λλ€.
λ²μ 5.2μμ μμ λ κ² κ°μ΅λλ€.
μλ νμΈμ μ¬λ¬λΆ, μ€μ λ‘ μμ λμμ΅λκΉ?
5.2.1
λ₯Ό μ¬μ©νκ³ μμΌλ©° μλ‘ μμ±λ Lerna monorepo
μ μ΄ λ¬Έμ κ° μμ΅λλ€.
μ κ²½μ°μλ λ€μκ³Ό κ°μ΅λλ€. https://github.com/storybookjs/storybook/issues/3346#issuecomment -475437230
Babel
μ»΄νμΌμμ "Lerna" packages
μ node_modules
Storybook Webpack config
λ₯Ό μμ νμ΅λλ€. νμ§λ§ λ¬Έμ λ μ¬μ ν μλ€κ³ μκ°ν©λλ€.
@idbartosz λ μ λκΈμ λ°λΌ λ¬Έμ λ«μμ΅λλ€. @Lighttree κ° μ¬μ ν κ³ μ₯λ κ² κ°μ΅λκΉ?
νΌλμ λλ € μ£μ‘ν©λλ€. νμν ν¨ν€μ§κ° 루νΈλ‘ νΈμ΄μ€νΈλμ΄ κ±°κΈ°μ dev μ’
μμ±μΌλ‘ μ€μΉλλ Lerna ꡬμ±μ λν λ΅λ³μ κΈ°λ°μΌλ‘ νμ΅λλ€. λ°λΌμ node_modules
ꡬ문 λΆμ λ¬Έμ κ° λ°μνμ§ μμμ΅λλ€.
μΌλΆ μ¬μ©μλ /lib/components/node_modules
https://github.com/storybookjs/storybook/issues/3346#issuecomment -475437230κ³Ό κ°μ νΈλ¦¬ κΉμμ΄ ν¨ν€μ§λ₯Ό μ€μΉνκ³ babel-loaderκ° λ€μμ μλνλ μ¬μ© μ¬λ‘λ₯Ό κ°μ§κ³ μλ κ² κ°μ΅λλ€. κ·Έλ€μ ꡬ문 λΆμν©λλ€.
κΈ°λ³Έμ μΌλ‘ μ€ν 리λΆμ λ£¨νΈ node_modules
λ₯Ό μ μΈνμ§λ§ λͺ¨λ μ μΈνλ κ²μ΄ μ’μ΅λλ€.
@shilman μ λ react-motion
in lerna
mono-repo μ μ₯μμμ μ΄ μ€λ₯μ μ§λ©΄νκ³ μμ΅λλ€.
@idbartosz μ루μ
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λκΉ?
@sayjeyhi μ, κ·ΈλμΌ ν©λλ€. μ΄κ²μ μ€μ λ‘ Storybook
λ¬Έμ κ° μλλλ€. μ΄κ²μ monorepo
μμ μμ
ν λ νλ‘μ νΈ λ£¨νΈλΏλ§ μλλΌ */packages
μλ $#$ node_modules
$#$κ° μκΈ° λλ¬Έμ λ°μνλ©° κΈ°λ³Έμ μΌλ‘ μ μΈλμ§ μμ΅λλ€. (μ€μ λ‘λ monorepo
μ‘°μ§μ λ°λΌ λ€λ₯΄κΈ° λλ¬Έμ κ·Έλ κ² ν΄μλ μ λλ€κ³ νμ νμ§ λͺ»ν©λλ€. Lerna packages
ν΄λμ Storybook
λ₯Ό package
λ‘ μμ±νλ©΄ μ΄κ²Όμ΅λλ€. μ΄ λ¬Έμ κ° μμ΅λλ€)
κ·Έλμ μ κ²½μ°μλ .storybook/webpack.config.js
μμ μ΄κ²μ νμ΅λλ€.
const path = require('path');
const glob = require('glob');
// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
// `mode` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Make whatever fine-grained changes you need
const babelLoader = config.module.rules[0];
/**
* Exclude pacakge's `node_modules` from Storybook babel processing.
*/
glob.sync('./packages/*/node_modules').forEach(match => {
babelLoader.exclude.push(path.resolve(match));
});
// Return the altered config
return config;
};
λ΄κ° λ§λ μμ μ¬ν μμ μ μλ ν΄κ²° λ°©λ²μ μ€μ λ‘ λ³΄μ¬μ€ μ¬λμ΄ μμ΅λκΉ?
https://github.com/storybookjs/storybook/issues/3346#issuecomment -514324312
μ§λ¬Έμ νμ€ν λ΅μ΄ λ κ² κ°μ΅λλ€.
monorepo
νλ‘μ νΈκ° μλ λλΆλΆμ λͺ¨λ μ¬λλ€μ΄ lerna
λ₯Ό μ¬μ©νκ³ μμμ μ μ μμ΅λλ€. lerna
λμ yarn workspaces
λ₯Ό μ¬μ©νλ monorepo
νλ‘μ νΈκ° μμ΅λλ€. lerna
λ° λͺ¨λ κ²μ΄ μ΅μ λ²μ μ storybook + typescript
μμ μ μλνκ³ μ΄μν webpack
κ΅¬μ± μμ΄ babelμμλ μ μλν΄μΌ ν©λλ€.
μ½κ°μ κ΄μ¬μ 보μ΄λ©΄ monorepo
λ₯Ό storybook
λ‘ λ§λ€ μ μμ΅λλ€. @busticated μ νμΌμμ μΌλΆ μ€ν¬λ¦½νΈκ° μλͺ»λ μμλ‘ μ€νλκ³ μΌλΆ μ’
μμ±μ΄ μλͺ»λ package.json
, μ΄κ²μ΄ λ¬Έμ λ₯Ό μΌμΌν€λ κ²μ μλμ§λ§ λ¬Έμ κ° λ μ μμ΅λλ€.
@pixelate
@busticated μ νμΌμμ μΌλΆ μ€ν¬λ¦½νΈκ° μλͺ»λ μμλ‘ μ€νλκ³ μΌλΆ μ’ μμ±μ΄ μλͺ»λ package.jsonμ μμμ λ³Ό μ μμ΅λλ€.
λ μμΈνκ² μκΈ°ν΄ μ£Ό μκ² μ΄μ?
λν https://github.com/storybookjs/storybook/issues/3346#issuecomment -513397002μ μΈκΈλ λλ‘ μ€ν λ¦¬λΆ v3
μ μ€ννλ μμ 리ν¬μ§ν 리μ _working_ λ²μ μ΄ μμμ λͺ
μ¬νμμμ€.
@pixelateate μμ 리ν¬μ§ν 리λ₯Ό 곡μ νμκ² μ΅λκΉ?
monorepo
νλ‘μ νΈκ° μλ λλΆλΆμ λͺ¨λ μ¬λλ€μ΄lerna
λ₯Ό μ¬μ©νκ³ μμμ μ μ μμ΅λλ€.lerna
λμyarn workspaces
λ₯Ό μ¬μ©νλmonorepo
νλ‘μ νΈκ° μμ΅λλ€.lerna
λ° λͺ¨λ κ²μ΄ μ΅μ λ²μ μstorybook + typescript
μμ μ μλνκ³ μ΄μνwebpack
κ΅¬μ± μμ΄ babelμμλ μ μλν΄μΌ ν©λλ€.κ΄μ¬μ 보μ΄λ©΄
monorepo
λ₯Όstorybook
λ‘ λ§λ€ μ μμ΅λλ€. @busticated μ νμΌμμ μΌλΆ μ€ν¬λ¦½νΈκ° μλͺ»λ μμλ‘ μ€νλκ³ μΌλΆ@ μ’ μμ±μ΄ μμμ μ μ μμ΅λλ€. μλͺ»λpackage.json
μμ λ¬Έμ λ₯Ό μΌμΌν€λ κ²μ μλμ§λ§ λ¬Έμ κ° λ μ μμ΅λλ€.
babelConfig.exclude.push(/node_modules/);
λ start-storybook
μ€νν λ λ¬Έμ λ₯Ό ν΄κ²°νμ§λ§ build-storybook
μμ μΆλ ₯μ μ€νν λ λμΌν exports is not defined
μ€λ₯κ° λ°μν©λλ€.
νΈμ§: storybook-addon-jsx
μ κ±°νμ¬ ν΄κ²°λμμ΅λλ€.
@busticated μμ μΌλ‘ PRμ μ΄μμ΅λλ€.
https://github.com/busticated/storybook-monorepo-repo/pull/1
λ΄κ° μκ°νλ μ£Όμ λ¬Έμ μΈ λͺ κ°μ§ μλͺ»λ μμ νμ΄ μμμ΅λλ€.
@jacobrask μ€ν 리λΆμ ν΅μ¬μμ λ³κ²½νκ³ μΆμ΅λλ€. νμ§λ§ λ§μ΄λ 릴리μ€μμ λ³κ²½νλ©΄ ν° νΌν΄λ₯Ό μ νκΉ λλ ΅μ΅λλ€.
@shilman λ°κΏμΌ νλ€κ³ μκ°νμ§λ§ λ©μ΄μ λ²μ μΆ©λμ΄μ΄μΌ ν©λλ€.
@ndelangen
μμ μΌλ‘ PRμ μ΄μμ΅λλ€.
κ°μ¬ ν΄μ!
λ΄κ° μκ°νλ μ£Όμ λ¬Έμ μΈ λͺ κ°μ§ μλͺ»λ κ°μ Έμ€κΈ°κ° μμμ΅λλ€.
ν . μ. eslint
λ₯Ό μ€μ νμ§ μμ κ²μ΄ μ³μ΅λλ€ ππ€¦ββ
μ¦, μΌλ¨ μλͺ»λ λ³μ μ΄λ¦μ μ€λͺ
νκ³ @storybook/addon-backgrounds
μ¬μ©λ²μ μ
λ°μ΄νΈν κ² κ°μ΅λλ€. master
( 1 , 2 , 3 , 4 )μ λν΄ μνν κ²μ²λΌ - μ μΌνκ² λμ λλ λ³κ²½ μ¬νμ μ€μ μ¬μ©ν©λλ€.
λ λ§μ?
νΈμ§: μ¬κΈ°μ yarn
μ νμν λ³κ²½ μ¬νλ§ ν¬ν¨λ μ 리λ λΆκΈ°κ° μμ΅λλ€. π https://github.com/busticated/storybook-monorepo-repo/commit/4fb2cac0f05b65a5983f121b92a7c2d7438d8857
μμ¬ μμ 곡κ°μ 루νΈμ λν λͺ¨λ μ’ μμ±μ λμ΄μ¬λ € μλ§μ λ¬Έμ λ₯Ό ν΄κ²°ν κ²μ λλ€.
λ΄ PRμμ https://github.com/storybookjs/storybook/pull/8822 κΈ°λ³Έμ μΌλ‘ MULTIPLE node_modules ν΄λ μ μΈλ₯Ό μ§μνλλ‘ μ€ν 리λΆμ λ³κ²½ν©λλ€.
κ±°κΈ°μ μμΈν μ€λͺ λμ΄ μλ―μ΄ μ λ λ§μ΄λ 릴리μ€μμ ν΄λΉ λ³κ²½ μ¬νμ λ‘€λ§νλ κ²μ΄ λ§€μ° λλ ΅κ³ @shilmanλ λ§μ°¬κ°μ§μ λλ€. 6.0κΉμ§ μ μ§νλ κ²μ΄ μ’μ΅λλ€.
μμ¬ μμ 곡κ°μ 루νΈμ λν λͺ¨λ μ’ μμ±μ λμ΄μ¬λ € μλ§μ λ¬Έμ λ₯Ό ν΄κ²°ν κ²μ λλ€.
μμ¬λ₯Ό μ¬μ©νλ€κ³ κ°μ νλ©΄ π
κΈ°λ³Έμ μΌλ‘ MULTIPLE node_modules ν΄λ μ μΈλ₯Ό μ§μνλλ‘ μ€ν λ¦¬λΆ λ³κ²½
κ·Έκ²μ΄ κ·Όλ³Έ μμΈμΈκ°? λ³κ²½ μ¬νμ λ‘μ»¬λ‘ μ μ©ν΄λ λ¬Έμ κ° ν΄κ²°λμ§ μλ κ² κ°μ΅λλ€.
λ΄ λΈλΌμ°μ μ μ½μμ λ€μμ΄ νμλ©λλ€.
TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
...μ΄λκ² μ’ λ€λ₯Έ κ² κ°μλ°..? νμ λ³Ό μ μμ§λ§ νμ λ€λ₯Έ μ루μ μ΄ μλ λ λ€λ₯Έ μ€λ₯ π€¦ββ _/babelκ³Ό webpackμ μΌλ°μ μΈ λ°©ν₯μ λν΄ λμ΄μ μ°νΈλ¦½λλ€_ π¬
λλ λ§μ΄λ 릴리μ€μμ κ·Έ λ³κ²½ μ¬νμ λ‘€μμνλ κ²μ΄ λ§€μ° λλ ΅κ³ @shilmanλ λ§μ°¬κ°μ§μ λλ€. 6.0κΉμ§ μ μ§νλ κ²μ΄ μ’μ΅λλ€.
μ€ μ, λΉμ μ λ§μ λ£μ΅λλ€. μ΄ λͺ¨λ κ²μ κ²°μ½ μ¬μ΄ μΌμ΄ μλλλ€. μ¬κΈ°μ λ€λ₯Έ κ³³μμ λΉμ μ΄ νλ λͺ¨λ μΌμ λν΄ λλ¨ν κ°μ¬ν©λλ€ - Storybook(μ¬μ§μ΄ v3)μ λλλλ‘ μ μ©ν λꡬμ λλ€ :pray::clap::clap::clap::+1:
TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
μ΄κ²μ Webpackμ΄ CommonJS λͺ¨λμ ESM λνΌλ‘ λννκΈ° λλ¬Έμ λ°μνμ κ°λ₯μ±μ΄ ν½λλ€. Webpackμ λͺ¨λμμ import
κ° μ¬μ©λ κ²½μ° ESM λνΌλ₯Ό μ¬μ©ν©λλ€. μΌλ°μ μΌλ‘ λ€μ μ€ νλλ‘ μΈν΄ λ°μν©λλ€.
λ λ²μ§Έ κ²½μ°λ₯Ό νΌνλ €λ©΄ Babelμ sourceType
λ₯Ό "unambiguous"
λ‘ μ€μ νμ¬ λͺ¨λ μ νμ λ¨Όμ νμΈνλλ‘ ν΄μΌ ν©λλ€.
https://github.com/i-like-robots/broken-webpack-bundle-test-case
μ λ°μ΄νΈ: λ΄ μλ μ견 μ μμ μ¨κ²¨μ Έ μμ§λ§ μ΄κ²μ μ¬λ¬ monorepo νλ‘μ νΈμμ μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°νλ λ° μ¬μ©ν κΈ°λ³Έ ꡬμ±μ λλ€.
const excludePaths = [/node_modules/, /dist/]
module.exports = ({ config }) => {
// Use real file paths for symlinked dependencies do avoid including them multiple times
config.resolve.symlinks = true
// HACK: extend existing JS rule to ensure all dependencies are correctly ignored
// https://github.com/storybooks/storybook/issues/3346#issuecomment-459439438
const jsRule = config.module.rules.find((rule) => rule.test.test('.jsx'))
jsRule.exclude = excludePaths
// HACK: Instruct Babel to check module type before injecting Core JS polyfills
// https://github.com/i-like-robots/broken-webpack-bundle-test-case
const babelConfig = jsRule.use.find(({ loader }) => loader === 'babel-loader')
babelConfig.options.sourceType = 'unambiguous'
// HACK: Ensure we only bundle one instance of React
config.resolve.alias.react = require.resolve('react')
return config
}
@i-like-robots sourceType = 'unambiguous'
μ¬μ©μ λ¨μ μ 무μμ
λκΉ?
ν΄κ²° λ°©λ²μ κ²μν΄ μ£Όμ μ κ°μ¬ν©λλ€!
monorepo μ§μμ κ°μ νκΈ° μν΄ μ΄κ²μ μ¬μ©ν κ²μ λλ€: https://github.com/storybookjs/storybook/pull/8822
(6.0.0 κΈ°λ₯)
κ΄λ ¨μ΄ μμ μλ μμ§λ§ https://storybook.js.org/docs/configurations/custom-babel-config/ λ₯Ό μ½κ³ λ΄ μ¬μ©μ μ μ babel.config.js
λλ¬Έμ μ΄ exports is not defined
λ¬Έμ κ° λ°μνμ΅λλ€. λ¬Έμ .
@qrosmeli ν κ°μ¬ν©λλ€. λΉμ μ λ΄ ν루λ₯Ό ꡬνμ΅λλ€! π
νμ!! μ΄ λ¬Έμ λ₯Ό μ°Έμ‘°νλ PR #8822κ° ν¬ν¨λ https://github.com/storybookjs/storybook/releases/tag/v6.0.0-alpha.0 μ λ°©κΈ μΆμνμ΅λλ€. μ§κΈ μ κ·Έλ μ΄λνμ¬ μ¬μ©ν΄ 보μΈμ!
μ΄ μννμ @next
NPM νκ·Έμμ μ°Ύμ μ μμ΅λλ€.
μ΄ λ¬Έμ λ₯Ό λ«μ΅λλ€. μμ§ ν μΌμ΄ λ μλ€κ³ μκ°λλ©΄ λ€μ μ΄μ΄μ£ΌμΈμ.
[μ λ°μ΄νΈλ¨] - μ΄ κ·μΉμμ node_modulesλ₯Ό μ μΈν΄μΌ ν©λλ€. κ·Έλ μ§ μμΌλ©΄ λΉλκ° μ€λ¨λ©λλ€.
μ€ν λ¦¬λΆ main.js νμΌμ μ΄ κ·μΉμ μΆκ°νμ¬ ν΄κ²°νμ΅λλ€.
let rules = [{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: /dist/, //Include dist folder as well to parse using babel loader in order to resolve exports not defined error
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
["@babel/preset-env", {
modules: "commonjs"
}]
]
}
}]
μ΄μ ν¨κ» dist ν΄λμ λν eslint μ ν¨μ± κ²μ¬λ₯Ό λΉνμ±νν΄μΌ ν μλ μμΌλ―λ‘ μλ μ€ν¬λ¦½νΈλ₯Ό μ¬μ©ν μ μμ΅λλ€.
webpackFinal: config => {
//Find eslint loader rule from webpack config
let eslintRule = config.module.rules.find(rule => {
if (rule && rule.use) {
return rule.use.some(use => use.loader.match('eslint-loader'))
}
});
//Exclude validations of dist folder contents
eslintRule.exclude = /dist/;
return {
...config,
module: {
rules: [
...rules,
eslintRule,
...config.module.rules
]
}
}
}
κ°μ¬ν©λλ€ @ashvin777 , 맀λ ₯μ²λΌ μλν©λλ€ :wink:
@aperkazλ , node_modules
λ₯Ό μ μΈνλλ‘ κ·μΉμ μ
λ°μ΄νΈνμ΅λλ€. μ΄ λ³κ²½μΌλ‘ μΈν΄ μ€ν 리λΆμ΄ κ°λ° λͺ¨λμμλ μ λλ‘ μμλμ§λ§ νλ‘λμ
λͺ¨λμμλ μ€λ¨λλ κ²μ λ°κ²¬νμ΅λλ€. κ·Έλμ μμ νκΈ° μν΄ node_modules
λ₯Ό μ μΈν΄μΌ νμ΅λλ€. μμ μ
λ°μ΄νΈλ λκΈμμ μ΅μ μ 보λ₯Ό μ»μ μ μμ΅λλ€.
λλ λκ°μ λ¬Έμ κ° μμκ³ ν΄κ²°μ±
μ $ babel.config.js
$ μμ transform-es2015-modules-commonjs
μμ @babel/plugin-transform-modules-commonjs
λ‘ μ ννλ κ²μ΄μμ΅λλ€.
~ μ μ
module.exports = {
presets: [['@babel/preset-env', { modules: false }], '@babel/preset-react'],
plugins: [
'transform-es2015-modules-commonjs',
'@babel/plugin-proposal-class-properties'
]
};
~ νμ
module.exports = {
presets: [['@babel/preset-env', { modules: false }], '@babel/preset-react'],
plugins: [
'@babel/plugin-transform-modules-commonjs',
'@babel/plugin-proposal-class-properties'
]
};
TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
λλ μ΄ λ¬Έμ μ λν΄ ν루λ₯Ό 보λκ³ μ΄λ―Έ sourceType: 'unambigous'
λ₯Ό κ°μ§κ³ μμμ΅λλ€.
νμμ κ²½μ° node_modules
ν΄λ λ°λ‘ μμ μλ μλ νμΌμ΄κΈ° λλ¬Έμ 무μν ν΄λμ μ°κ²°λμ§ μμμ΅λλ€.
λλ₯Ό μν΄ μλνλ ν΄κ²° λ°©λ²μ @babel/preset-env
$ μ λν΄ modules: 'cjs'
μ΅μ
μ κ°μ μ€ννλ κ²μ
λλ€.
λλ λν @storybook/react@next
μ μ΄ λ¬Έμ κ° μμ΅λλ€. λλ₯Ό μν μ΅μ’
ν΄κ²°μ±
μ μλμΌλ‘ babel νλ¬κ·ΈμΈ @babel/plugin-transform-modules-commonjs
μ μΆκ°νλ λ°λ©΄ @babel/preset-env
μλ debug: true
μ΅μ
μ μ¬μ©νλ κ²μ
λλ€. λλ κ·Έκ²μ΄ μ΄λ―Έ μ¬μ©λ κ²μ λ³Έλ€... λλ μ΄ν΄νμ§ λͺ»νμ§λ§ μλνλ€.
νΈμ§: μ΄κ²μ webpackκ³Ό ν¨κ» ESM λͺ¨λμ μ΄μ μ μμ€νκΈ° λλ¬Έμ μ루μ μ΄ μλλλ€. μ€ν λ¦¬λΆ λΉλμ λν΄μλ§ κ°μ λ‘ cjsλ‘ λ³νν΄μΌ ν©λλ€.
:tada: λ΄ .storybook/.babelrc
: :tada:
{
"extends": "../.babelrc",
"plugins": [
"@babel/plugin-transform-modules-commonjs"
]
}
κ°μ₯ μ μ©ν λκΈ
μ΄ λ¬Έμ λ
.babelrc
νμΌμ μ¬λ°λ₯Έ νλ¬κ·ΈμΈμ μΆκ°νμ¬ ν΄κ²°ν μ μμ΅λλ€.tsconfig
νμΌμcommonjs
νΈν λͺ¨λμ μμ±νλλ‘ κ΅¬μ±λμ΄ μμΌλ―λ‘ μ μ ν νλ¬κ·ΈμΈμ μ¬μ©ν΄μΌ ν©λλ€.μ΄κ²μ λ΄
.babelrc
νμΌμ μλ κ²μ΄λ©° λͺ¨λ κ²μ΄ μ μλν©λλ€. μ νν λμΌν μ΅μ κ³Ό κ°μ κ°μ§tsconfig
νμΌμ΄ μμ΅λλ€."@babel/core"
"^7.1.0""@storybook/react"
^4.0.0-μν.2""react"
"^16.4.0"μ°Έκ³ : μ΄ μ루μ μ λ€λ₯Έ μ’ λ₯μ λͺ¨λμμ μλν©λλ€. https://babeljs.io/docs/en/next/plugins#modules