Setting up babel/webpack
npm install @babel/core @babel/cli @babel/preset-env --save-dev
바벨은 아무일도 하지 않는다. Transpile을 하는 것은 babel plugins. 어떤게 있을까:
@babel/plugin-transform-arrow-functions
여러가지 플러그인을 일일히 설치하는 것을 피곤하니까 그걸 한데 묶어 누가 만든 것이 preset이다:
@babel/preset-env
@babel/preset-react
@babel/preset-typescript
등등...
@babel/preset-env를 설치하고 설정하자:
npm install --save-dev @babel/preset-env
.babelrc 파일에서
{
"presets" : [ "@babel/preset-env" ]
}
그런데 @babel/preset-env이 하는 일이 너무 많아서 번들파일이 과도하게 커 질 수 있다. @babel/preset-env
에서 어디까지 브라우저 지원을 할 지 설정할 수 있다.
{
"presets" : [
[
"@babel/preset-env" ,
{
"targets" : "last 2 versions, > 1%"
}
]
]
}
위 설정은 각 브라우저의 마지막 두버전과 점유율이 1%를 넘는 브라우저를 지원한다.
browserl.ist 를 통해 확인할 수 있다.
Webpack
이제 webpack을 설정해보자
npm install --save-dev webpack webpack-cli
Webpack이 번들링을 할 때 babel을 사용하기 위해 babel-loader도 사용한다.
npm install --save-dev babel-loader
이제 webpack.config.js
파일에서 웹펙 설정을 해보자:
const path = require ( "path" )
module . exports = {
entry: "./src/index.js" ,
output: {
path: path. resolve (__dirname, "dist/static" ),
filename: "bundle.js" ,
},
module: {
rules: [
{
test: / \. js $ / ,
include: [path. resolve (__dirname, "src" )],
exclude: /node_modules/ ,
use: {
loader: "babel-loader" ,
options: {
presets: [
[
"@babel/preset-env" ,
{
target: "last 2 versions, > 1%" ,
},
],
],
},
},
},
],
},
devtool: "source-map" ,
mode: "development" ,
}
웹팩은 entry point에서 시작해 의존성이 있는 것들을 한데 모아 합쳐준다. 결과물을 저장하는 경로와 파일명을 정해줄 수 있다.(dist/static/bundle.js
)
Entry point에서 시작해 의존성이 있는 파일들을 읽으면서 확장자에 따라 알맞은 처리를 한다. 위의 설정에서는 ./src/
안에 있는 자바스크립트파일들을 바벨을 이용해 트랜스파일해준다.
다음으로 css를 임포트하려면 어떻게 해야 할까?
npm i -D css-loader sass-loader mini-css-extract-plugin
webpack.config.js
에서
const MiniCssExtractPlugin = require ( "mini-css-extract-plugin" )
module . exports = {
module: {
rules: [
... {
test: / \. css $ / ,
use: [MiniCssExtractPlugin.loader, "css-loader" ],
},
{
test: / \. s [ac] ss $ / ,
use: [MiniCssExtractPlugin.loader, "css-loader" , "sass-loader" ],
},
],
},
plugins: [
new MiniCssExtractPlugin ({
filename: "style.css" ,
}),
],
}
이제 웹팩은 파일을 읽어나가다가 css나 sass를 만나면 정리해서 ./dist/static/style.css
로 저장을 해 준다.
그런데 살다보니까 매번 브라우저를 열고 새로고침을 하는 것이 힘들 때가 있다. 이런 사람을 위해 누군가가 webpack-dev-server
라는 것을 만들어 놨다.
npm i -D webpack-dev-server
module . exports = {
...
devServer: {
contentBase: path. join (__dirname, "./dist" ),
publicPath: "/static/" ,
compress: true ,
port: 5500 ,
hot: true ,
},
}
contentBase
에 있는 파일들을 static file로 제공해주고 번들링을 한 결과는 따로 파일로 저장하지 않지만 /static/
에서 제공한다. 예를들면 localhost:5500/static/bundle.js
가 번들된 자바스크립트파일이다.
그런데 html 파일은 어떻게 할까? 이 역시 플러그인을 사용하자
npm i -D html-webpack-plugin html-webpack-harddisk-plugin
const HtmlWebpackPlugin = require ( "html-webpack-plugin" );
const HtmlWebpackHarddiskPlugin = require ( "html-webpack-harddisk-plugin" )
module . exports = {
...
plugin: [
new HtmlWebpackPlugin ({
template: path. resolve (__dirname, "./public/index.html" ),
filename: path. resolve (__dirname, "./dist/index.html" ),
inject: true , // inject built script in the end of body tag
alwaysWriteToDisk: true ,
}),
new HtmlWebpackHarddiskPlugin (),
]
}
이제 웹팩은 ./public/index.html
파일을 여러가지 작업(minify, 헤더에 css 파일 추가, 바디 태그 끝에 번들된 자바스크립트 추가)을 한 후 ./dist/index.html
파일로 저장한다.
그리고 쓰다보니 빌드를 하기 전에 배포파일을 저장하는 폴더를 다 지워주었으면 좋겠다는 생각이 들 수도 있다.
npm i -D clean-webpack-plugin
const { CleanWebpackPlugin } = require ( "clean-webpack-plugin" );
module . exports = {
...
plugins: [
new CleanWebpackPlugin ({
cleanAfterEveryBuildPatterns: [ "dist" ],
}),
...
]
}
더불어 package.json
에 스크립트를 만들자:
{
"scripts" : {
"build" : "webpack --config webpack.config.production.js" ,
"dev" : "webpack-dev-server --open --config webpack.config.dev.js"
}
}
위에는 안썼는데 사실 개발용 설정과 배포용 설정 파일을 나눠놨다. 이것은 숙제 ㅎㅎ
참고문헌
Jest를 사용해보자
Jest는 테스팅 라이브러리이다.
npm i -D jest
package.json
에서
{
"scripts" : {
"test" : "jest --watch"
}
}
이제 npm run test
를 하면 테스트를 실행시켜준다. --watch
는 파일 변경이 있으면 자동으로 테스트를 다시 하라는 의미. 테스트는 __tests__
폴더 안에 있는 .js
파일이다. 이게 싫으면 그냥 확장자 앞에 .test
또는 .spec
을 붙일 수도 있다. 예를들면 Component.test.js
. 사실 더 자세하고 설정도 할 수 있는데 이건 숙제.
하나 만들어 보자:
tt.js
import "./style.css"
export default function tt () {
return 1
}
테스트 파일은
tt.test.js
import tt from "./tt"
describe ( "tt" , () => {
it ( "returns 1" , () => {
expect ( tt ()). toBe ( 1 )
})
})
이제 실행시켜보자.
npm run test
어라? 오류가 난다. import "./style.css"
를 어떻게 이해할지 모르기 때문. 테스트할때는 스타일이 필요 없으니 대충 속이자.
jest.config.js
module . exports = {
moduleNameMapper: {
" \\ .(css|less|sass|scss)$" : "<rootDir>/src/lib/__mocks__/styleMock.js" ,
},
}
그리고 위의 해당 파일(styleMock.js)는 빈 모듈이다:
module . exports = {}
이러면 jest는 css 파일을 빈 모듈로 착각해 신경쓰지 않고 아무 문제 없이 테스트를 진행한다.
Dom 테스트가 힘들 때
위의 세팅을 다 해놓고 dom을 테스트하려하는데 막막한가? jest는 기본적인 검사함수밖에 주지 않는다. 이를 불편하게 여긴 어떤 사람이 또 패키지를 만들었다.
npm i -D @testing-library/dom
이 패키지는 getByText(dom, "aaa")과 같은 편리한 함수들을 제공해준다. 사용법은 숙제.