요즘 너무나도 많은 곳에서 사용되고 있는 Next.js 프레임워크가 벌써 13 version까지 나왔다.
사내 프로젝트 애플리케이션은 Next.js 10 version을 사용 중인데, 더는 늦어지면 안될 것 같아 이번 기회에 11 version 으로 한 단계 업그레이드를 진행해보았다.
업그레이드 명령어
$yarn add next@11
또는 upgrade
를 사용하여 패키지를 업그레이드를 할 수 있다.
$yarn upgrade next@11
(단, 이 yarn upgrade 명령어로 패키지를 업그레이드 하고자 할 경우, 꼭 이 문서를 참고하도록 하자)
위의 명령어로 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.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;
},
};