7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

nextjsでmaterial-uiを導入した時にコンパイルエラーでハマった話

Last updated at Posted at 2019-12-25

はじめに

next.jsでmaterial-uiで使用されているフォントを導入した時に以下のコンパイルエラーでハマったので解法を記録しておきます。

compile_error
./node_modules/typeface-roboto/index.css 2:0
Module parse failed: Unexpected character '@' (2: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
| /* roboto-100normal - latin */
> @font-face {
|   font-family: 'Roboto';
|   font-style: normal;

結論

このissueの通りに対処すれば動きます。
https://github.com/zeit/next-plugins/issues/432

yarn add @zeit/next-css
yarn add -D url-loader
next.config.js
const withCSS = require("@zeit/next-css");
module.exports = withCSS({
  webpack: config => {
    config.module.rules.push({
      test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
      use: {
        loader: "url-loader",
        options: {
          limit: 100000,
          name: "[name].[ext]"
        }
      }
    });
    return config;
  }
});

コンパイルエラー発生までの流れ

nextjs導入

公式のDocに従ってnextjsを導入します。
https://nextjs.org/learn/basics/getting-started/setup

yarn init -y
yarn add react react-dom next
mkdir pages
package.json
"scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
},
pages\index.js
const Home = () => <h1>Hello World!</h1>;

export default Home;
yarn dev

ここまでは何の問題も無くHelloWorldが表示されるはずです。

material-ui導入

続いてmaterial-uiを導入
公式が入れろと言ってるのでフォントも一緒に入れる
https://material-ui.com/getting-started/installation/

yarn add @material-ui/core typeface-roboto
pages\index.js
+ import "typeface-roboto";

ここでyarn devを行うと以下のコンパイルエラーが発生します。

compile_error
./node_modules/typeface-roboto/index.css 2:0
Module parse failed: Unexpected character '@' (2: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
| /* roboto-100normal - latin */
> @font-face {
|   font-family: 'Roboto';
|   font-style: normal;

解決法

結論で貼ったissueの通りに対処すると無事私達のHelloWorldが帰ってきます。
再度掲示します。

yarn add @zeit/next-css
yarn add -D url-loader
next.config.js
const withCSS = require("@zeit/next-css");
module.exports = withCSS({
  webpack: config => {
    config.module.rules.push({
      test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
      use: {
        loader: "url-loader",
        options: {
          limit: 100000,
          name: "[name].[ext]"
        }
      }
    });
    return config;
  }
});

なぜ治るのか

これで終わってはissueを貼っただけで味気ないのでなぜこれで治るのかを考えます。

next.config.jsで何をしているのかを考えます。
testに記載した正規表現にマッチするファイルはパースの際にuse内に記載したloaderを使う といったconfigを作成しwebpackに設定する、といった事をしています。

今回導入したtypeface-robotoindex.cssを見るとわかるように@font-faceを使って拡張子がwoff, woff2のファイルを読み込んでいます。

typeface-roboto\index.css
/* roboto-100normal - latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-display: swap;
  font-weight: 100;
  src:
    local('Roboto Thin '),
    local('Roboto-Thin'),
    url('./files/roboto-latin-100.woff2') format('woff2'), /* Super Modern Browsers */
    url('./files/roboto-latin-100.woff') format('woff'); /* Modern Browsers */
}

webpackはデフォルトだとこのような特殊な拡張子のファイルは上手くパースできません。

よってこのようにnext.config.jsで明示的に特殊なparser(今回はurl-loader)を指定してあげることによってパースを成功させることができます。

勿論今回parserが必要なのはwoff, woff2だけなので正規表現にこれら2つだけ記載した場合でも動きます。

webpackのloaderについての解説はこの方の記事がわかりやすかったです。
https://qiita.com/takano-h/items/1a6a5a0b9d25a677f7d2

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?