GPT 및 검색의 도움을 받아보니 웹팩에서 특정한 파일 형식을 처리할 수 없을 때 발생하는 일반적인 문제.
전체 오류 메세지
./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| export function createEmptyBreakpointObject() {
| let breakpointsInput = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
> const breakpointsInOrder = breakpointsInput.keys?.reduce((acc, key) => {
| const breakpointStyleKey = breakpointsInput.up(key);
| acc[breakpointStyleKey] = {};
해결
yarn remove react-scripts
yarn add react-scripts
필자의 경우엔 react-scripts 패키지 재설치로 바로 해결되었다.
해당 프로젝트의 세팅 파일들
package.json
{
"name": "react-template",
"version": "0.1.0",
"private": true,
"dependencies": {
"@date-io/date-fns": "^3.0.0",
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@material-ui/pickers": "^3.3.11",
"@mui/material": "^6.1.3",
"@types/jest": "24.0.18",
"@types/node": "12.7.12",
"@types/react": "16.9.5",
"@types/react-csv": "^1.1.2",
"@types/react-datepicker": "^4.1.3",
"@types/react-dom": "16.9.1",
"@types/react-redux": "^7.1.4",
"@types/react-router-dom": "^5.1.0",
"@types/redux-thunk": "^2.1.0",
"axios": "^0.19.0",
"bootstrap": "^4.3.1",
"css-loader": "^7.1.2",
"file-loader": "^6.2.0",
"rc-progress": "^3.1.4",
"react": "^16.10.2",
"react-csv": "^2.0.3",
"react-datepicker": "^4.1.1",
"react-dom": "^16.10.2",
"react-fontawesome": "^1.6.1",
"react-js-pagination": "^3.0.3",
"react-quill": "^1.3.5",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.2",
"react-scripts": "^5.0.1",
"react-search-field": "^2.0.1",
"reactjs-popup": "^1.5.0",
"redux": "^4.0.4",
"redux-thunk": "^2.3.0",
"source-map-loader": "^3.0.0",
"style-loader": "^4.0.0",
"styled-components": "^6.0.7",
"sweetalert2": "^11.1.7",
"ts-loader": "^9.2.6",
"typescript": "^4.4.3",
"xlsx": "^0.17.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/compat-data": "7.19.4",
"@babel/core": "7.19.6",
"@babel/generator": "7.19.6",
"@babel/helper-compilation-targets": "7.19.3",
"@babel/helper-create-class-features-plugin": "7.19.0",
"@babel/helper-module-transforms": "7.19.6",
"@babel/preset-env": "^7.25.8",
"@babel/preset-typescript": "^7.25.7",
"@fortawesome/fontawesome-free": "^5.11.2",
"@types/react-js-pagination": "^3.0.4",
"babel-loader": "^8.0.6"
}
}
webpack.config.js
module.exports = {
mode: "production",
// Webpack의 출력물에서 디버깅을 하기위해 소스 맵을 허용합니다.
devtool: "source-map",
resolve: {
// 확인 가능한 확장자로 '.ts' 와 '.tsx' 를 추가합니다.
extensions: [".ts", ".tsx"]
},
module: {
rules: [
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [
{
loader: "ts-loader"
}
]
},
// 모든 '.js' 출력 파일은 'source-map-loader'에서 다시 처리한 소스 맵이 있습니다.
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'], // CSS 파일을 처리
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'], // SCSS 파일을 처리
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'file-loader', // 이미지 파일을 처리
},
],
},
]
},
// 경로가 다음 중 하나와 일치하는 모듈을 가져올 때,
// 해당 전역 변수가 있다고 가정하고 사용합니다.
// 브라우저가 빌드간에 라이브러리를 캐시 할 수 있도록
// 모든 의존성을 묶지 않아도 되기 때문에 중요합니다.
externals: {
"react": "React",
"react-dom": "ReactDOM"
},
devServer: {
historyApiFallback: true,
},
};
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"declaration": true,
"outDir": "dist",
"sourceMap": true,
"noImplicitAny": true
},
"include": [
"src"
]
}
.babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-proposal-optional-chaining"
]
}