μλ νμΈμ,
λλμ΄ νΉλ³ν λ¬Έμ κ° μ λ°μνλμ§ μμ λ΄λ €κ³ λ Έλ ₯νκ³ μμ΅λλ€. λ€μκ³Ό κ°μ μ€ν 리λ₯Ό λμ μΌλ‘λ‘λν©λλ€.
function loadStories() {
const req = require.context('../components', true, /story.js$/);
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
κ° story.js
νμΌμλ κ°μ Έ μ€λ κ°κ°μ sass λλ css νμΌμ΄ μμ΅λλ€ ( story.js
κ° κ°μ Έμ¬ κ΅¬μ± μμ μΈλΆμμλ μ€ν 리 νΉμ μ€νμΌμ λͺ©μ μ μν΄ λ€μμ νμνκΈ° μν΄).
import './story.sass';
νμ¬ μ½ 4 κ°μ μ€ν λ¦¬κ° μμΌλ©° μ΄κ²μ΄ κ° μ€ν 리 iframeμ μμ€μ λλ€. λͺ¨λ μ€νμΌ μνΈλ₯Όλ‘λν©λλ€.
μ΄κ² μ μμ μΈ νλμΈκ°μ ...?
-
λ°λͺ¨
https://github.com/moimikey/729-single-stories-pulling-all-stylesheets
λν webpackμ λͺ¨λ μ΄μΌκΈ°λ₯Ό λ΄ λ³΄λ λλ€. κ·Έλμ webpackμ μ΄λ»κ² ꡬμ±νλμ§ κΆκΈν©λλ€.
λλ λ°μ½λ μ΄ν°λ μ¬μ©νλ €κ³ νλλ°, μ μ΄λ μΆκ° μ€νμΌ μνΈλ₯Ό μ€ν 리μ λΆλ¦¬ ν μ ββμμκΈ° λλ¬Έμμ΄ λΆλΆμ΄ μ λ°μΌλ‘ κΉ¨μ‘μ΅λλ€.
.addDecorator((getStory) => {
require('./story.sass');
return getStory();
})
νΈμ λ΄μ κ°κΈ°
ν₯λ―Έ λ‘κ΅°μ!, μ΄κ²μ 보μ¬μ£Όλ μ μ₯μκ° μμ΅λκΉ?
@ndelangen μ΄ κ³§ λ§λ€ κ²μ λλ€.
μμ§λ μ΄κ±Έ νμΈν μκ°μ μ°Ύλ μ€ ..
κ³ λ§μμ; D μ΄μ ν΄μ. λλ κ·Έκ²μ 보μμ§λ§ μ΄λμλΆν° μμν΄μΌν μ§ λͺ¨λ₯΄κ² μ΅λλ€.
κ·Έλμ λ΄κ° μκ°νλ κ²μ λͺ¨λ CSS νμΌμ΄ webpack μ€νμΌ λ‘λμ μν΄ μ νλμ΄ ν€λμ μ£Όμ λλ€λ κ²μ λλ€. μ¬μ© μ¬λΆμ κ΄κ³μμ΄
κ·Έλ¬λ κ³ μΉλ λ°©λ²?
CSSλ₯Ό μν΄ μ κ° ν μΌμ CSS λͺ¨λμ μ¬μ©νλ κ²μ λλ€. μμ± λ ν΄λμ€ μ΄λ¦μ λ΄ JSλ‘ κ°μ Έμ΅λλ€. λͺ¨λ CSSκ° ν€λμ ν¨κ» μ½μ λλλΌλ κ³ μ ν ν΄λμ€ / μ νμκ° λ³΄μ₯λλ―λ‘ μ€μνμ§ μμ΅λλ€.
κ·Έκ²μ λΉμ μ΄ κ°μ§κ³ μλ μ νν λ¬Έμ λ₯Ό μ€μ λ‘ ν΄κ²°νμ§ λͺ»ν©λλ€. κ·Έλ¬λ μ΄κ²μ΄ μ€νμΌ λ‘λμ μλ λ λμμ΄λΌκ³ μκ°ν©λλ€.
μ΄κ²μ μ¬μ€μ
λλ€. i (κ·Έλ¦¬κ³ μ°λ¦¬ νμ¬)λ CSSλ‘ λ²μλ₯Ό μ§μ νκ³ μμ§λ§ μμ²λ μ½λ μ¬κ°λ°μ μννκ³ μμΌλ―λ‘ μ€νμΌμ 곡μ νλ―λ‘ styleName
λ° className
μμ΅λλ€. κ²°κ΅ μ€ν 리 λΆμ μν₯μ λ―ΈμΉλ κ²μ "μΈλΆ"CSS νμΌμ
λλ€.
λ§₯μ£Όλ₯Ό λ§μκ³ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©λ², ꡬν νλͺ ν λ°©λ²μ μμ λΈ ν μ€λ λ°€ λ€μ μ€ν 리 λΆ μ½λλ₯Ό μ΄ν΄ λ³΄κ² μ΅λλ€.
@moimikey λ¬Έμ μ λν΄ μ€νμΌ λ‘λλ₯Ό 건λ λ°κ³ λ°μ½λ μ΄ν°λ₯Ό μ¬μ©νμ¬ μλμΌλ‘ CSS νμΌμλ‘λν΄μΌνλ€κ³ μκ°ν©λλ€. μλ§λ λ€μκ³Ό κ°μ΅λλ€.
.addDecorator(getStory => (
<div>
<link ... />
{getStory()}
</div>
))
μμ° .... λ΄ λ§μμ λμ΄μ μ μ΄ μλλ° ... μλν΄ λ³Όκ²μ.
ickνμ§λ§ λ€μ sass ... x_xλ₯Ό μ¬μ©ν©λλ€. λλ μ¬μ§μ΄ μΈλΌμΈ μꡬλ₯Ό μλνλ€. νμ§λ§ μ΄μ΄λ³λ‘ μμμ΅λλ€. κ·Έλλ 곧λ°λ‘ CSSμ λν νλ₯ν μ루μ μ΄ λ κ²μ λλ€ :)
κ·Έλμ @mnmtanish. λΉμ μμ§λμ κ°μ¬λ립λλ€. λλ λΉμ μ μκ°μΌλ‘ λ΄ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
.addDecorator((getStory) => {
require('./story.sass');
return getStory();
})
mmm μ΄μ μ μΌν λ¬Έμ λ μ€ν 리μμ μ€ν λ¦¬λ‘ μ΄λν λ μ€νμΌμ΄ μμ΄λ κ²μ λλ€.
μ€νμΌ λ‘λλ μ κ±° ν μ μλλ‘ HEAD μ΄μΈμ λ€λ₯Έ μμΉμ μ½μ νλλ‘ κ΅¬μ± ν μ μμ΅λλ€. λλ μ΄κ²μνμ§ μμκΈ° λλ¬Έμ κ·Έκ²μ΄ κ°λ₯νμ§ νμ€νμ§ μμ΅λλ€. μ΄κ²λ€ μ νμΈνμμμ€.
μ»΄ν¬λνΈλ₯Ό μμ ν 격리 λ μνλ‘λ‘λνμ¬ νμ¬ μ νν μ€ν 리μ κ΄λ ¨λ JavaScript / CSS λ§ μ€ννλ κ²μ΄ React μ€ν 리 λΆμ μ± μμ΄ μλλκΉ?
https://github.com/storybooks/react-storybook/issues/686 κ³Ό κ΄λ ¨μ΄
@ConneXNL μ. μ’μ μ§μ . μ΄κ²μ μ¬μ€μ λλ€ ...; X
@mnmtanish λ¬Όλ‘ λ΄ λ€μ μλ΅μ λ€λ₯Έ λ¬Έμ λ‘ μ΄μ΄μ§λλ€. insertAt
λ μ μ© ν μ μμ§λ§ μ΅μ λ²μ μ style-loader
μμλ§ μ¬μ©ν μ μμ΅λλ€. [email protected]
μ€ν 리 λΆμ μ¬μ ν 0.x
μμ΅λλ€. μ°λ¦¬κ° μ¬μ©ν μμλ μ΅μ λ²μ μ [email protected]
. : (...
μλ νμΈμ @moimikey μλ§λ μν 릴리μ€μμ λ§μ§λ§μΌλ‘ μΈκΈ ν μ κ·Ό λ°©μμ μλν΄ λ³Ό μ μμ΅λκΉ?
μ€ν 리λ₯Ό μ ν ν λ μ iframe μμλ₯Ό λ§λλ κ²μ΄ λ λ«κ±°λ μμ νμ§ μμ΅λκΉ?
μμ νκ³ μ±λ₯μλ μ’μ§ μμ΅λλ€.
μλ‘μ΄ iframeμ μλ° μ€ν¬λ¦½νΈλ₯Ό νμ±νκ³ , CSSλ₯Ό νμ±νκ³ , postmessage-channelμ μ°κ²°νκ³ , μΉ μμΌμ λ€μ μ°κ²°νλ λ± λ λ§μ κ²λ€μν΄μΌν©λλ€.
μ€ν 리 μ€μμΉμμ <style>
μμλ₯Ό μ κ±°νλ©΄μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μμ΅λκΉ?
λ¬Όλ‘ κΈλ‘λ² μ€νμΌμ΄μκ³ λͺ¨λ κ²μ΄ μ μ νκ² λ€μ μ€νμ΄μ€κ° μ§μ λμ΄ μμ΅λλ€. μ΄κ²μ λͺ λ°±ν λ¬Έμ κ° μλλλ€. λ΄κ° μκ°νκΈ°μ ν¬λ§μ°¬ μκ°. π
λκ΅°κ°κ° μμ μ§μ μ΄ κ±°μ§μμ μ¦λͺ ν μ μκ±°λ λΆμ μ μΈ κ²°κ³Όκ° μμμ μ μ¦ ν μ μλ€λ©΄, λͺ¨λ κ·μ λλ€!
μ€λ λͺ κ°μ§ ν μ€νΈλ₯Όνμ΅λλ€. λ°μ½λ μ΄ν° ν¨ν΄μ΄ μ μλνμ¬ μ€ν λ¦¬λ‘ μ ν ν νμ λ§ ββμ€νμΌμ΄ μ½μ λ©λλ€. κ·Έλ¬λ μ€ν 리λ₯Ό μ ν ν λ μ€νμΌμ΄ μ κ±°λμ§ μλ λμΌν λ¬Έμ κ° λ°μνμ΅λλ€.
λλ λ°μ½λ μ΄ν°μμ μ€νμΌμ μ κ±°νλ©΄μ λμμ§λ§ νμν μ€νμΌμ΄ ν λ²λ§ μ μ©λ κ² κ°μ΅λλ€. require ()λ₯Ό λ€μ νΈλ¦¬κ±° ν μ μμ΅λκΉ? singleton : falseλ₯Ό μ¬μ©ν΄ 보μμ§λ§ λ¬Έμ κ° ν΄κ²°λμ§ μμμ΅λλ€.
λλ μ΄κ²μ μ μνλ κ²μ κ±°μ μ£Όμ νμ§λ§ μΉν© μΊμλ₯Ό νμ΄ ν΄ λ³Ό μ μμ΅λλ€.
https://webpack.github.io/docs/api-in-modules.html#advanced
μ΄κ²μ μΉν© 1 λ¬Έμμ΄μ§λ§ μ¬μ ν μλ ν μ μμ΅λλ€.
μμ΄λμ΄ : μ€ν 리λ₯Ό μ ν ν λ λͺ¨λ <style>...</style>
λ₯Ό μ κ±°νλ λ°μ½λ μ΄ν°λ₯Ό μμ±ν μ μμ΅λλ€. νμ¬ μ€ν 리μ κ΄λ ¨μ΄μλ μ€νμΌμ μ 리ν©λλ€.
κ±°μ λ€ μμ΄μ. webpack ꡬμ±μμ λλ
'style-loader/useable' instead of 'style-loader',
μμ ν APIκ° μΆκ°λ©λλ€. .use ()λ μ€νμΌμ μΆκ°νκ³ unuse ()λ μ€νμΌμ μ κ±°ν©λλ€. λ΄ μ΄μΌκΈ° ββνμΌμμ λ€μκ³Ό κ°μ λ°μ½λ μ΄ν°λ₯Ό μ¬μ©ν©λλ€.
.addDecorator((c) => <ReactStylesheet stylesheets={[require('./stories.scss')]}>{ c() }</ReactStylesheet> )
λ€μ React Componentλ₯Ό μ¬μ©νμ¬ μ€νμΌμ μΆκ°νκ³ μ κ±°νμμμ€.
import * as React from 'react';
export class ReactStylesheet extends React.Component{
componentWillUnmount(){
let stylesheets = Array.isArray(this.props.stylesheets) ? this.props.stylesheets : [this.props.stylesheets];
stylesheets.forEach((stylesheet) => {
console.log("Unmounting....");
stylesheet.unuse();
});
}
componentDidMount(){
let stylesheets = Array.isArray(this.props.stylesheets) ? this.props.stylesheets : [this.props.stylesheets];
stylesheets.forEach((stylesheet) => {
console.log("Mounting....");
stylesheet.use();
});
}
render(){
return this.props.children;
}
}
μ€νμΌ μνΈλ₯Ό μ¬λ°λ₯΄κ² λ³κ²½νλ©΄ μ€νμΌμ΄ λ€μλ‘λλ©λλ€. λ€λ₯Έ μ€ν λ¦¬λ‘ μ ννλ©΄ unuse ()κ° νΈμΆλκ³ μ€νμΌ μνΈκ° μ 리λ©λλ€. κ·Έλ¬λ μ€νμΌ μνΈμ λΉ hrm μ λ°μ΄νΈ λ²μ μ κ΄κ³ νκΈ° λλ¬Έμ μ€νμΌμ λ€μ μΆκ°νλ©΄ λ©μλκ° μ€λ¨λ©λλ€. κ·Έ νμ λ³κ²½νλ©΄ λ€μ μ€λ₯κ° λ°μν©λλ€.
Uncaught (in promise) TypeError: Cannot read property 'refs' of undefined
at update (webpack:///./~/style-loader/addStyles.js?:63:4)
at eval (webpack:///./src/Component/stories.scss?:32:4)
at Object.hotApply [as apply] (http://dev.test:6006/static/preview.bundle.js:499:14)
at cb (webpack:///(webpack)-hot-middleware/process-update.js?:52:36)
at eval (webpack:///(webpack)-hot-middleware/process-update.js?:68:13)
at <anonymous>
μ΅μ HRM λ²μ μ κ°λ¦¬ ν€λλ‘ require λ¬Έμ μ λ°μ΄νΈνλ λ°©λ²μ μ λͺ¨λ₯΄κ² μ΅λλ€.
νμμ μΈ μμ¬ μμ ! λλ μ μ μ΄μ κ°μ κ²μ λλ¬ λ³΄μμ§λ§ μ°Ύμ μ μμμ΅λλ€.
@ConneXNL μ λκΈ° μν΄
μ루μ
μ΄ κ°κΉμμ§κ³ μμ΅λλ€. stylesheet.use()
λ° unuse
μ λν μμ΄λμ΄λ λμκ² λ―μ κ²μ΄μμ§λ§ μ¬λ°λ₯Έ λ°©ν₯μΌλ‘ κ°κ³ μλ κ² κ°μ΅λλ€.
μ΄κ²μ μλ λ°μ± μ€ν 리 λΆ https://github.com/Wildhoney/ReactShadowμ λ λ€λ₯Έ ν₯λ―Έλ‘μ΄ μ μ λλ€.
μλ νμΈμ μ¬λ¬λΆ! μ΅κ·Όμ΄ λ¬Έμ μμ λ§μ μΌμ΄ μΌμ΄λμ§ μμ κ² κ°μ΅λλ€. μ¬μ ν μ§λ¬Έ, μ견 λλ λ²κ·Έκ° μμΌλ©΄ ν λ‘ μ κ³μνμμμ€. μνκΉκ²λ λͺ¨λ λ¬Έμ λ₯Ό λ€λ£° μκ°μ΄ μμ΅λλ€. μ°λ¦¬λ νμ κΈ°μ¬μ μ΄λ € μμΌλ―λ‘ λμμ΄ νμνλ©΄ ν μμ²μ 보λ΄μ£Όμμμ€. λΉνμ± λ¬Έμ λ 60 μΌ νμ λ§κ°λ©λλ€. κ°μ¬!
@ConneXNL μ΄μ΄ λ¬Έμ λ₯Ό λ§λ¬΄λ¦¬νκΈ° μν΄μ΄ μ μμ λ¬Έμλ₯Ό κ°μ νλ λ° λμμ μ€ μ μλ€κ³ μκ°νμλκΉ?
μ’μ μ₯μλ₯Ό μ°Ύμ μ μλ€λ©΄ λ§ν¬ λ€μ΄ νμμΌλ‘ μ΄λκ°μ κ½μ λμΈμ. λ΄κ° λ£μ΄ μ€κ².
π
μλ νμΈμ μ¬λ¬λΆ! μ΅κ·Όμ΄ λ¬Έμ μμ λ§μ μΌμ΄ μΌμ΄λμ§ μμ κ² κ°μ΅λλ€. μ¬μ ν μ§λ¬Έ, μ견 λλ λ²κ·Έκ° μμΌλ©΄ ν λ‘ μ κ³μνμμμ€. μνκΉκ²λ λͺ¨λ λ¬Έμ λ₯Ό λ€λ£° μκ°μ΄ μμ΅λλ€. μ°λ¦¬λ νμ κΈ°μ¬μ μ΄λ € μμΌλ―λ‘ λμμ΄ νμνλ©΄ ν μμ²μ 보λ΄μ£Όμμμ€. λΉνμ± λ¬Έμ λ 60 μΌ νμ λ§κ°λ©λλ€. κ°μ¬!
μλ , λ λμΌ! μ΄ λ¬Έμ λ₯Ό λ§λ¬΄λ¦¬νμ¬ κ΄λ¦¬μκ° λμ νμ¬ κ°λ° λ‘λ맡μ μ§μ€ν μ μλλ‘νκ² μ΅λλ€. μΈκΈ λ λ¬Έμ κ° μ¬μ ν μ°λ €λλ κ²½μ° μ ν°μΌμ μ΄κ³ μ΄ μ΄μ ν°μΌμ μΈκΈνμμμ€. μ€ν 리 λΆμ μ¬μ©ν΄ μ£Όμ μ κ°μ¬ν©λλ€!
μ¬κΈ°μλ κ°μ λ¬Έμ μΈ μ€ν 리 λΆμ κ° μ€ν 리λ₯Ό λΆλ¦¬νμ§ μμΌλ―λ‘ μκ°μ ν μ€νΈ / μΉμΈ ν μ€νΈμ μ¬μ©ν μ μμ΅λλ€.
μ€ν 리 μ£Όμμ κ·Έλ¦Όμ λΏλ¦¬λ₯Ό λλ©΄ @ndelangen μ μ±λ₯ λ¬Έμ
@bennypowers ν₯λ―Έ λ‘μ΅λλ€! κ·Έκ²μ λ¬μ±νλ λ°©λ²μ λν μ½λ μνμ΄ μμ΅λκΉ? π
@shilman μκ²λ
μλ
νμΈμ. μ΄ λ¬Έμ λ λ°μν©λλ€.
μ΄ λ¬Έμ κ° ν΄κ²°λμκ±°λ ν΄κ²° λ°©λ²μ΄ μμ΅λκΉ?
λΏ‘λΏ‘
μ¬κΈ°μ κ°μ₯ λΉ λ₯Έ λ§μ‘±λλ ReactShadow λ₯Ό μ¬μ© νλΌλ @moimikey μ μ μ μΌ κ²μ λλ€.
μ·¨ν μ λ΅μ ReactShadow κ΅¬μ± μμμ 루νΈλ₯Ό λν ν λ€μ adoptedStyleSheets
(λλ μ§μλμ§ μλ λΈλΌμ°μ μ κ²½μ° <style>
μμ)λ‘ μ€νμΌμ κ°μ Έ μ€λ κ²μ
λλ€.
μ΄ λ¬Έμ λ₯Ό λ€μμ¬μμμ€.μ΄ λ¬Έμ λ‘ μΈν΄ μ€ν 리λ³λ‘ μ¬μ©μ μ§μ μ€νμΌμ μΆκ°νλ κ²μ΄ λ§€μ° μ΄λ ΅μ΅λλ€. μμ μ λν μ¬μ©μ μ§μ μ€νμΌμ ꡬννλ μμ ν λΆλ¦¬ λ MDX μ€ν λ¦¬κ° μμΌλ©° λͺ¨λ μ€ν 리μ λͺ¨λ μ€νμΌμ μ μ μ μΌλ‘ ν¬ν¨νλ©΄μ΄ μ¬μ© μ¬λ‘λ₯Ό μ μ§ν μ μμ΅λλ€.
νΈμ§ : κ°μ¬ν©λλ€ !!!
2020 λ 3 μ 21 μΌκΉμ§μ΄ λ¬Έμ κ° ν΄κ²°λκΈ°λ₯Ό λ°λλλ€.
@moimikey μ΄ μΌμ κ΄μ¬μ΄
IMOμμλ μ€νμΌ μνΈ μ μ© κΈ°λ₯μ μΆκ°νλ λμ λ§€κ° λ³μ λλ μ λμ¨μ μΆκ°νμ¬μ΄ κΈ°λ₯μ μ²λ¦¬ν΄μΌν©λλ€. μ€νμΌ μνΈμ μ€ν¬λ¦½νΈκ°μ μΌκ΄μ±μλ λμμ΄ λ°μν©λλ€. κ·Έλ¬λ "격리"κ° μ΄λ»κ²λμ΄μΌνλμ§ κ³ λ €ν μ’μμκΈ°μΌκΉμ?
λλ κ·Έκ²μ΄ κ°λ₯νμ§ κΆκΈν΄νλ μ λμ¨ μ κ·Ό λ°©μμ λν λΉ λ₯Έ PoCλ₯Ό μμ±νμ΅λλ€.
https://github.com/pocka/storybook-addon-css
@pocka λΉμ μ κ΅μ₯ν©λλ€! π―
yazzzzz. 건배 @pocka
mdx-js / mdx # 894 λλ¬Έμ MDX μ€ν 리λ₯Ό μ¬μ©νλ κ²½μ° @pocka μ μ루μ μ΄ μλνμ§ μλλ€λ μ μ μ£Όλͺ©ν κ°μΉκ° μμ΅λλ€.
νΈμ§ : λ΄ λμ, νμ€ν κ·Έλ μ΅λλ€! μ€νμΌ λ‘λ 1.x +κ° μμ΄μΌνλ©° λ€μκ³Ό κ°μ΄ν΄μΌν©λλ€.
--- a/components/grid/GridChild.stories.mdx
+++ b/components/grid/GridChild.stories.mdx
@@ -1,7 +1,9 @@
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { GridContainer, GridRow, GridChild } from './';
import '../../shared/critical-path.scss';
-import 'o-grid/demos/src/scss/_demos.scss';
+import demoStylesModule from '!!style-loader?injectType=lazyStyleTag!css-loader!sass-loader!o-grid/demos/src/scss/_demos.scss?story';
+
+export const demoStyles = Promise.resolve(demoStylesModule);
<Meta title="Core|Grid/GridChild" component={GridChild} />
@@ -37,7 +39,12 @@ You supply it a `colspan` prop in one of the following formats:
```
<Preview>
- <Story name="Default unresponsive columns">
+ <Story
+ name="Default unresponsive columns"
+ parameters={{
+ styles: [demoStyles],
+ }}
+ >
<GridContainer>
<GridRow>
<GridChild colspan="1">
λΏ‘λΏ‘
μ§μ ν΄μ£Όμ
μ κ°μ¬ν©λλ€. μ λ MDXλ₯Ό μμ ν μμμ΅λλ€. : no_mouth :
PoCλ₯Ό μ
λ°μ΄νΈνκ³ MDX μμ λ₯Ό μΆκ°νμ΅λλ€ .
μ λμ¨ λ°©μ (μ€ν 리 μ€νμΌ λ³)μ μ¬μ©νλ©΄ νμΌ λ²μ μ§μ λ°©μ (νμΌ μ€νμΌ λ³)κ³Ό λ¬λ¦¬ λ¬Έμ νμ λͺ¨λ μ€ν 리μ λͺ¨λ μ€νμΌ μνΈλ₯Ό κ°μ Έμ΅λλ€. λ΄ μ μμ "foo"λ° "baz"μ€ν 리 κ°μ Έ μ€κΈ° foo.css
λ° "bar"μ€ν 리 κ°μ Έ μ€κΈ° bar.css
, κ·Έλ¬λ©΄ λ¬Έμ νμμ foo.css
λ° bar.css
κ°μ Έ μ€κΈ° . λλ μ΄κ²μ΄ νΌν μ μλ€κ³ μκ°νλ©° μ΄κ²μ΄ μμ© κ°λ₯νμ§ μλμ§ λͺ¨λ₯΄κ² μ΅λλ€.
@pocka https://github.com/storybookjs/storybook/tree/next/addons/cssresources WDYTμμ κ·Έ μ κ·Ό λ°©μμ΄ μ μλ ν κ²μ΄λΌκ³ μκ°ν©λλ€.
λΏ‘λΏ‘
μ, λ§μ!
foo.story = {
parameters: {
cssresources: [
{
id: 'foo',
code: `<style>${require('!to-string-loader!css-loader!./foo.css')}</style>`,
picked: true
}
]
}
}
ν κ°μ§ λ¬Έμ λ μ¬μ©μκ° λ§€μ° ν° μ€νμΌ μνΈλ₯Ό κ°μ Έ μ€λ©΄ "CSS 리μμ€"νμ΄ μ§μ λΆν΄μ§ κ²μ λλ€.
@pocka λ§μ΅λλ€. cssresources μ λμ¨μ΄ ν΄λΉ λΆμμμ ν¬κ² ν₯μ λ μ μλ€κ³ μκ°ν©λλ€. κ·Έκ±Έ λ°μλ€μ΄κ³ μΆλ?
λΏ‘λΏ‘
μ : μ€λ§μΌ :
κ·Έλ°λ° μ¬μ©μκ° raw-webpack-queryλ₯Ό μμ±νλλ‘ νμ©νλ κ²μ λν΄ μ΄λ»κ² μκ°νμλκΉ? ( !to-string-loader!...
μ²λΌ) μ°λ¦¬κ° μ΄κ²μ μμ κ³ μΆλ€λ©΄ μ λμ¨ μ½λμ λ§μ ν λ§λ²μ΄ νμνλ€κ³ μκ°ν©λλ€ ...
κΈ°λ³Έμ μΌλ‘ babel-macrosλ₯Ό μ§μνλ―λ‘ μ¬μ©μκ° macro-preval μ μ¬μ©νμ¬ λ²λ€μ νμΌ μ½ν μΈ λ₯Ό μ½μ ν μ μμ΅λκΉ?
λͺ°λμ΅λλ€. 곧 μ΄ν΄ λ³Όκ²μ!
μλ νμΈμ, λμΌν λ¬Έμ κ° λ°μνμ΅λλ€.
λ¬Έμ κ°μλ μ¬λμ μ΄ ν΄κ²° λ°©λ²μ μλν΄λ³΄μμμ€. (νμ§λ§ μ½κ°μ κΉμ μΉν© μ§μμ΄ νμν©λλ€).
@ndelangen 맀ν¬λ‘λ₯Ό μ΄ν΄ to-string-loader
(λλ file-loader
)λ‘ CSS νμΌμ κ°μ Έ μ€λ κ·μΉμ μΆκ°νλ CSSResource μ λμ¨μ
λλ€.
// adding a rule like this
{
test: /\.css$/,
resourceQuery: /cssresources/,
use: ['to-string-loader', 'css-loader', 'postcss-loader']
}
μ μ²λ¦¬κΈ°μ κ²½μ° test
λ° use
λ₯Ό μ¬μ©μ μ§μ νλ μ΅μ
λ νμν©λλ€. μ€νμΌ νμΌμ λν κ·μΉμ μ νν λ€μ oneOf
λ‘ μμ ν μ μμ§λ§ λ무 볡μ‘ν©λλ€ ...
μ΄λ»κ² μκ°ν΄?
@pocka μ, ν₯λ―Έλ‘μ΄ κ°λ μ²λΌ λ€λ¦½λλ€!
μλ νμΈμ, μμ§ μμ μ€μΈμ§ κΆκΈνμλκΉ? λν λ¬Έμ κ° λ°μνμ΅λλ€. ν΄κ²° λ°©λ²μ μκ³ μμ§λ§ μ‘°λ§κ° μμ μ¬νμ μ¬μ©ν μ μλμ§ μκ³ μΆμ΅λλ€.
μλ νμΈμ, Vue Storyλ₯Ό μ¬μ©νμ¬ ν΄κ²° λ°©λ²μ μλ₯Ό μ 곡 ν μ μμ΅λκΉ?
λ΄κ° λ§ν μμλ ν, ν΄κ²° λ°©λ² μ μ μ΄λ λ¬Έμ λΆκ° κΈ°λ₯μ μ¬μ©νλ κ²½μ° μ΄κΈ°λ³΄κΈ° νμ μ€νμΌ μνΈκ° μμ΄λ κ²°κ³Όλ₯Ό κ°μ Έμ΅λλ€. π
무λ‘ν μλκ° μμκΈ° λλ¬Έμ @pocka μ μ λμ¨ μ κ·Ό λ°©μμ λ μΌλ°μ μΈ ν¨ν΄μ΄λΌκ³ μκ°νλ μ€ν 리 νμΌκ³Ό λ¬λ¦¬ κ΅¬μ± μμ νμΌμμ κ°μ Έμ¨ μ€νμΌμ λΆλ¦¬νμ§ μκΈ° λλ¬Έμ λ€μ λΆμ‘±νλ€λ κ²μ μμμ΅λλ€. λ΄ κ°μΈμ μΈ μλ§ (μ΄ μ€λ λμ λ€λ₯Έ μ¬λλ€μ΄ μ΄κ²μ 곡μ ν μ μλ€κ³ μκ°ν©λλ€.)μ Button.jsx
μ€ν 리 νμΌμμλ§ μ¬μ©λλ Button.jsx
λ΄λΆμ import './Button.css'
λ₯Ό κ°μ§ μμλ κ²μ
λλ€ Button.jsx
λ₯Ό κ°μ Έ μμ΅λλ€. @pocka κ° μ 곡 ν λ°©μμ μ€ν 리 λ³ μ€νμΌλ§μ Button
(μ§κ°μ μ μΌλ‘)λ₯Ό κ°μ Έ μ€μ§ μλ κ΅¬μ± μμκ° μν₯μλ°μ§ μλλ‘νλ κ²λ§ νΌ μ€μνμ§ μμ΅λλ€. Button.css
λͺ¨λ CSS κ·μΉ. (μ¬κΈ°μμ μ°λ €λλ μ μ OtherWidget.css
μ μ€μλ‘ Button.css
λ‘ λλλ μΌλΆ κ·μΉμ΄ μλμ§ νμΈνλ €λ κ²μ
λλ€. OtherWidgetμ μ€ν 리λ μ 체 μ±μ μ μ μΌλ‘ κ°μ Έμ¨ CSSλ₯Ό λͺ¨λ κ°μ Έ μ€λ―λ‘ OtherWidgetμ Storybookμμ μ¬μ ν μ 보μ
λλ€.)
λμ μ κ° μκ°νλ κ²μ λͺ¨λ CSS λ‘λλ₯Ό λ³κ²½νμ¬ lazyStyleTag
μ£Όμ
ν λ€μ, webpack APIλ₯Ό μ¬μ©νμ¬ CSS λͺ¨λμ κΆκ·Ήμ μΌλ‘ νμλ‘νκ³ μ€ν 리 λ³κ²½μ μμ νλ μ€ν 리 νμΌλ³λ‘ κ·Έλ£Ήννλ μ λͺ¨λμ μμ±νλ κ²μ
λλ€. μ΄λ²€νΈλ₯Ό ν΅ν΄ ν΄λΉ λͺ¨λμ μΌκ³ λλλ€.
μ΄ μ κ·Ό λ°©μμ μ΄λ―Έ κ³ λ €νκ³ νκΈ° νμ΅λκΉ? μλλ©΄ μ§κΈλ³΄κ³ μλ λ¬Έμ κ° μμ΅λκΉ? Storybook μ λμ¨μμ λͺ¨λ κ²μ ν μ μλ€κ³ μκ°νμ§λ§ Storybookμ ν΅μ¬ κΈ°λ₯μΌλ‘ ν΅ν©νλ©΄ λ κΉ¨λν μ μμ΅λλ€.
κ°λ ₯ν μ€νμΌ μΊ‘μνλ₯Ό μνλ©΄ λΈλΌμ°μ κ° ν¨κ» μ 곡λ©λλ€. μ¬κΈ°μ λ΄ λ¬΄μ§κ° λλ¬λ μνμ μ²ν΄ μμ§λ§,μ΄ λͺ¨λ μ¬μ©μ μμ JavaScript (κ΄λ ¨ 볡μ‘μ± λΉμ© ν¬ν¨)κ° κΈ°λ³Έ μ 곡λκ³ λ°λ‘ μ¬μ©ν μμλ μμ μ μννλ λ° νμν μ΄μ λ μμ§ νμ€νμ§ μμ΅λλ€.
λ€μκ³Ό κ°μ΄ κ° μ€ν 리μ DOMμ κ·Έλ¦Όμ 루νΈλ‘ λ λλ§νμ§ μλ μ΄μ
customElements.define('encapsulated-story', class EncapsulatedStory extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
/* not sure why we'd need this getter, but let's say */
get storyHTML() {
return this.shadowRoot.innerHTML;
}
set storyHTML(string) {
this.shadowRoot.innerHTML = storyHTML;
}
});
κ·Έλ¦¬κ³ μ΄μΌκΈ°κ° λ°λ λλ§λ€
encapsulatedStory.storyHTML = theStoryDOMStringWithAllStyleTags;
μλ£? μ¬κΈ°μ theStoryDOMStringWithAllStyleTags
λ λͺ¨λ κ΄λ ¨ μ€νμΌμ΄ μΈλΌμΈ <style>
νκ·Έλ‘ μ°κ²°λ μ€ν 리μ HTMLμ μ°κ²° ν κ²μ
λλ€. Storyλ νμμ²λΌ :host
μ νκΈ°λ‘ νΈμ€νΈ μμμ μ€νμΌμ μ§μ ν μ μμ΅λλ€.
μ΄λ μλ§λ μΌλΆ λΌμ΄λΈλ¬λ¦¬ μ½λλ‘ λμ€μ λΉλ ν μμλ μ΅μνμ μμμ μ΄μ§λ§, μ μ΄λ μλ‘ μ μ λ λͺ¨λ APIκ° νμμμ΄ κ°λ ₯ν μ€νμΌ μΊ‘μνμ λͺ©νλ₯Ό λ¬μ± ν κ²μ λλ€.
κ·Έλλ webpackκ³Ό μ΄λ»κ² μλν©λκΉ? Webpackμ λͺ¨λ κ²μ DOM λ¬Έμμ΄μ΄ μλ JavaScript λ²λ€λ‘ ν¨ν€μ§ν©λλ€. μΉν©μ΄ νμ¬ κ΅¬μ±λλ λ°©μμ λͺ¨λ μ€ν 리λ₯Ό λ¨μΌ λ²λ€λ‘ ν¨ν€μ§ν©λλ€. JavaScriptκ° (ν« λ¦¬)λ‘λλλ κ²½μ° λ¬Έμμ 머리μ μ€νμΌμ μ§μ μ½μ ν λ μλμ° λ£¨νΈκ° λμμ΄λμ§ μλλ€κ³ μκ°ν©λλ€. μ΄λ₯Ό λ³κ²½νλ €λ©΄ νΈμ΄ λ§μ μΉν© ꡬμ±μ μνν΄μΌν©λλ€.
Shadow DOMμ μ¬μ©νμ¬ κ° μ€ν 리λ₯Ό μμ ν λΆλ¦¬νλ κ²μ λ§μ μ€ν 리μμ 곡μ νλ μ€νμΌ νκ·Έλ₯Ό κ° μ€ν λ¦¬λ‘ λ³΅μ νλ κ²μ μλ―ΈνκΈ°λν©λλ€. μΉν©μ λ²λ€λ‘ μ 곡λλ 곡μ μ€νμΌμ μ¬μ©νλ κ²μ΄ λ ν¨μ¨μ μ
λλ€. ν° μ°¨μ΄λ₯Ό λ§λ€κΈ°μλ μΆ©λΆνμ§ μμ μλ μμ§λ§, lazyStyleTag
λμ Shadow DOMμ μ¬μ©νλ μ΄μ μ΄ μλ€λ©΄μ΄λ₯Ό μμνκΈ°μ μΆ©λΆν μ μμ΅λλ€. λΉμ μ ꡬνμμμ€).
μ‘°λ§κ°μ΄ λ¬Έμ κ° ν΄κ²°λλ κ²μλ³΄κ³ μΆμ΅λλ€.
μμ νκ³ μ±λ₯μλ μ’μ§ μμ΅λλ€.
μλ‘μ΄ iframeμ μλ° μ€ν¬λ¦½νΈλ₯Ό νμ±νκ³ , CSSλ₯Ό νμ±νκ³ , postmessage-channelμ μ°κ²°νκ³ , μΉ μμΌμ λ€μ μ°κ²°νλ λ± λ λ§μ κ²λ€μν΄μΌν©λλ€.
@ndelangen 2017μμ μΈμ© ν΄ μ£μ‘νμ§λ§ iframeμ λ€μλ‘λνλ κ²μ΄ λ무 λΉμΈλ€λ κ²μ΄ μ¬μ ν κ·νμ κ΄μ μ λκΉ? λΈλΌμ°μ λ μ΄λ¬ν μ νμ μμ μ μ§μμ μΌλ‘ μνν©λλ€. μλ§ λ§€μ° μ΅μ νλμ΄μμ κ²μ λλ€. μ΄ κ²½μ° κ΄λ ¨λ λ€νΈμν¬ μμ²μ΄ μκΈ° λλ¬Έμ μΌλ° νμ΄μ§λ‘λλ³΄λ€ ν¨μ¬ λΉ λ¦ λλ€.
λμκ² μ΄μ΅μ λΉμ©λ³΄λ€ ν½λλ€. κ° μ€ν 리μ λν΄ μλ‘μ΄ iframeμ λ§€μ° μ νΈνκΈ° λλ¬Έμ λλ€. λλ κ·Έλ¬ν μ¬μΉνμ μν΄ 600msμ μ§μ°μ νμ© ν κ²μ λλ€.
(λ΄ μ¬μ© μ¬λ‘λ μ€ν 리 λΆμμ μΌλΆ λ κ±°μ angularjs κ΅¬μ± μμλ₯Ό λ λλ§νλ €κ³ νλ κ²μ λλ€. κ΅¬μ± μμκ° λ§€μ° μμνμ§ μλ€κ³ κ°μ ν΄ λ³΄κ² μ΅λλ€. λ§€μ° μν μ μ₯μ λλ€. λΆμμ©μ΄ μμΌλ©° λ€μκ³Ό κ°μ angularjs μλΉμ€λ₯Ό μ¬μ©ν©λλ€. μν©μ΄ μμμΉ λͺ»ν λ°©μμΌλ‘ μ€λ¨λ©λλ€.)
API νλ©΄μ λν ν κ°μ§ μμ΄λμ΄λ .storybook/manager.js
μμ μ€ν 리 λΆμ ꡬμ±νλ κ²μ
λλ€.
addons.setConfig({
refreshBetweenStories: true,
})
머리λ₯Ό μ¬λ°λ₯Έ λ°©ν₯μΌλ‘ κΈ°μΈμ΄λ©΄ UI μ€μ μΌλ‘ κ°μ£Ό λ μ μμ΅λλ€.
μ΄ νλκ·Έλ₯Ό νμ±ννμ§ μλ μ¬λμκ²λ λ°νμ λΉμ©μ΄ λ€μ§ μμΌλ©° νμ±ννλ μ¬λμκ²λ _ μ λ§λ‘ _ νμνλ―λ‘ μ΄λ¬ν μ§μ°μ νμ©λ©λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ €λ©΄ λ¬Έμ μ€λͺ μ πμ μΆκ°νμ¬ μ°¬μ±νμΈμ. μ°μ μμλ₯Ό μ νλ λ°μ΄ μ 보λ₯Ό μ¬μ©ν©λλ€!
.addDecorator ((getStory) => {
require ( './ story.sass');
return getStory ();
})
μλ
νμΈμ!!!!
μ΄κ±° μ΄λμ λ μ μλμ? !!!
κ°μ₯ μ μ©ν λκΈ
μ€ν 리 μ£Όμμ κ·Έλ¦Όμ λΏλ¦¬λ₯Ό λλ©΄ @ndelangen μ μ±λ₯ λ¬Έμ