Как импортировать css внутри компонента в next.js

Пытаюсь импортировать css файл из node_modules внутри собственного component-а, но в результате не получаю никаких ошибок, как собственно и необходимых мне стилей в билде

next.config.js

const fs = require('fs');
const path = require('path');

const withSass = require('@zeit/next-sass');
const withPlugins = require('next-compose-plugins');
const withAntd = require('./next-antd.config');
const lessToJS = require('less-vars-to-js');
const FilterWarningsPlugin = require('webpack-filter-warnings-plugin');

require('dotenv').config();

const isDev = process.env.NODE_ENV !== 'production';
if(isDev) {
    process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
}

const antdVariables = lessToJS(fs.readFileSync(path.resolve(__dirname, './assets/variables.less'), 'utf8'));

// fix: prevents error when .less files are required by node
if (typeof require !== 'undefined') {
    require.extensions['.less'] = file => { }
}

const nextConfig = {
    webpack: config => {
        config.plugins.push(
            new FilterWarningsPlugin({
                // ignore ANTD chunk styles [mini-css-extract-plugin] warning
                exclude: /mini-css-extract-plugin[^]*Conflicting order between:/,
            }),
        );

        return config;
    },
    env
};

module.exports = withPlugins([
        [withSass, {
            cssLoaderOptions: {
                modules: true,
                importLoaders: 1,
                localIdentName: "[local]___[hash:base64:5]",
            },
        }],
        [withAntd, {
            cssModules: true,
            cssLoaderOptions: {
                sourceMap: false,
                importLoaders: 1,
            },
            lessLoaderOptions: {
                javascriptEnabled: true,
                modifyVars: antdVariables,
            },
        }],

], nextConfig);

next-antd.config.js

const cssLoaderConfig = require('@zeit/next-css/css-loader-config');

module.exports = (nextConfig = {}) => ({
    ...nextConfig,
    ...{
        webpack(config, options) {
            if (!options.defaultLoaders) {
                throw new Error(
                    'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade',
                );
            }

            const { dev, isServer } = options;
            const { cssModules, cssLoaderOptions, postcssLoaderOptions, lessLoaderOptions = {} } = nextConfig;

            // for all less in clint
            const baseLessConfig = {
                extensions: ['less'],
                cssModules,
                cssLoaderOptions,
                postcssLoaderOptions,
                dev,
                isServer,
                loaders: [
                    {
                        loader: 'less-loader',
                        options: lessLoaderOptions,
                    },
                ],
            };

            config.module.rules.push({
                test: /\.less$/,
                exclude: /node_modules/,
                use: cssLoaderConfig(config, baseLessConfig),
            });

            // for antd less in client
            const antdLessConfig = {
                ...baseLessConfig,
                ...{ cssModules: false, cssLoaderOptions: {}, postcssLoaderOptions: {} },
            };

            config.module.rules.push({
                test: /\.less$/,
                include: /node_modules/,
                use: cssLoaderConfig(config, antdLessConfig),
            });

            // for antd less in server (yarn build)
            if (isServer) {
                const antdStyles = /antd\/.*?\/style.*?/;
                const rawExternals = [...config.externals];

                config.externals = [
                    (context, request, callback) => {
                        if (request.match(antdStyles)) {
                            return callback();
                        }

                        if (typeof rawExternals[0] === 'function') {
                            rawExternals[0](context, request, callback);
                        } else {
                            callback();
                        }
                    },
                    ...(typeof rawExternals[0] === 'function' ? [] : rawExternals),
                ];

                config.module.rules.unshift({
                    test: antdStyles,
                    use: 'null-loader',
                });
            }

            if (typeof nextConfig.webpack === 'function') {
                return nextConfig.webpack(config, options);
            }

            return config;
        },
    },
});

Я пробовал импортировать @zeit/next-css и добавить его в withPlugins, но это тоже не дало желаемого эффекта


Ответы (1 шт):

Автор решения: qwabra

Как импортировать css внутри компонента в next.js?

вот что говорит оф. док.

"adding-a-global-stylesheet" - добавление стилей глобально

текст ниже - вольный перевод

Чтобы добавить стили в своё приложение - импортируйте css файл тут pages/_app.js.

Пример css файла styles.css:

body {
  font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
    'Arial', sans-serif;
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}

Создайте pages/_app.js (если такого нет). Затем импортируйте styles.css.

// import '../styles.css'
import '../public/styles.css'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

В режиме разработки - поддерживается подгрузка на лету.

В продакшене - все css файлы будут объединены и минимифицырованны.

"adding-component-level-css" - добавление на компонентном уровне

[name].module.css

import styles from './Button.module.css'

export function Button() {
  return (
    <button
      type="button"
      // Note how the "error" class is accessed as a property on the imported
      // `styles` object.
      className={styles.error}
    >
      Destroy
    </button>
  )
}

если не получается - создайте базовый проект

проверено - работает.

$ yarn create next-app

структура базового проекта

$ tree -I node_modules
.
├── package.json
├── pages
│   └── index.js
├── public
│   ├── favicon.ico
│   └── zeit.svg
├── README.md
└── yarn.lock

2 directories, 6 files

структура проекта после создания файлов

$ tree -I node_modules
.
├── package.json
├── pages
│   ├── _app.js
│   └── index.js
├── public
│   ├── favicon.ico
│   ├── styles.css
│   └── zeit.svg
├── README.md
└── yarn.lock

2 directories, 8 files

на компонентном уровне - тоже всё ок.

$ tree -I node_modules
.
├── package.json
├── public
│   ├── favicon.ico
│   ├── styles.css
│   └── zeit.svg
├── README.md
├── src
│   ├── components
│   │   ├── ClickCount.js
│   │   └── ClickCount.module.css
│   └── pages
│       ├── _app.js
│       └── index.js
└── yarn.lock

4 directories, 10 files

содержимое package.json:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "9.2.2",
    "react": "16.13.0",
    "react-dom": "16.13.0"
  }
}

- ,- -, -

→ Ссылка