v4 에서 v5로 마이그레이션하기
마이그레이션 해야 하는 이유
버그 수정 및 새로운 스타일링 엔진과 같은 여러 개선사항의 이점을 얻으려면 마이그레이션 해야한다.
마이그레이션 단계
React 또는 TypeScript 버전 업데이트
- React 최소지원버전: v16.8.0 to v17.0.0.
- TypeScript 최소지원버전: v3.2 to v3.5.
ThemeProvider setup
v5로 업그레이드 전에 ThemeProvider
가 당신의 어플리케이션의 root에 정의되어 있고(default theme를 사용한다고 하더라도) useStyles
가 <ThemeProvider>
전에 호출되진 않았는지 확인해 본다. 그 이유는 임시로 @mui/styles
(JSS style-engine)을 사용해야 하는데, 이것이 ThemeProvider
를 요구한다.
1 | import { |
MUI 버전 업데이트
v5 버전의 MUI core를 사용하려면 먼저 패키지 네임을 업데이트해야 한다.
1 | npm install @mui/material @mui/styles |
만약 아래와 같은 패키지가 이미 있는 경우 새 패키지를 별도로 설치해라
@material-ui/lab
→@mui/lab
@material-ui/icons
→@mui/icons-material
모든 변경된 패키지 리스트 보기
1
2
3
4
5
6
7
8
9
10
11
12
13@material-ui/core -> @mui/material
@material-ui/system -> @mui/system
@material-ui/unstyled -> @mui/base
@material-ui/styles -> @mui/styles
@material-ui/icons -> @mui/icons-material
@material-ui/lab -> @mui/lab
@material-ui/types -> @mui/types
@material-ui/styled-engine -> @mui/styled-engine
@material-ui/styled-engine-sc ->@mui/styled-engine-sc
@material-ui/private-theming -> @mui/private-theming
@material-ui/codemod -> @mui/codemod
@material-ui/docs -> @mui/docs
@material-ui/envinfo -> @mui/envinfo
org 또는 패키지 이름이 @material-ui
에서 @mui
로 변경된 것은 리브랜딩의 일환이다. 자세한 내용은 블로그 포스트 또는 #27803을 확인한다.
그 다음으로는 새로운 종속 디펜던시인 이모션 패키지를 설치해야 한다.
1 | npm install @emotion/react @emotion/styled |
만약 MUI Core v5를 emotion 대신 styled-components와 함께 사용하고 싶다면 설치 가이드를 확인한다.
만약 @material-ui/pickers
를 사용중이라면 이것은 @mui/lab
으로 이동했다. 이 링크를 통해 @mui/lab
으로 마이그레이션 하는 다음 단계를 확인할 수 있다.
지금쯤 @mui/styles
를 설치했어야 한다. 여기에는 emotion을 복제하는 JSS를 포함하고 있다. 이는 v5로의 점진적인 마이그레이션을 허용하기 위한 것이다. 다음 단계에 따라 종속성을 제거할 수 있도록 한다.
어플리케이션이 에러없이 잘 실행되고 있는지 확인하고, 다음 단계를 이어가기 전에 변경 사항을 커밋하도록 한다.
어플리케이션이 완전히 MUI v5로 마이그레이션 되면 이전의 @material-ui/*
패키지를 yarn remove
또는 npm install
로 제거할 수 있다.
codemod 실행
마이그레이션을 쉽게 할 수 있도록 codemod를 준비했다.
preset-safe
이 codemod에는 마이그레이션에 유용한 대부분의 transformer가 포함되어 있다. (이 codemod는 폴더당 한 번만 적용될 수 있도록 한다.)
1 | npx @mui/codemod v5.0.0/preset-safe <path> |
이 codemode를 일대일로 하나씩 실행하려면 preset-safe codemod에서 상세 내용을 확인한다.
variant-prop
어떠한 variant도 정의되지 않았다면 (default variant는 v4 standard에서 v5 outlined로 변경되었다.)<TextField/>
, <FormControl/>
, <Select/>
등의 컴포넌트에 variant=”standard”를 적용하여 변환할 수 있다.
1 | // if you have theme setup like this, ❌ don't run this codemod. |
만약 variant=”standard” 를 컴포넌트에서 유지하고 싶다면, 이 codemod를 실행하거나 theme default props를 구성한다.
1 | npx @mui/codemod v5.0.0/variant-prop <path> |
자세한 내용은 variant-prop codemod를 확인한다.
link-underline-hover
underliner prop이 정의되지 않았다면 컴포넌트에 underline=”hover”를 적용하면 변환할 수 있다. (default underline은 v4 “hover”에서 v5 “always”로 변경되었다.)
1 | // if you have theme setup like this, ❌ don't run this codemod. |
만약 variant=”hover” 를 컴포넌트에서 유지하고 싶다면, 이 codemod를 실행하거나 theme default props를 구성한다.
1 | npx @mui/codemod v5.0.0/link-underline-hover <path> |
자세한 내용은 link-underline-hover codemod에서 확인한다.
codemod 단계를 일단 완료했다면 어플리케이션을 다시 실행해본다. 이때 에러없이 실행되어야 한다. 그렇지 않을 경우 troubleshooting 섹션을 확인해본다. 다음 단계는 각 컴포넌트의 주요 변경사항을 처리하는 것이다.
Handling breaking changes
지원되는 브라우저 및 노드 버전
default 번들의 타겟이 변경되었다. 정확한 버전은 browserslist query가 릴리즈 될 때 고정된다.
"> 0.5%, last 2 versions, Firefox ESR, not dead, not IE 11, maintained node versions"
기존 번들은 아래와 같은 최소 버전을 지원한다.
- Node 12 (up from 8)
- Chrome 90 (up from 49)
- Edge 91 (up from 14)
- Firefox 78 (up from 52)
- Safari 14 (macOS) and 12.5 (iOS) (up from 10)
- and more (see .browserslistrc (
stable
entry))
더이상 IE 11을 지원하지 않기 때문에 IE 11을 지원해야 하는 경우는 lagacy bundle를 확인한다.
non-ref-forwarding class components
component prop의 non-ref-forwarding class components 또는 immediate children의 지원이 중단되었다. 만약 unstable_createStrictModeTheme를 사용하고 있거나 React.StrictMode의 findDOMNode
과 관련된 어떠한 경고도 표시되지 않았다면 아무런 작업도 수행할 필요가 없다. 그렇지 않다면 Caveat with refs 섹션에서 어떻게 마이그레이션 해야하는지 알아볼 필요가 있다. 이 변경 사항은 component prop를 사용하는 곳이나 children을 element로 필요로 하기 때문에 children을 components에 전달해야 하는 거의 모든 components에 영향을 미친다. (예를 들어,
style library
v5에서 default로 사용하는 스타일 라이브러리는 [emotion](https://github.com/emotion-js/emotion)
이다. JSS에서 emotion으로 마이그레이션 하는 동안 components에 JSS style을 사용하여 override하는 경우 (예를 들자면 makeStyles 통해 override하는 경우) CSS 삽입 순서 (CSS injection order)를 신경써야 한다. 이렇게 하려면 StyledEngineProvider
와 injectFirst
옵션이 컴포넌트 tree의 가장 최상단에 위치해야 한다.
1 | //예시 |
1 | //예시 |
styled-components를 사용 중이고, 커스텀 타겟이 있는 StyleSheetManager를 사용중이라면 타겟이 HTML
엘리먼트의 첫번 째 요소인지 확인한다. 어떻게 이것을 수행하는지 확인하려면@mui/styled-engine-sc
package에 있는 [StyledEngineProvider
implementation](https://github.com/mui-org/material-ui/blob/master/packages/mui-styled-engine-sc/src/StyledEngineProvider/StyledEngineProvider.js)을 살펴본다.
Theme structure
theme 구조는 v5에서 변경되었기 때문에 변경된 형태로 업데이트 해야 한다. 원활한 전환을 위해서 adaptV4Theme
를 사용해서 일부 테마의 변경된 사항을 새로운 테마 구조로 반복적으로 업그레이드 할 수 있다.
1 | -import { createMuiTheme } from '@mui/material/styles'; |
adapther는 다음의 변경 사항을 지원한다.
- “gutters” abstraction은 가치가 있다고 생각될 만큼 자주 사용되지 않는다고 입증되었다.
1 | -theme.mixins.gutters(), |
theme.spacing
은 이제 default로 px 유닛과 단일 값을 반환한다. 이는 styled-compontnts와 emotion의 통합을 개선한다.
1 | 이는 `theme.spacing`이 template string로 호출되던 것으로부터 'px' 접미사를 제거해서 |
1 | //before |
- 이 기능을 설명하는 데 일반적으로 사용되는 “dark mode”라는 용어를 더 잘 따르기 위해서
theme.palette.type
키는theme.palette.mode
로 이름이 변경되었다.
1 | import { createTheme } from '@mui/material/styles'; |
- default
[theme.palette.info](http://theme.palette.info)
색상은 라이트, 다크 모드 모두에서 AA 표준 명암비를 통과하도록 변경되었다.
1 | info = { |
- default
theme.palette.succeess
색상은 색상은 라이트, 다크 모드 모두에서 AA 표준 명암비를 통과하도록 변경되었다.
1 | success = { |
- default
theme.palette.warning
색상은 색상은 라이트, 다크 모드 모두에서 AA 표준 명암비를 통과하도록 변경되었다.
1 | warning = { |
- default
theme.palette.text.hint
키는 MUI components에서는 사용되지 않기 때문에 제거되었다. 만약 dependency를 가지고 있다면 뒤에 아래 예시와 같은 내용을 덧붙이도록 한다.
1 | import { createTheme } from '@mui/material/styles'; |
- theme의 components 정의는 어떠한 관련된 component에서도 정의를 쉽게 찾아볼 수 있도록 compontns key 아래에 새롭게 구성되었다.
prop
1 | import { createTheme } from '@mui/material/styles'; |
overrides
1 | import { createTheme } from '@mui/material/styles'; |
Styles
- 기능을 더 잘 나타내기 위해
fade
에서alpha
로 이름이 변경되었다. 이전의 이름은 입력 색상 값에 이미 alpha값이 있을 때 혼동을 야기했다. helper는 색상의 alpha 값을 override 한다.
1 | - import { fade } from '@mui/material/styles'; |
createStyles
함수는@mui/material/styles
에서 export 되는 것에서@mui/styles
에서 export되는 것으로 변경되었다. 디펜던시를 core 패키지의@mui/styles
로 이동시키는 것이 필요하다.
1 | -import { createStyles } from '@mui/material/styles'; |
@mui/styles
ThemeProvider
@mui/styles
와 @mui/material
를 함께 사용한다면, ThemeProvider
를 @mui/material/styles
에서 export 되던 것을 @mui/styles
에서 export 되도록 변경해야 한다. 이 방법은 @mui/styles
에서 export된 스타일링 유틸리티인 makeStyles, withStyles 등과 MUI component에서 context에서 제공되는 theme가 모두 사용되도록 할 수 있다.
1 | -import { ThemeProvider } from '@mui/styles'; |
Default Theme (TypeScript)
@mui/styles
패키지는 더이상 @mui/material/styles
의 일부가 아니다. @mui/styles
를 @mui/material
과 함께 사용하는 경우에 DefaultTheme에 대해 모듈을 추가하여 적용해야 한다.
1 | // in the file where you are creating the theme (invoking the function `createTheme()`) |
@mui/material/colors
- 1 레벨 이상의 중첩된 import는 private이다.
@mui/material/colors/red
에서 색상을 가져올 수 없다.
1 | -import red from '@mui/material/colors/red'; |
@mui/material/styles
createGenerateClassName
createGenerateClassName
함수는 더이상 @mui/material/styles
에서 export되지 않는다. @mui/styles
에서 직접 import해야 한다.
1 | -import { createGenerateClassName } from '@mui/material/styles'; |
@mui/styles를 사용하지 않고 커스텀 클래스네임을 생성하려면 ClassNameGenerator에서 세부내용을 확인한다.
createMuiTheme
createMuiTheme
함수는 ThemeProvider
를 좀더 직관적으로 사용할 수 있도록 하기 위해서 createTheme
로 이름이 변경되었다.
1 | -import { createMuiTheme } from '@mui/material/styles'; |
jssPreset
jssPreset
객체는 더이상@mui/material/styles
에서 export되지 않는다.@mui/styles
에서 바로 import해서 사용해야 한다.
1 | -import { jssPreset } from '@mui/material/styles'; |
makeStyles
makeStyles
JSS 유틸리티는 더이상@mui/material/styles
에서 export되지 않기 때문에 대신@mui/styles/makeStyles
를 사용해야 한다.defaultTheme
를 더이상 사용할 수 없기 때문에ThemeProvider
를 어플리케이션의 루트에 추가하도록 한다. 만약@mui/material
와 함께 사용하고 있다면@mui/material/styles
에 있는 ThemeProvider 컴포넌트를 사용하는 것을 추천한다.
1 | -import { makeStyles } from '@mui/material/styles'; |
MuiThemeProvider
MuiThemeProvider
컴포넌트는 더이상 @mui/material/styles
에서 export되지 않으므로 ThemeProvider
를 대신 사용한다.
1 | -import { MuiThemeProvider } from '@mui/material/styles'; |
serverStyleSheets
ServerStyleSheets
컴포넌트는 더이상 @mui/material/styles
에서 export되지 않으므로 @mui/styles
에서 직접 import하도록 한다.
1 | -import { ServerStyleSheets } from '@mui/material/styles'; |
Styles
styled
JSS utility는 더이상 @mui/material/styles
에서 export되지 않으므로 대신 @mui/styles
에서 export된 것을 사용하도록 한다. defaultTheme
를 더이상 사용할 수 없기 때문에 ThemeProvider
를 어플리케이션의 루트에 추가하도록 한다. 만약 @mui/material
와 함께 사용하고 있다면 @mui/material/styles
에 있는 ThemeProvider 컴포넌트를 사용하는 것을 추천한다.
1 | -import { styled } from '@mui/material/styles'; |
StylesProvider
StylesProvider
컴포넌트는 더이상@mui/material/styles
에서 export되지 않으므로@mui/styles
에서 바로 export하여 사용하도록 한다.
1 | -import { StylesProvider } from '@mui/material/styles'; |
useThemeVariants
useThemeVariants
hook은 더이상@mui/material/styles
에서 export 되지 않기 때문에@mui/styles
에서 즉시 import하여 사용하도록 한다.
1 | -import { useThemeVariants } from '@mui/material/styles'; |
withStyles
innerRef
prop은 ref
prop으로 교체한다. Refs는 이제 자동으로 inner 컴포넌트에 전달된다.
1 | import * as React from 'react'; |
withStyles
JSS utility는 더이상 @mui/material/styles
에서 export 되지 않기 때문에 @mui/styles/withStyles
를 대신 쓰도록 한다. defaultTheme
를 더이상 사용할 수 없기 때문에 ThemeProvider
를 어플리케이션의 루트에 추가하도록 한다. 만약 @mui/material
와 함께 사용하고 있다면 @mui/material/styles
에 있는 ThemeProvider 컴포넌트를 사용하는 것을 추천한다.
1 | -import { withStyles } from '@mui/material/styles'; |
withTheme
withTheme
HOC utility는 @mui/material/styles
패키지에서 제거되었기 때문에 대신 @mui/styles/withTheme
를 사용할 수 있다. defaultTheme
를 더이상 사용할 수 없기 때문에 ThemeProvider
를 어플리케이션의 루트에 추가하도록 한다. 만약 @mui/material
와 함께 사용하고 있다면 @mui/material/styles
에 있는 ThemeProvider 컴포넌트를 사용하는 것을 추천한다.
1 | -import { withTheme } from '@mui/material/styles'; |
innerRef
prop를 ref prop으로 바꾼다. Ref는 이제 자동으로 내부 컴포넌트에 전달된다.
1 | import * as React from 'react'; |
withWidth
이 HOC는 제거되었고, 대안으로 [useMediaQuery
hook](https://mui.com/components/use-media-query/#migrating-from-withwidth)을 쓸 수 있다.
mui/icons-matetial
Github
Github icon은 24px에서 22px로 크기가 감소되었다.
@material-ui/pickers
@material-ui/pickers
를 마이그레이션 하는 방법은 다음 페이지를 참조하도록 한다.
System
다음의 system function 및 속성은 사용되지 않는 css로 간주되어 이름이 변경되었다.
gridGap
togap
gridRowGap
torowGap
gridColumnGap
tocolumnGap
간격을 조정하는 unit인 gap
, rowGap
, columnGap
등을 사용할 때, 이전에 숫자로 사용하고 있었다면 theme.spacing과 더불어 새롭게 변환되기 위해 px를 덧붙여서 사용해야 한다.
1 | <Box |
css prop은 styled-components와 emotion의 css prop이 충돌되는 것을 막기 위해 sx
로 변경한다.
1 | ;-(<Box css={{ color: 'primary.main' }} />) + |
Core components
core components는 스타일 엔진으로 emotion을 사용하기 때문에 emotion에 의해 사용되는 props들은 전파되지 않는다. 아래의 코드 스니펫처럼 props as
는 SomeOtherComponent
로 전파되지 않는다.
1 | <MuiComponent component={SomeOtherComponent} as='button' /> |
References
Migration from v4 to v5 - MUI