Next.js: Trabajar con archivos css y scss externos

Creado en 19 oct. 2017  ·  38Comentarios  ·  Fuente: vercel/next.js

Es un problema redundante, lo sé, pero abrí este problema intencionalmente. Son tres días que estoy configurando una plantilla de next.js (con redux, redux-saga, ...) y son dos días que estoy atascado en la configuración de carga de archivos css y scss externos. He comprobado los ejemplos de hoja de estilo global y hoja de estilo de ámbito y postcss , pero cada uno de ellos tiene problemas importantes mencionados en números anteriores. He visto demasiados problemas abiertos y cerrados que están resolviendo este problema con hacks ... Creo que es una buena idea que en lugar de dejar el problema para encontrar la mejor solución, resuélvalo con las soluciones actuales disponibles hasta encontrar una mejor. ¡Porque muchos tienen este problema ahora y quieren verlo resuelto ahora!

Comentario más útil

También me gustaría señalar que personalmente no me gusta el tono de la gente en este número.
Entiendo totalmente que desea importar css. Y somos muy conscientes de esta solicitud. Por eso pasé la semana pasada trabajando en la mejor solución posible 👍
Más sobre esto pronto. Hasta entonces, sean amables y felices fiestas 🎅😄

Todos 38 comentarios

Estoy de acuerdo, solo styled-jsx tiene soporte limpio (incluida la recarga en caliente) y eso es lo que me impide usar Next.js para cualquier cosa, excepto cuando necesito un prototipo rápido.

Creo que la solución a los problemas de alcance de CSS de los módulos CSS es mucho más limpia, además, con los módulos CSS todavía es posible pasar clases a componentes secundarios (intente poner una clase no global en un SVG importado con babel-plugin-inline-react-svg con styled-jsx).

Eso y prefiero tener archivos .css estandarizados para evitar el bloqueo del marco tanto como sea posible y archivos CSS externos en producción para el almacenamiento en caché (y para hacer que los polyfills de MQ como Respond.js funcionen si tienes la mala suerte de todavía tengo que admitir IE8).

Masivo +1
Es una gran frustración que algo tan simple como css / scss externo sea casi imposible de lograr con next.js, lo que lo vuelve inútil para el 90% de mis aplicaciones.

Estoy trabajando con bootstrap y necesito una configuración en la que haya una importación css de bootstrap global, con la adición de css de ámbito externo.

Si bien nos las arreglamos para hacer funcionar el lápiz óptico externo con el estilo jsx 1 (paquete web para manejar la compilación), tuvimos dificultades para resolverlo en el estilo jsx 2 desde que se introdujo el cambio radical en el manejo de archivos css separados.
Enfoque actual:

import ComponentStyles from './footer.styl';
...
      <style jsx>
        {ComponentStyles}
      </style>

Sería genial ver https://github.com/zeit/next.js/tree/master/examples/with-styled-jsx-scss trabajando con archivos scss externos.

Pasamos por la misma prueba al configurar el entorno.
Finalmente, nos conformamos con una hoja de estilo global con scss + post css con lost-grid.
La recarga en caliente funciona, así que aunque no es una solución ideal (debido a que la hoja de estilo global se carga de una vez), es un buen compromiso.

Dependencias

"autoprefixer": "^7.1.6",
"babel-plugin-module-resolver": "^2.7.1",
"babel-plugin-wrap-in-js": "^1.1.1",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"pixrem": "^4.0.1",
"postcss-easy-import": "^3.0.0",
"postcss-loader": "^2.0.8"

En package.json

  ...
  "postcss": {
    "plugins": {
      "lost": {},
      "postcss-easy-import": {
        "prefix": "_"
      },
      "autoprefixer": {},
      "pixrem": {}
    }
  }
  ...

En next.config.js

webpack: (config, { dev }) => {
    config.module.rules.push(
      {
        test: /\.(css|scss)/,
        loader: 'emit-file-loader',
        options: {
          name: 'dist/[path][name].[ext]'
        }
      }
    ,
      {
        test: /\.css$/,
        use: ['babel-loader', 'raw-loader', 'postcss-loader']
      }
    ,
      {
        test: /\.s(a|c)ss$/,
        use: ['babel-loader', 'raw-loader', 'postcss-loader',
          { loader: 'sass-loader',
            options: {
              includePaths: ['styles', 'node_modules']
                .map((d) => path.join(__dirname, d))
                .map((g) => glob.sync(g))
                .reduce((a, c) => a.concat(c), [])
            }
          }
        ]
      }
    )
    return config
  }

En pages/_document.js

...

import stylesheet from 'styles/main.scss'

   ...
        <Head>
          <style dangerouslySetInnerHTML={{ __html: stylesheet }} />
        </Head>
   ...

Y luego puede administrar sus estilos a partir de /styles/main.scss
Espero eso ayude

Mi problema con cada uno de estos dos ejemplos de estilo ( with-global-stylesheet y with-scoped-stylesheets-and-postcss ) es que ninguno de ellos es fácil de integrar con las pruebas de Jest y Snapshot con CSS en la instantánea. Ha habido personas que lograron que Jest funcionara con Webpack, pero eso se logró omitiendo específicamente el CSS.

Ejecutar un archivo de preprocesador babel-jest como se describe en esta respuesta SO parece un truco tan malo.

Parece obtener CSS externo, ya que with-global-stylesheet debe usar Webpack, pero para usar Jest no puede confiar en Webpack, solo en Babel.

¿Alguien tiene ideas en este espacio?

Me enfrento a un problema similar. Soy nuevo en nextjs y no puedo hacer que el ejemplo "with-external-scoped-css" funcione correctamente. A veces, mi css está cargado y otras no. No sé si es el mismo tema del que estás hablando.

https://github.com/zeit/next.js/issues/3276

Se resolvieron problemas de estilos externos con este cargador https://github.com/coox/styled-jsx-css-loader

@ilionic He comprobado tu solución. ¡Es genial! Gracias :)

@arefaslani No creo que este problema esté cerrado.

A partir de HTTP v1, sigue siendo un impuesto de rendimiento horrible para que se carguen toneladas de CSS, aumenta drásticamente el tiempo para dibujar por primera vez.

El soporte de estilo externo adecuado permitiría importar CSS y dar como resultado una no una línea