NuxtでCheerioを使ってHTMLパースを使用しようとするとエラーが出るので、使えるようにします。

環境

  • Nuxt: 2.15.8
  • Vue: 2.6.14

問題

以下のようにNuxt環境でcheerioを使用するコードがあります。

import * as cheerio from 'cheerio'

const $ = cheerio.load('<div>test</div>')

上記のコードを含めてビルドすると以下のようなエラーが出ます。

ERROR in ./node_modules/htmlparser2/lib/esm/index.js 48:9
Module parse failed: Unexpected token (48:9)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|  * They should probably be removed eventually.
|  */
> export * as ElementType from "domelementtype";
| import { getFeed } from "domutils";
| export { getFeed } from "domutils";
 @ ./node_modules/cheerio/lib/esm/index.js 11:0-68 13:6-26
## 省略 ##

ERROR in ./node_modules/cheerio/node_modules/parse5/dist/index.js 7:9
Module parse failed: Unexpected token (7:9)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| export { ERR as ErrorCodes } from './common/error-codes.js';
| /** @internal */
> export * as foreignContent from './common/foreign-content.js';
| /** @internal */
| export * as html from './common/html.js';
 @ ./node_modules/cheerio/lib/esm/parsers/parse5-adapter.js 2:0-79 22:10-23 23:10-23 48:18-32
 @ ./node_modules/cheerio/lib/esm/index.js
## 省略 ##

ERROR in ./node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5/dist/index.js 7:9
Module parse failed: Unexpected token (7:9)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| export { ERR as ErrorCodes } from './common/error-codes.js';
| /** @internal */
> export * as foreignContent from './common/foreign-content.js';
| /** @internal */
| export * as html from './common/html.js';
 @ ./node_modules/parse5-htmlparser2-tree-adapter/dist/index.js 1:0-30 35:25-29
 @ ./node_modules/cheerio/lib/esm/parsers/parse5-adapter.js
 @ ./node_modules/cheerio/lib/esm/index.js
## 省略 ##

 FATAL  Nuxt build error

  at WebpackBundler.webpackCompile (node_modules/@nuxt/webpack/dist/webpack.js:2127:21)
  at processTicksAndRejections (node:internal/process/task_queues:96:5)
  at async WebpackBundler.build (node_modules/@nuxt/webpack/dist/webpack.js:2076:5)
  at async Builder.build (node_modules/@nuxt/builder/dist/builder.js:327:5)
  at async Object.run (node_modules/@nuxt/cli/dist/cli-build.js:110:7)
  at async NuxtCommand.run (node_modules/@nuxt/cli/dist/cli-index.js:413:7)

   ╭─────────────────────────────╮
   │                             │
   │   ✖ Nuxt Fatal Error
   │                             │
Error: Nuxt build error   │
   │                             │
   ╰─────────────────────────────╯

解決策

解決策としては、webpackにcheerio用のローダーを読み込ませることで使用できるようになります。

以下のようにnuxt.config.tsを変更します。

nuxt.config.ts
export default {
  /* 略 */
  build: {
    extend(config: any) {
      // htmlparser2 loader
      config.module.rules.push({
        test: /\/node_modules\/htmlparser2\/lib\/esm\/index\.js$/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env'],
        },
      })
      // cheerio loader
      config.module.rules.push({
        test: /\/node_modules\/cheerio\/node_modules\/parse5\/dist\/index\.js$/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env'],
        },
      })
      // parse5-htmlparser2-tree-adapter loader
      config.module.rules.push({
        test: /\/node_modules\/parse5-htmlparser2-tree-adapter\/node_modules\/parse5\/dist\/index\.js$/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env'],
        },
      })
    },
  },
  /* 略 */
}

これで読み込めるようになるはずです。