monaco-editorをwebpackでバンドルする

問題

monaco-editorを以下のようなloader設定とplugin設定でバンドルしようとしたらハマった。

const path = require('path')
const config = {
  externals: ["electron"],
  target: "electron-renderer",
  entry: "./src/renderer/index.tsx",
  plugins: [], //←重要,
  output: {
    path: path.join(__dirname, "dist"),
    filename: "renderer.js"
  },
  module: {
    rules: [ //←重要
      {
        test: /.tsx$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
    ]
  }
}

module.exports = config

エラー内容はこんなかんじで 下部分で重要そうな問題だけコピペしてきた

    ERROR in ./node_modules/monaco-editor/esm/vs/editor/contrib/find/findWidget.css 8:0
    Module parse failed: Unexpected token (8:0)
    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
    | /* Checkbox */
    |
    > .monaco-checkbox .label {
    |   width: 12px;
    |   height: 12px;
     @ ./node_modules/monaco-editor/esm/vs/editor/contrib/find/findWidget.js 18:0-26
     @ ./node_modules/monaco-editor/esm/vs/editor/contrib/find/findController.js
     @ ./node_modules/monaco-editor/esm/vs/editor/editor.all.js
     @ ./node_modules/monaco-editor/esm/vs/editor/edcore.main.js
     @ ./node_modules/monaco-editor/esm/vs/editor/editor.main.js
     @ ./src/renderer/components/monaco-editor.tsx
     @ ./src/renderer/index.tsx

    ERROR in ./node_modules/monaco-editor/esm/vs/editor/contrib/gotoError/media/gotoErrorWidget.css 8:0
    Module parse failed: Unexpected token (8:0)
    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
    | /* marker zone */
    |
    > .monaco-editor .peekview-widget .head .peekview-title .icon.warning {
    |   background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMTYgMTYiIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTcuNSAyTDIgMTJsMiAyaDlsMi0yTDkuNSAyeiIvPjxwYXRoIGQ9Ik05IDNIOGwtNC41IDkgMSAxaDhsMS0xTDkgM3ptMCA5SDh2LTFoMXYxem0wLTJIOFY2aDF2NHoiIGZpbGw9IiNmYzAiLz48cGF0aCBkPSJNOSAxMEg4VjZoMXY0em0wIDFIOHYxaDF2LTF6Ii8+PC9zdmc+") center center no-repeat;
    | }
     @ ./node_modules/monaco-editor/esm/vs/editor/contrib/gotoError/gotoErrorWidget.js 18:0-37
     @ ./node_modules/monaco-editor/esm/vs/editor/contrib/gotoError/gotoError.js
     @ ./node_modules/monaco-editor/esm/vs/editor/editor.all.js
     @ ./node_modules/monaco-editor/esm/vs/editor/edcore.main.js
     @ ./node_modules/monaco-editor/esm/vs/editor/editor.main.js
     @ ./src/renderer/components/monaco-editor.tsx
     @ ./src/renderer/index.tsx

CSS読み込もうとしたけど、僕の書いてるwebpack.config.jsにstyle-loader系の記述が入ってなくて、依存関係を解決しようとしたときにcssにぶち当たって死んでそうな雰囲気。

解決

とりあえずstyle-loaderとcss-loader入れれば解決するかなと大体当たりがついたので、インターネット上で似た事例がないかだけ一旦調査してみたところ、MSが作ってる専用のwebpack-pluginを使えばいいということがわかった。

1 以下のコマンドで専用のプラグインと必要なloaderを入れる

yarn add --dev monaco-editor-webpack-plugin css-loader style-loader

2 webpack.config.js に先程いれたプラグインとloaderを使うように変更

const path = require('path')
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const config = {
  externals: ["electron"],
  target: "electron-renderer",
  entry: "./src/renderer/index.tsx",
  plugins: [new MonacoWebpackPlugin()], //←重要,
  output: {
    path: path.join(__dirname, "dist"),
    filename: "renderer.js"
  },
  module: {
    rules: [ //←重要
      {
        test: /.tsx$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        // 追加されたシリーズ
        test: /\.css$/,
        use: ["css-loader", "style-loader"]
      }
    ]
  }
}

module.exports = config

これでビルドが通るようになったのでよかったね。

参考文献

欲求ボタン