react-router v4

2019-01-22

기존 프로젝트 버전 업하는 작업을 하기전 테스트를 해보았다.

기존버전 신규버전
react 15.3.2 react 16.7.0
webpack 1.13.2 webpack 4.19.0
babel-loader 6.2.5 babel-loader: 7.0.0
babel-core 6.14.0 babel-core 7.0.1

Babel7

.babelrc 파일에 설정을 해줘야한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-transform-object-assign",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-transform-regenerator",
"@babel/plugin-syntax-export-default-from",
"transform-export-extensions",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-object-rest-spread"
]
}

babel7+ 버전부터는 babel-plugin-syntax-trailing-function-commas 를 사용하여 파라미터들을 나열할 때 마지막 파라미터에 콤마(,)를 허용한다.
그러나 마지막 파라미터에 object spread 연산자가 있는 경우 콤마 (,) 를 허용하지 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
const {
style,
color,
width, // 가능
} = this.props;


const {
style,
color,
...other, ---> 이 부분을 ...other로 수정
} = this.props;

Router v4 - browserRouter

react-router v4부터는 라우터가 컴포넌트 개념이라고 생각하면 된다.
hashRouter를 사용하는 경우 현재 프로젝트와 동일하게 작업을 하면 된다.
그러나 browserRouter를 사용하는 경우에는 아래와 같이 webpack.config 파일 설정이 필요하다.

1
2
3
4
5
6
7
8
module.exports = {
   ...
    devServer: {
        contentBase: path.join(__dirname,'src'),
        disableHostCheck: true, // realgrid때문에 host파일 설정을 하는데 설정을 해줘야 lululala.co.kr이런식으로 접근할 수 있다.
        historyApiFallback: true  // browserRouter사용하는 경우 /밑에 app안에 정의된 router 로 이동할 수 있다.
    },
}

browserRouter를 사용하는 경우에 www.lululala.co.kr/rocket/LUXButton –> 이 경우 build된 파일의 경로를 바로 잡지 못해 아래와 같은 에러가 발생한다.
이는 해당 주소를 서버에 요청하면 서버 쪽 라우터에서 먼저 연결할 곳이 있는지 확인해보고 없으면 오류가 발생한다.
이를 해결하기 위해서는 webpack에서 publicPath 설정을 해야한다.
publicPath란 서비스가 시작되는 루트경로를 제외한 상대경로를 설정하는 것이다. 즉, 웹팩에 의해 빌드될 때 사용되는 경로이다.

기존 publicPath 적용 후

Router Splitting

기존에는 react-loadable 라이브러리를 사용하여 페이지가 로더될 때와 로딩될 때를 구분하여 사용할 수 있었다.

1
2
3
4
5
6
7
8
9
10
11
import loadable from 'react-loadable';


const AboutComponentPage = () => {
return import('./about');
}

const AsynAboutComponent = loadable( {
loader: AboutComponentPage, // 로드될 페이지
loading: Loading //로딩 될때
});

react 16.6 부터 react에서 지원하는 Lazy, Suspense를 사용하면 된다.
dynamic import 를 통해서 사용한다. 아직 로딩이 되지 않은 lazy컴포넌트의 fallback을 suspense 를 통해 표시할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
import React, { Suspense, lazy } from 'react'
const ErrorDialogComponent = lazy(() => import('./Documents/LUXErrorDialog/ErrorDialogDocument'));
const Loading = () => <div>loading...</div>


render{
return (
<Suspense fallback={<Loading />}>
<Route path={`${this.props.match.path}/LUXButton`} render={(props) => <ErrorDialogComponent {...props} />} onEnter={scrollToTop}/>
</Suspense>
)
}

webpack4

1. 기본적으로 설정되어 있는 development모드와 production모드가 생김

2. 빌드 속도가 빨라짐

3.  webpack core와 webpack-cli가 분리됨

4.  CommonsChunkPlugin이 deprecated 되고 SplitChunksPlugin이 내장되어 있음 

splitChunk 는 대형 프로젝트에서 거대한 번들 파일을 적절히 분리하고 나눌 수 있다. 파일 사이즈, 비동기 요청 횟수 등의 옵션에 따라 자동으로 분리할 수 있고 정규식에 따라서 특정 파일들만 분리할 수 있다. 또한 특정 엔트리 포인트를 분리할 수 있다.

번들 파일을 적절히 분리하면 브라우저 캐시를 전략적으로 활용할 수 있으며 초기 로딩속도를 최적화 할 수 있다.

cacheGroups 는 특정 파일을 청크로 분리할 때 사용된다.

commons은 청크를 분리한다.

test 를 사용해 대상이 되는 파일을 정규식으로 잡는다.

name은 청크로 분리할 때 이름으로 사용될 파일명이다. 여기서는 output.filename옵션에 [name]에 대치될 내용이다.

chunks는 모듈의 종류에 따라 청크에 포함할지 말지를 결정하는 옵션이다. 옵션으로는 initial, async, all이 있다. all 은 test조건에 포함되는 모든 것을 분리하겠다는 뜻이다. initial은 초기 로딩에 필요한 경우 async는 import를 이용해 다이나믹하게 사용되는 경우에 분리한다.

common은 모듈이 여러 청크 사이에서 두 번 이상 공유되는 경우 생성 한 다음 새 청크를 형성하는 경우이를 피할 수 있다.

AsyncChunkNames 플러그인은 import 요청한 파일 이름을 분석하여 청크 이름을 추측하여 청크파일 이름을 생성한다. 파일명의 이름과 같게 생성을 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module.exports = (env, options) => {
const config = {
//..
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
},
common: {
name: 'common',
minChunks: 2,
chunks: "all",
priority: 10,
reuseExistingChunk: true,
enforce: true
},
}
}
}
}
}

참조: https://meetup.toast.com/posts/153
:https://itnext.io/react-router-and-webpack-v4-code-splitting-using-splitchunksplugin-f0a48f110312