[Next.js] 10 version -> 11version 마이그레이션 한 후 development mode 에러 처리

BinaryWoo_dev·2023년 2월 28일
0

Next.js

목록 보기
1/2

요즘 너무나도 많은 곳에서 사용되고 있는 Next.js 프레임워크가 벌써 13 version까지 나왔다.
사내 프로젝트 애플리케이션은 Next.js 10 version을 사용 중인데, 더는 늦어지면 안될 것 같아 이번 기회에 11 version 으로 한 단계 업그레이드를 진행해보았다.

Next.js 버전 업그레이드 하기

업그레이드 명령어

	$yarn add next@11

또는 upgrade 를 사용하여 패키지를 업그레이드를 할 수 있다.

	$yarn upgrade next@11

(단, 이 yarn upgrade 명령어로 패키지를 업그레이드 하고자 할 경우, 꼭 이 문서를 참고하도록 하자)

Development Mode로 로컬 서버 실행 중 마주친 에러

위의 명령어로 Next.js 를 10 -> 11 version 정상 업그레이드를 하였다.

이제 $yarn dev 명령어를 실행하여 개발 모드 로컬 서버를 실행하려고 하는데, 아래와 같은 에러 문구들이 엄청 길게 출력되었다. (어쩐지 순탄히 진행되는 것 같더라니..)

에러 결과

	        absolutePath: true
      },
      Pathinfo: {
        description: 'Include comments with information about the modules.',
        anyOf: [ { enum: [Array] }, { type: 'boolean' } ]
      },
      Performance: {
        description: 'Configuration for web performance recommendations.',
        anyOf: [
          { enum: [Array] },
          { '$ref': '#/definitions/PerformanceOptions' }
        ]
      },
      
(...)
.
.
.
.
.
.(생략)

import('../lib/Compiler')) => void"
      },
      WebpackPluginInstance: {
        description: 'Plugin instance.',
        type: 'object',
        additionalProperties: true,
        properties: {
          apply: {
            description: 'The run point of the plugin, required method.',
            instanceof: 'Function',
            tsType: "(compiler: import('../lib/Compiler')) => void"
          }
        },
        required: [ 'apply' ]
      }
    },
    title: 'WebpackOptions',
    description: 'Options object as provided by the user.',
    type: 'object',
    additionalProperties: false,
    properties: {
      amd: { '$ref': '#/definitions/Amd' },
      bail: { '$ref': '#/definitions/Bail' },
      cache: { '$ref': '#/definitions/CacheOptions' },
      context: { '$ref': '#/definitions/Context' },
      dependencies: { '$ref': '#/definitions/Dependencies' },
      devServer: { '$ref': '#/definitions/DevServer' },
      devtool: { '$ref': '#/definitions/DevTool' },
      entry: { '$ref': '#/definitions/Entry' },
      experiments: { '$ref': '#/definitions/Experiments' },
      externals: { '$ref': '#/definitions/Externals' },
      externalsPresets: { '$ref': '#/definitions/ExternalsPresets' },
      externalsType: { '$ref': '#/definitions/ExternalsType' },
      ignoreWarnings: { '$ref': '#/definitions/IgnoreWarnings' },
      infrastructureLogging: { '$ref': '#/definitions/InfrastructureLogging' },
      loader: { '$ref': '#/definitions/Loader' },
      mode: { '$ref': '#/definitions/Mode' },
      module: { '$ref': '#/definitions/ModuleOptions' },
      name: { '$ref': '#/definitions/Name' },
      node: { '$ref': '#/definitions/Node' },
      optimization: { '$ref': '#/definitions/Optimization' },
      output: { '$ref': '#/definitions/Output' },
      parallelism: { '$ref': '#/definitions/Parallelism' },
      performance: { '$ref': '#/definitions/Performance' },
      plugins: { '$ref': '#/definitions/Plugins' },
      profile: { '$ref': '#/definitions/Profile' },
      recordsInputPath: { '$ref': '#/definitions/RecordsInputPath' },
      recordsOutputPath: { '$ref': '#/definitions/RecordsOutputPath' },
      recordsPath: { '$ref': '#/definitions/RecordsPath' },
      resolve: { '$ref': '#/definitions/Resolve' },
      resolveLoader: { '$ref': '#/definitions/ResolveLoader' },
      snapshot: { '$ref': '#/definitions/SnapshotOptions' },
      stats: { '$ref': '#/definitions/StatsValue' },
      target: { '$ref': '#/definitions/Target' },
      watch: { '$ref': '#/definitions/Watch' },
      watchOptions: { '$ref': '#/definitions/WatchOptions' }
    }
  },
  headerName: 'Webpack',
  baseDataPath: 'configuration',
  postFormatter: [Function: postFormatter]
}

에러 원인을 파악하기 위해 공식 문서를 살펴본 결과, Next.js > v11 부터는 webpack5가 default로 적용된다고 한다.
그래서, next.config.js 를 살펴보니 현재 프로젝트 애플리케이션는 webpack4 에 대한 설정들을 사용하고 있기 때문에 발생하는 것이었다.

// next.config.js

const path = require('path');
const glob = require('glob');

module.exports = {
  (...)
  webpack: (config) => {
    // moment@2.19.0 workaround
    config.resolve.alias = {
      ...config.resolve.alias,
      moment$: 'moment/moment',
    };

    config.node = {
      fs: 'empty',
    };

    config.module.rules.push(
      {
        test: /\.(css|scss)/,
        loader: 'emit-file-loader',
        options: {
          name: 'dist/[path][name].[ext]',
        },
      },
      {
        test: /\.s[ac]ss$/i,
        use: [
          'babel-loader',
          'raw-loader',
          'postcss-loader',
          {
            loader: 'sass-loader',
            options: {
              implementation: require('sass'),
              includePaths: ['styles', 'node_modules']
                .map((d) => path.join(__dirname, d))
                .map((g) => glob.sync(g))
                .reduce((a, c) => a.concat(c), []),
            },
          },
        ],
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'url-loader',
        options: {
          name: '[name].[ext]',
          limit: 100000,
        },
      },
    );

    return config;
  },
};

친절하게도 공식문서에 아래와 같이 해결 방법이 나와있었다. (공식 문서)

  • Next.js 11 버전은 모든 애플리케이션에서 webpack5이 기본적으로 사용됩니다. 당신이 webpack5 가 아닌 기존 webpack을 그대로 사용하기를 원한다면, next.config.js 파일에 webpack5: false 구문을 추가하면 됩니다.

하지만, 마지막 문구를 보면 Next.js 12부터는 얄짤 없이 webpack5 을 사용해야한다고 한다.

해결 방법

따라서, next.config.js 내부에 webpack5: false 구문을 추가하여 webpack5를 기본으로 사용하지 않도록 설정한 후, 다시 $yarn dev 를 실행하였더니 정상적으로 로컬 서버가 실행되었다.

// next.config.js

const path = require('path');
const glob = require('glob');

module.exports = {
  (...)
+ webpack5: false,
  webpack: (config) => {
    // moment@2.19.0 workaround
    config.resolve.alias = {
      ...config.resolve.alias,
      moment$: 'moment/moment',
    };

    config.node = {
      fs: 'empty',
    };

    config.module.rules.push(
      {
        test: /\.(css|scss)/,
        loader: 'emit-file-loader',
        options: {
          name: 'dist/[path][name].[ext]',
        },
      },
      {
        test: /\.s[ac]ss$/i,
        use: [
          'babel-loader',
          'raw-loader',
          'postcss-loader',
          {
            loader: 'sass-loader',
            options: {
              implementation: require('sass'),
              includePaths: ['styles', 'node_modules']
                .map((d) => path.join(__dirname, d))
                .map((g) => glob.sync(g))
                .reduce((a, c) => a.concat(c), []),
            },
          },
        ],
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'url-loader',
        options: {
          name: '[name].[ext]',
          limit: 100000,
        },
      },
    );

    return config;
  },
};
profile
매일 0.1%씩 성장하는 Junior Web Front-end Developer 💻🔥

0개의 댓글