19 mar 2018

Ładowanie CSS i CSS modules w tym samym czasie Webpack

W react możemy importować css jak i css jako moduły.
Ale co jeśli chcemy zrobić do w tym samym czasie powiedzmy dodać globalny styl np. normalize.css?

Importowanie jako moduł:

import React from 'react'
import styles from './moj-komponent.css';

const MyComponent => <div className={styles.jakasKlasa}></div>

No ale jak użyć css powiedzmy jakieś zewnętrznej biblioteki:

import React from 'react'
import './moj-komponent-zewnetrzny.css';

const MyComponent => <div className="jakasKlasa"></div>

Aby tego dokonać należy zmodyfikować webpack. Ja korzystam z create-react-app i modyfikuję zarówno wersję dev jak i prod webpacka.

module: {
    rules: [
        {
            // wcześniej było /\.css$/
            test: /^(?!.*?\.module).*\.css$/, 
            
            // dalej zostawiamy jak było czyli 
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                  modules: true,
                  localIdentName: '[name]__[local]__[hash:base64:5]'
                },
                ...
        },
        // dodajemy następną regułę dla zewnętrznych css
        {
            test: /\.module\.css$/,
            use: [
                require.resolve('style-loader'),
                require.resolve('css-loader')
            ],
        },
    ]
}

Teraz możemy użyć w jednym komponencie zarówno css modułów jak i zewnętrznych bibliotek.
Należy pamiętać że zewnętrzny komponent musi mieć w nazwie *.module.css

import React from 'react'
import styles from './moj-komponent.css';
import './jakis-zewnetrzny.module.css'

const MyComponent => <div className={`${styles.jakasKlasa} jakas-klasa-z-zewnatrz`}></div>

W wersji produkcyjnej webpack kopiuję całą regułę css i wstawiam poniżej,
zmieniam test: /\.css$/, na test: /\.module\.css$/,
Ustawiam modules: false i tyle.