Next12 next.config.js에서 외부 모듈 include 하기

November 05, 2021

Next가 12버전으로 release가 되었다. 금번 nextjs의 경우 babel 대신 swc compiler를 사용하고 있고, webpack 내부의 설정이 변경됨. 따라서, monorepo등을 이용하여 외부 component 등을 설정하여 불러오는 경우, 해당 compiler 에러가 발생할 수 있다.

app project root 외에 별도의 폴더에서 가져오는 경우, 변경된 next12 에서 next.config의 webpack 설정을 변경하여 include에 삽입해야함.

// next.config.js
module.exports = {
  webpack: config => {
    config.module.rules.forEach(rule => {
      console.log('rule ===>', rule);
    });

    return config;
  }
};

이전의 경우 config.module.rules를 forEach로 loop 도는 경우, ts, tsx에 대한 module rules가 array형태로 구성되었으나, 금번부터 ts | tsx의 소스코드의 경우 다음과 같이 구성됨

{
  oneOf: [
    {
      test: /\.(tsx|ts|js|cjs|mjs|jsx)$/,
      include: [Array],
      exclude: [Function: exclude],
      issuerLayer: 'api',
      parser: [Object],
      use: [Object]
    },
    {
      test: /\.(tsx|ts|js|cjs|mjs|jsx)$/,
      include: [Array],
      exclude: [Function: exclude],
      issuerLayer: 'middleware',
      use: [Object]
    },
    {
      test: /\.(tsx|ts|js|cjs|mjs|jsx)$/,
      include: [Array],
      exclude: [Function: exclude],
      use: [Array]
    },
    { test: /a^/, loader: 'noop-loader', options: [Object] },
    {
      test: /\.(css|scss|sass)$/,
      issuer: /pages[\\/]_document\./,
      use: [Object]
    },
    {
      sideEffects: false,
      test: /\.module\.css$/,
      issuer: [Object],
      use: [Array]
    },
    {
      sideEffects: false,
      test: /\.module\.(scss|sass)$/,
      issuer: [Object],
      use: [Array]
    },
    { test: [Array], use: [Object] },
    {
      sideEffects: true,
      test: /(?<!\.module)\.css$/,
      include: [Object],
      issuer: [Object],
      use: [Array]
    },
    {
      sideEffects: true,
      test: /(?<!\.module)\.css$/,
      issuer: [Object],
      use: [Array]
    },
    {
      sideEffects: true,
      test: /(?<!\.module)\.(scss|sass)$/,
      issuer: [Object],
      use: [Array]
    },
    { test: [Array], issuer: [Object], use: [Object] },
    { test: [Array], use: [Object] },
    {
      issuer: /\.(css|scss|sass)$/,
      exclude: [Array],
      type: 'asset/resource'
    },
    {
      test: /\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$/i,
      use: [Object],
      issuer: /pages[\\/]_document\./
    }
  ]
}

oneOf로 구성이 되어 있어, oneOf에 대한 조건을 찾아서 module include에 push 해주어야 함.

config.module.rules.forEach(rule => {
      console.log('rule ===>', rule);
      if (Array.isArray(rule.oneOf)) {
        rule.oneOf.forEach(item => {
          if (Array.isArray(item.include)) {
            item.include.push('include 하고자 하는 javascript path');
          }
        });
      }
    });
...