Next.js: ¿Importando archivos CSS?

Creado en 27 dic. 2016  ·  102Comentarios  ·  Fuente: vercel/next.js

A veces es bueno dividir su CSS en un archivo .css separado. Intenté hacer lo siguiente:

pages/
└── index
    ├── index.css
    ├── index.js
    └── component.js

Luego, en index.js, intenté hacer:

import css from './index.css'

Y en next.config.js:

module.exports = {
  webpack: function (config) {
    config.module.loaders = (config.module.loaders || []).concat({
      test: /\.css$/, loader: 'raw'
    })
    return config
  }
}

Pero, lamentablemente, me sigue dando:

 ERROR  Failed to compile with 1 errors

This dependency was not found in node_modules:

* ./index.css

Parece que no se está resolviendo en el lugar correcto por alguna razón, aunque el local component.js funciona a través de import component from './component.js' , así que no estoy seguro de qué está pasando aquí.

Comentario más útil

Aquí hay una solución simple para importar archivos CSS usando babel-plugin-inline-import :

.babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "inline-import",
      {
        "extensions": [".css"]
      }
    ]
  ]
}

página / componente

import "prismjs";

import { PrismCode } from "react-prism";
import prismGlobalStyles from "prismjs/themes/prism.css";

export default () => {
    return (
        <div>
            <style global jsx>
                {prismGlobalStyles}
            </style>
            <PrismCode className="language-javascript">
                {`function(noop) {
                    return noop;
                }`}
            </PrismCode>
            {/* ... */}
        </div>
    );
};

Todos 102 comentarios

¿Quiere decir que esto no funciona en el servidor?
Creo que todavía no tenemos una solución para esto. cc @arunoda

Ah, claro, supongo que debería haber una forma de que la configuración del paquete web en next.config.js funcione en ambos lados para que esto funcione.

Tengo una especie de problema similar en el estadio de béisbol en el que parece que no puedo hacer que Next juegue bien con CSS o SASS. Tengo un directorio components con componentes estándar de React, ya que importo a mis páginas, pero cada vez que intento importar archivos SASS (o CSS), aparece un ~ "necesita usar el cargador apropiado para este archivo" escriba el mensaje de error.

Generalmente, en React, importo archivos SASS y hago que Webpack compile usando cargadores de estilo, css y sass. Intenté agregarlos al archivo next.config.js (y NPM los instaló) pero sigo recibiendo el mismo mensaje de error.

Mi archivo next.config.js :

module.exports = {
  webpack: (config, { dev }) => {
    config.module.rules.push({ test: /\.scss$/, loader: ['style-loader', 'css-loader', 'sass-loader'] });
    return config;
  }
}

Lo siento si estas preguntas suenan tontas o me he perdido algo obvio en los documentos que explican las respuestas, pero si alguien tiene un ejemplo funcional de importación / compilación de SASS (o al menos CSS) en un componente o una página con lo que sea necesario para agregar a next.config.js para cargarlos / compilarlos, lo agradecería enormemente. ¡Gracias!

Estoy usando css-modules-require-hook
para hacer que CSS funcione.

@spacedragon ¿Tiene un ejemplo de cómo integrar css-modules-require-hook con Next.js? Tengo problemas para que funcione.

Todavía tengo problemas para hacer que SASS compile si alguien pudiera arrojar algo de luz sobre cómo hacer esto o simplemente importar un archivo CSS dentro de Next, sería apreciado (a través de un ejemplo de código).

Es interesante que el archivo README se haya actualizado para eliminar el ejemplo del cargador SVG y se haya cambiado para decir que se desaconseja agregar cargadores para archivos como SVG, CSS y SASS. No estoy seguro de por qué CSS en línea está bien, pero CSS importado no lo es, pero estoy seguro de que hay una buena razón para ello. Actualmente no estoy seguro de cuál es la mejor estrategia para manejar ningún CSS y SASS definidos / en línea de JS.

@MikeDigitize Ver comentario sobre # 627 y # 638.

De hecho, es posible y bastante fácil procesar estilos en el lado del servidor.

directamente en el nodo:

require.extensions['.css'] = function(file) {
    console.log(file.id)
    return;
}

a través del registro babel:

// from https://babeljs.io/docs/core-packages/babel-register/
require("babel-register")({
  // Optional ignore regex - if any filenames **do** match this regex then they
  // aren't compiled.
  ignore: /regex/,

  // Ignore can also be specified as a function.
  ignore: function(filename) {
    if (filename === '/path/to/es6-file.js') {
      return false;
    } else {
      return true;
    }
  },

  // Optional only regex - if any filenames **don't** match this regex then they
  // aren't compiled
  only: /my_es6_folder/,

  // Setting this will remove the currently hooked extensions of .es6, `.es`, `.jsx`
  // and .js so you'll have to add them back if you want them to be used again.
  extensions: [".es6", ".es", ".jsx", ".js"]
});

a través de cargadores de paquetes web:

Yo personalmente uso isomorphic-style-loader ya que me permite incorporar CSS crítico mientras renderizo en el servidor. La recarga en caliente y otras cosas relacionadas con DX también funcionan. Realmente no soy fanático de CSS en JS, ya que complica el uso de componentes de terceros y, de alguna manera, quita la C de CSS.

@viktorbezdek ¿Ha utilizado con éxito el cargador de estilo isomorfo con next.js?

@noeljackson No realmente, pero tengo la intención de hacerlo. Next.js parece prometedor y podría ahorrarme mucho tiempo si lo hago funcionar. Lo investigaré en las próximas una o dos semanas y enviaré una solicitud de extracción si tengo éxito.

@viktorbezdek Daré una recompensa por este, ya que es realmente crucial para un proyecto en el que estoy trabajando. Sé que no soy un inepto, pero no entiendo cómo depurar las transformaciones de Babel lo suficiente como para resolver esto. Probé la permutación de estas ideas y nada funciona al 100%. He podido conseguir que raw-loader extraiga una hoja de estilo con codificación de datos utilizando babel-plugin-webpack-loaders, pero ninguno de los cargadores de estilo funciona. ¡Gracias por participar! :) Muy apreciado.

¿Hay una solución para esto? Me gustaría ver una solución para no tener que incluir css a nivel mundial.

FWIW, acabo de poner mis archivos CSS en la carpeta /static . No es una gran colocación, pero tampoco mucho.

Habrá una solución. Simplemente no logré terminarlo. Tengo el primer prototipo local que parece funcionar, sin embargo, necesita pocas horas para estar terminado. Estoy bastante seguro de que terminaré después del fin de semana. Manténganse al tanto.

@matthewmueller ¿Está utilizando módulos CSS?

@viktorbezdek ¡ Gracias por trabajar en esto! El soporte de módulos CSS (o similar) es importante para este proyecto en mi opinión. El estilo jsx está bien para situaciones simples, pero es difícil de leer para componentes con mucho estilo.

¿Un complemento de babel como este sería una opción (también del lado del servidor)? https://github.com/gajus/babel-plugin-react-css-modules

Intenté que esto funcionara pero no tuve suerte: /

Tengo módulos CSS que funcionan con babel-plugin-css-modules-transform . Mira mi ejemplo hacky en mi tenedor .

La desventaja es que tienes que matar el servidor y reiniciarlo cada vez que realizas un cambio en el CSS.

Algunos componentes de React exponen el estilo predeterminado a través de un recurso estático import able. Por ejemplo, para importar el estilo predeterminado de https://github.com/react-component/slider se usaría:

import 'rc-slider/assets/index.css';

Seguro que es posible copiar y pegar esta hoja de estilo en el directorio static/ pero no se sincronizará con el estilo anterior en una futura actualización del componente y no coincide con lo que recomienda la documentación de este componente.

El problema es que esos archivos CSS introducen efectos globales. Necesitamos ser capaces de _capturar_ el CSS y ponerlo dentro del ciclo de vida de React, para que se desmonte, renderice en el servidor, etc.

Muchas bibliotecas hacen eso, pero no creo que sea un buen patrón.

No estoy familiarizado con los aspectos internos de Zeit Next, pero ¿podría usarse algún análisis estático de import para registrar / capturar el CSS?

Podríamos, pero sería realmente extraño. Similar a algo que está fuera de render() insertándose mágicamente dentro del ciclo de vida de su componente.

// Pensé que compartiría esto con alguien más

Bueno ... acabo de pasar demasiado tiempo tratando de piratear CSS aquí, PERO encontré una solución que funciona (para mí). Es cierto que es un truco, pero la recarga en caliente funciona y también lo hace la construcción del lado del servidor.

Usando (_shudder_) gulp, con este gulpfile (https://gist.github.com/auser/25e88e39d83413773c01f4c000ec2806) todos los archivos **/*.scss se concatenan y se colocan en un componente Styles que se montan la página como un elemento "normal".

Espero que esto ayude a alguien más hasta que podamos obtener un verdadero soporte postcss en el próximo.

Gracias por el truco @auser , ¡he estado mirando la configuración del paquete web todo el día sin suerte!

Editar:
Por cierto, ¡necesitas agregar un analizador sass al gulpfile!

Sí y no ... Solo uso la extensión .scss como una forma de diferenciar los archivos css puros de los precompilados. Dado que postcss (con precss ) imita bastante bien el descaro, no tengo uno. Siéntase libre de editar usted mismo con un analizador sass.

Parece que esa es actualmente la mejor solución, usar gulp para compilar el archivo css y compilarlo en línea o incluso en / static si no le importa no tener una recarga en caliente.

Obtuve css import + hot reload funcionando de manera limpia. El CSS se importa como una cadena y el usuario puede insertarlo en la página como cualquier otra cadena. Por favor, eche un vistazo a este ejemplo, ayúdeme a probar y los RP son bienvenidos.

https://github.com/davibe/next.js-css-global-style-test

Creo que este ejemplo debería convertirse en ejemplos oficiales de next.js. ¿Lo hace? @rauchg @arunoda @nkzawa (lo siento si

@davibe gracias por su demostración y babel-plugin-wrap-in-js

En el ejemplo, veo el uso de un archivo CSS y un archivo SCSS. ¿Sabes si esto funcionaría con postcss y cssnext?

@ khrome83 No veo por qué no, creo que es solo una cuestión de ajustar .babelrc y next.config.js

@davibe Descubrí que no pude implementar mi aplicación en función de su configuración. La compilación no pudo leer next/babel en el archivo .babelrc . Envié un problema, pero tengo muchas esperanzas de que surja una solución a todo esto. Falta la facilidad de import file.css de create-react-app , pero sé que debe haber una solución en camino :)

La solución que quiero es probablemente en estas líneas:

https://github.com/zeit/styled-jsx/pull/100#issuecomment -277133969

Podríamos programa permite importar .css (por medio de simplemente transpiling en un módulo que las exportaciones (una cadena) y del mismo modo que podrían apoyar .svg por transpiling en una pura reaccionar componente)

y del mismo modo podríamos admitir .svg transformándolo en un componente de reacción puro

Este es un truco bastante simple. Crearé un ejemplo básico que muestre cómo manejé esto en otro proyecto =)

EDITAR: consulte https://github.com/zeit/next.js/pull/982

Basado en la muestra de @davibe , he creado https://github.com/moxystudio/next.js-style-loader que, con suerte, facilitará la adición de archivos css en proyectos next.js. Es similar al style-loader del paquete web en el sentido de que agregará / eliminará hojas de estilo a medida que el usuario navega. También es compatible con SSR.

Funciona bien con css-loader (con y sin módulos css), postcss-loader , sass-loader y posiblemente otros. Tenga en cuenta que cuando se usa css-loader, su opción url debe establecerse en false beucase next.js, las imágenes, fuentes, etc.deben vivir /static . Encontrarás toda esta información en el archivo README.

¡Disfruta y dame tu opinión!

¡Gracias por el repositorio! Funcionó para importar los archivos css. Estoy probando blueprintjs y parece que el CSS se está cargando correctamente. Sin embargo, la regla @ font-face que incluye el CSS no parece funcionar. :

--------------------editar----------------------

En realidad está funcionando, ¡mal!
Sin embargo, los íconos no se cargan porque el enrutamiento de nextjs por defecto no permite servir contenido estático fuera / estático / y la ruta relativa en realidad hace que se cargue con una ruta que no está permitida.

@pencilcheck sí, debe usar rutas que apunten a / static, quizás lo

¿Existe alguna solución alternativa con respecto a la ruta relativa incluida en los archivos css, como fonts atm? ¿O simplemente tengo que copiar todos los archivos de fuentes y CSS en una carpeta estática para que funcione?

@pencilcheck los archivos CSS pueden permanecer fuera de la estática. Sus imágenes y fuentes deben estar dentro de estáticas y las referencia con /static/file .

Lo entiendo. Sin embargo, estoy usando blueprint, que es un paquete npm, me gustaría poder no tener que modificar ningún archivo dentro de node_modules.

@pencilcheck Desafortunadamente, eso no es posible. next.js es muy estricto en la forma en que maneja las imágenes y otros activos. No contaminemos esta conversación y por favor cree un problema en el repositorio next-style-loader si puede.

@tgoldenberg, ¿puedes describir mejor el problema o decirme cómo reproducirlo? por favor consulte mi repositorio. Es más fácil para mí rastrear los problemas allí.

@davibe , terminó siendo un problema usar yarn sobre npm install . Yarn arrojaba algunos errores inexplicables, pero una vez que lo eliminé, el ejemplo funcionó bien en producción.

Pasé 4 horas tratando de configurar esto y pensé que podría ser de interés para cualquiera que busque ahorrar algo de tiempo. Aplica estilos automáticamente al cambiar (como en el ejemplo actual), ejecuta CSS a través de PostCSS y le da nombres de módulos locales desde css-loader . La falta de este último fue un factor decisivo para mí en el estado actual de los ejemplos de “css global” / “importaciones css”.

componente.js

import React from 'react';
import stylesheet from './styles.css';

const [css, className] = stylesheet;
const Component = () => (
    <p className={className.paragraph}>
        <Head><style dangerouslySetInnerHTML={{__html: css}} /></Head>
        bazinga
    </p>
);

.babelrc

{
    "presets": [
        "next/babel"
    ],
    "plugins": [
        ["wrap-in-js", {
            "extensions": ["css$"]
        }]
    ]
}

next.config.js
Observe el increíble truco con exports-loader . Tiene que haber una forma mejor, ¿¿¿¿¿¿¿¿¿¿¿¿??

module.exports = {
    webpack: (config) => {
        config.module.rules.push(
            {
                test: /\.css$/,
                use: [
                    {
                        loader: 'emit-file-loader',
                        options: {
                            name: 'dist/[path][name].[ext]'
                        }
                    },
                    {
                        loader: 'raw-loader'
                    },
                    {
                        loader: 'val-loader'
                    },
                    {
                        loader: 'exports-loader',
                        options: {
                            0: 'exports[0][1]',
                            1: 'exports.locals'
                        }
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            minimize: true
                        }
                    },
                    {
                        loader: 'postcss-loader'
                    }
                ]
            }
        );

        return config;
    }
};

Yo mismo se me ocurrió una solución, que es muy similar a lo que @satazor publicó más arriba en el hilo: https://github.com/jozanza/next-css-json-loader.

Simplemente agregue algunas líneas a su next.config.js :

module.exports = {
  webpack: config => {
    config.module.rules.push({
      test: /\.css$/,
      loader: 'emit-file-loader',
      options: {
        name: 'dist/[path][name].[ext]',
      }
    }, {
      test: /\.css$/,
      loader: 'babel-loader!next-css-json-loader',
    });
    return config;
  },
};

Los estilos se importan como objetos js, por lo que es muy fácil de usar con glamor y soluciones similares:

// .css files now conveniently expose all styles as js objects
import styles from 'some-package/styles.css';
import { css } from 'glamor';
// ...
<div {...css(styles)}>
  this is a nice box. 
</div>

¡Salud! 🍻 :)

¿Hay alguna forma de hacer que esto funcione para importar archivos de rebajas como cadenas? Actualmente estoy usando raw-loader, pero como es un complemento de paquete web, no funciona en el servidor.

@kristojorg

Acabo de escribir un complemento de babel para la importación de rebajas. En mi móvil ahora mismo, pero si ve mi GitHub, lo verá.

@ khrome83 eso suena increíble. Espero con ansias probar esto

¡Gracias @ khrome83! Le daré una oportunidad

Tuve que hacer esto muy rápido, así que no actualicé el archivo Léame. Pero solo lo incluye como un complemento de babel y luego usa

importar archivo desde 'File.md';

Lo hice funcionar, gracias !! Muy útil

Esto es fuera de tema, pero como el problema está cerrado, me siento libre de explicarlo :)

Para la rebaja, hay 2 cosas que puede hacer.

(1)
Una es incluir el archivo de rebajas como una cadena y luego traducirlo a html / react en tiempo de ejecución. Puede hacer esto usando el cargador genérico examples/with-globa-stylesheet/.babelrc para css.

(2)
Otra cosa que puede hacer es traducir markdown en el tiempo de transpilación usando markdown-in-js
Esto puede ser más interesante en algún escenario porque el documento de rebajas ya está pre-renderizado, por lo tanto, en tiempo de ejecución es más rápido (solo ejecuta js). Además, la biblioteca le permite dañar componentes personalizados de React. Desafortunadamente, en este caso, debe escribir la rebaja en línea en su source.js así .

Si elige (2), también sepa que hay un complemento de átomo que proporciona hilight de sintaxis para la sintaxis de markdown-in-js y se llama language-markdown-in-js

@davibe ¡ gracias por el consejo! Preferiría que el markdown se analice como tiempo de compilación, pero el único problema que tengo con markdown-in-js es escapar de las comillas invertidas mientras escribo :(. Tal vez debería intentar importar como una cadena usando babel y luego alimentar eso a markdown-in-js ?

@kristojorg

Están sus renders de rebajas. La razón por la que escribí mi complemento fue la misma. Hago markdown como una cadena, luego lo ejecuto a través de react-markdown. Esto funciona cada vez más bien porque puedo pasar componentes de reacción para representar piezas de renderizado con rebajas, como el componente List para manejar todas las listas. Funciona bien con Styled JSX.

¿Hay alguna actualización sobre esto? A través de los comentarios anteriores, veo que todavía no hay soluciones perfectas actualmente.
@arunoda
¿Es posible tener un ejemplo usando isomorphic-style-loader - https://www.npmjs.com/package/isomorphic-style-loader?

¡Eso sería perfecto!

¿Alguien tiene una solución para la importación de un componente de reacción del paquete npm que a su vez importa un archivo .css o .scss? así que básicamente transpilar archivos que se importan desde node_modules

He estado usando Create-React-App (CRA) durante algunas semanas, pero hoy me encontré con Next.js y me emocioné mucho porque CRA actualmente no admite la representación del lado del servidor (SSR), lo cual es una verdadera lástima.
Me encantaría cambiar a Next.js por su soporte SSR listo para usar, pero no poder importar archivos .scss me está frenando.
¿Alguien ha encontrado una manera de agregar un cargador SASS a la configuración de Webpack?

De acuerdo con cr101, no tener soporte para CSS / SASS significa que tengo que descartar los frameworks CSS como base, lo cual no es una opción para mí.

Estaba usando el repositorio proporcionado por @davibe, pero él ya no lo mantiene, y la última compilación rompe con la solución que tenía .

Me encantaría que alguien encontrara una solución para esto. La actualización a 2.4.1 era absolutamente necesaria debido al error de seguridad, por lo que no tengo la opción de volver a bajar.

@Yuripetusko @ cr101 @tgoldenberg Absolutamente de acuerdo. Honestamente, creo que lo siguiente es realmente asombroso para poder trabajar de inmediato. Todo está bien, incluso la estructura codificada (como el directorio obligatorio /pages , /static etc.). Pero los módulos scss totalmente no compatibles nos rompen todo. Tenemos una estructura scss compleja con puntos de interrupción automáticos y recálculo de la relación de aspecto de todo. Trabajamos muy duro para que nuestra estructura fuera tan perfecta. Lo siguiente es genial, ya que no podemos simplemente tirar todas las cosas scss que tenemos en este momento. El scss no admitido es lo único, pero lo más importante, que nos impide migrar a esta hermosa herramienta.

En realidad, # 1615 - hay algo de acción. @timmywil está intentando configurar isomorphic-style-loader para que funcione con next . Todos los interesados ​​son bienvenidos a unirse y participar.

Probé todas las soluciones, a las que apunta este hilo, sin embargo, podría hacer que cualquiera de ellas funcione. Así que decidí intentar hacer mi propio intento y lo he documentado aquí.

@almeynman ¡ gracias! ¡Definitivamente voy a ver en tu acercamiento!
Por cierto, he logrado que los módulos scss funcionen siguiendo este ejemplo. Todo lo que he hecho es agregar sass-loader y habilitar mapas de origen.

Logré hacer next.js suport CSS (incluso SCSS) de esta manera.

Primero, en next.config.js , modifique la configuración del paquete web agregando cargadores dados y una instancia DefintPlugin .

const webpack = require('webpack');

module.exports = {
  webpack: (config, {dev}) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        'sass-loader'
      ],
      exclude: /node_modules/,
    });

    config.plugins.push(
      new webpack.DefinePlugin({
        "process.env": {
          // flag to indicate this is for browser-side
          BROWSER: JSON.stringify(true),
       }
      })
    );

    return config;
  }
};

Luego, en el código del componente, se requiere un archivo de estilo con condición. Se asegura de que solo la agrupación del lado del navegador tenga un módulo de estilo.

if (process.env.BROWSER) {
  require("./style.scss");
}

Si no le importa el if (process.env.BROWSER) , funciona perfectamente.

Un buen enfoque está aquí

@almeynman En mi opinión, ese no es un buen enfoque, ya que está cargando el código CSS para todo el sitio web en cada página en lugar de cargar solo los estilos CSS relevantes para esa página.
Importar solo los archivos .scss que necesita en lugar del CSS para todo el sitio web reduciría en gran medida el tamaño de las páginas al cargar solo el código CSS que necesita.

@ cr101 Hola, no lo sabía. Realmente no he usado esa configuración, solo la publiqué como referencia para otros (pensé que es buena ...). Todavía utilizo mi enfoque descrito en la publicación del blog . Si pudiera darme algunos comentarios sobre esa configuración sería genial

Más ejemplos y discusiones si alguien está interesado:

https://github.com/iaincollins/nextjs-starter
https://github.com/zeit/next.js/issues/2534
https://github.com/zeit/next.js/tree/v3-beta/examples/with-global-stylesheet

Basado en lo anterior y en este hilo, pude usar PostCSS para transformar:

  • Archivo SCSS global (los módulos son iguales, solo necesita un punto de entrada para precompilar todo su CSS para la producción).
  • CSS independiente de terceros con fuentes personalizadas a las que se hace referencia a través de una URL relativa (resuelto a través de la magia en línea).

en un solo archivo CSS en /static/styles/app.css para servir en producción, con la recarga en caliente aún funcionando. Observe el uso de styled-jsx pero se puede hacer sin él, usando <style dangerouslySetInnerHTML={} />

postcss.config.js

module.exports = {
  plugins: [
    require("postcss-easy-import")({ prefix: "_" }), // keep this first
    require("postcss-url")({ url: "inline" })
  ]
};

next.config.js

Cargadores para transformar .scss en modo dev para recargar en caliente y extraer a un solo archivo .css en prod. Esto me da build/app.css así que en la compilación de producción, agregué cp build/app.css static/styles/app.css después de next build para tenerlo disponible en exportación estática e incrustarlo en un encabezado personalizado como se muestra a continuación.

const ExtractTextPlugin = require('extract-text-webpack-plugin');

export default {
  webpack: (config, { dev }) => ({
    ...config,
    module: {
      ...config.module,
      rules: [
        ...config.module.rules,
        {
          test: /\.(css|scss)/,
          loader: 'emit-file-loader',
          options: {
            name: 'dist/[path][name].[ext]'
          }
        },
        ...(dev
          ? [
              {
                test: /\.css$/,
                use: ['raw-loader', 'postcss-loader']
              },
              {
                test: /\.s(a|c)ss$/,
                use: [
                  'raw-loader',
                  {
                    loader: 'postcss-loader',
                    options: {
                      sourceMap: true
                    }
                  },
                  {
                    loader: 'sass-loader',
                    options: {
                      sourceMap: true
                    }                    
                  }
                ]
              }
            ]
          : [
              {
                test: /\.(css|scss)/,
                use: ExtractTextPlugin.extract({
                  use: [
                    {
                      loader: 'css-loader',
                      options: {
                        importLoaders: 2,
                        modules: false,
                        url: true,
                        minimize: true,
                        localIdentName: '[hash:base64:5]'
                      }
                    },
                    {
                      loader: 'postcss-loader'
                    },
                    {
                      loader: 'sass-loader'
                    }
                  ]
                })
              }
            ]),
        {
          test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
          loader: 'url-loader?limit=100000&&name=[name].[ext]?[hash:8]'
        }
      ]
    },
    plugins: [
      ...config.plugins,
      ...(dev ? [] : [new ExtractTextPlugin('app.css')])
    ]
  }),
};

cabecera personalizada

const inlineCSS =
  process.env.NODE_ENV !== ENV_PRODUCTION && require('styles/index.scss');
...
      <Head>
        {inlineCSS && <style jsx global> {__html: inlineCSS} </style>}
          {process.env.NODE_ENV === ENV_PRODUCTION &&
            <link
              rel="stylesheet"
              type="text/css"
              href={`/static/styles/app.css?${this.props
                .__NEXT_DATA__.buildId}`}
            />}
      </Head>

Espero que esto ayude. Avíseme si alguien necesita más aclaraciones. Esperamos más soluciones también. Con suerte, a alguien se le puede ocurrir un buen complemento eventualmente, ya que sigue siendo una integración bastante complicada y torpe.

En lugar de extraer todos sus archivos .scss un solo archivo CSS, sería mucho mejor compilar cada archivo .scss importado en su propio archivo CSS. De esa manera, solo cargará los estilos CSS que necesita en cada página.
Sin embargo, no estoy seguro de cómo lo harías.

Por favor, consulte mi solicitud de extracción, creo que tengo una buena solución:
https://github.com/zeit/next.js/pull/2638

@ cr101 eso es cierto en realidad. Estamos importando nuestra propia biblioteca de IU interna en diferentes proyectos, por lo que siempre hay una gran parte de un archivo para cargar (no es ideal, lo sé, todavía estoy trabajando en modularizar esa bestia). Sería el siguiente paso de compile and serve 1 file a X number of files at X locations . Se vuelve más complicado cuando se tienen en cuenta las ventajas y desventajas de dividirse en fragmentos de CSS más pequeños frente a versiones alojadas en CDN de rendimiento y almacenamiento en caché externo, por lo que creo que será un proyecto divertido pero que involucra por sí solo. EDITAR: definitivamente está fuera del alcance de lo que Next debe manejar, lo mejor que debemos buscar es un complemento o patrón de Next.

No estoy seguro de si esto tiene algún problema de rendimiento, pero esta es una solución bastante simple si está utilizando componentes con estilo o similares, simplemente cree un contenedor CSS:

import styled from 'styled-components';

const Collapse = props => (
  <__Collapse>
    { props.children }
  </__Collapse>
);

export default Collapse;

/**
 * CSS
 */
const __Collapse = styled.div`
  .rc-collapse {
    background-color: #f7f7f7;
    border-radius: 3px;
    border: 1px solid #d9d9d9;
  }
  ...
`;
import RcCollapse from 'rc-collapse';
import Collapse from '~/components/rc/Collapse';

const HelpPage = () => (
  <Collapse>
    <RcCollapse>
      <RcCollapse.Panel header="Title">Content</RcCollapse.Panel>
    </RcCollapse>
  </Collapse>
);

Lo que me gusta de este enfoque es que puedo personalizar desde el CSS de origen (lo que necesito hacer la mayoría de las veces de todos modos), sin tener que escribir anulaciones sobre las reglas originales si he importado .css archivo de node_modules .

Aquí hay una solución simple para importar archivos CSS usando babel-plugin-inline-import :

.babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "inline-import",
      {
        "extensions": [".css"]
      }
    ]
  ]
}

página / componente

import "prismjs";

import { PrismCode } from "react-prism";
import prismGlobalStyles from "prismjs/themes/prism.css";

export default () => {
    return (
        <div>
            <style global jsx>
                {prismGlobalStyles}
            </style>
            <PrismCode className="language-javascript">
                {`function(noop) {
                    return noop;
                }`}
            </PrismCode>
            {/* ... */}
        </div>
    );
};

@stovmascript, esta es una hermosa solución, pero todavía recibo errores (estoy importando la compilación .css desde https://github.com/Hacker0x01/react-datepicker). ¿Estás seguro de que no tienes nada más en juego aquí? Por los errores, parece que necesita otro nivel de carga de CSS.

@hilarykitz , la solución @stovmascript funciona para mí, ¿puede enviarnos el error que está recibiendo?

@stovmascript : ¿cómo se deshace del caché de babel?

  1. Crear archivo CSS
  2. Importar archivo
  3. Aplicar
  4. Cambiar archivo CSS: agregar un nuevo selector y estilo
  5. Sea testigo de que Babel Cache mantiene la versión antigua

@ khrome83 necesitará borrar los node_modules / .cache

Encontré una mejor solución usando el complemento babel-inline-loader que borra el caché y funciona con lo anterior. El problema con ese método es que solo puede aplicar estilos globales. Cuando se usa en una etiqueta que no sea <style jsx global> , no agregará el data-jsx correctamente anulando el propósito.

Encontré una mejor solución usando el complemento babel-inline-loader que borra el caché y funciona con lo anterior. El problema con ese método es que solo puede aplicar estilos globales. Cuando se usa en un

Agregué un ejemplo usando la solución de

https://github.com/zeit/next.js/pull/3157

¿Cómo se incluyen más de un CSS externo?
Yo uso 2 librerías que lo requieren en el mismo componente, cada una funciona por separado, pero no sé cómo combinarlas.

import rtStyle from 'react-table/react-table.css';
import dpStyle from 'react-datepicker/dist/react-datepicker.css';
...
render() {
    return (
      <div>
        {/* <style jsx global>{ rtStyle }</style> */}
        <style jsx global>{ dpStyle }</style>
...

@CHarnel prueba <style jsx global>{ rtStyle }{dpStyle}</style>

@almeynman obteniendo esto:

Module build failed: SyntaxError: C:/.../components/activeUsersTable.js: 
Expected one child under JSX Style tag, but got 2 (eg: <style jsx>{`hi`}</style>)

@CHarnel intente poner ambos en la cadena de plantilla

@CHarnel prueba este enfoque
<style jsx global>{ $ {rtStyle} $ {dpStyle} }</style>

@alanhr

trato de poner esos css en un archivo js y exportarlo

import bootstrap from 'bootstrap/dist/css/bootstrap.min.css'
import styles from './index.css'

export default bootstrap + styles

y luego solo

import styles from '../styles'
...
<style jsx global>{styles}</style>

Con https://github.com/sheerun/extracted-loader que he creado, puede usar ExtractTextPlugin tanto para el desarrollo como para la producción, sin necesidad de un html diferente en el desarrollo o inyectar css en js.

@comus Usé tu enfoque, funciona bien, gracias.

@sheerun agradable, gracias

Envié un ejemplo aún más completo a next.js:
https://github.com/zeit/next.js/pull/3451

Esto solía funcionar antes de nextjs v4

<style jsx global>{style}</style> <style jsx global>{colors}</style> <style jsx global>{layout}</style>

¿Cuál es la razón para usar este enfoque para cargar estilos globales jsx? <style jsx global>{ rtStyle }{dpStyle}</style>

Me hice una solución basada en emit-files-loader . Si alguien está interesado, puedo publicarlo aquí, pero se basa en una configuración de servidor personalizada; básicamente, debe poder servir estáticamente un solo directorio dentro de .next build dir. Probablemente podría configurarse sin un servidor confiando en la estructura de ruta /_next/... del servidor.

Aparte de eso, puede escribir import stylesheet from './styles/style.[scss|less|stylus|w/e]'; y será la ruta pública a su archivo de hoja de estilo, por lo que puede ponerlo en un <link> . Incluye ?[hash] para almacenamiento en caché permanente y recarga en caliente.

@timneutkens He visto este, ¿hay alguna estimación de "muy pronto"? Veo que ya está en canario.
Solo necesitaba una solución de inmediato, pasé 2-3 días buscando una y logré escribir la mía, que es básicamente una "solución fácil". Incluso estoy pensando en combinarlo con extract-text-webpack-plugin para que uno pueda unir estáticamente todos los archivos .[css|stylus|less|scss] separados y tenerlos todos disponibles como un solo recurso estático como lo haría normalmente sin el siguiente.

Creo que el principal problema detrás de estos problemas es que hay mucha "magia" detrás de las compilaciones de producción y desarrollo, con recargas en caliente y esas cosas ... Probablemente se podría leer la fuente y ver cómo se ensamblan las cosas. , pero sería increíble si alguien que lo creó escribiera algunos documentos sobre eso, creo que más personas podrían contribuir.

@nikolakanacki muy pronto 🙏 🤐

Incluso estoy pensando en combinarlo con extract-text-webpack-plugin para poder unir estáticamente todos los archivos. [css | stylus | less | scss] separados y tenerlos todos disponibles como un único recurso estático como lo haría normalmente sin el siguiente .

Los complementos que escribí para la próxima v5 ya hacen esto, pronto serán de código abierto 👍

Con respecto a la redacción de documentos sobre los aspectos internos, estamos planeando documentar cómo funciona todo después de que salga la v5 🙏

@timneutkens ¡ Gracias!

@timneutkens gracias por la actualización, ¡publique una actualización aquí cuando esto

¿Alguna noticia sobre esto?

No estoy seguro de qué otras noticias estás esperando 🤔

Esto fue lanzado en Next.js v5.
Incluso está en el archivo readme https://github.com/zeit/next.js#importing -css - sass - less - stylus-files

Además, el RP mencionado se fusionó y este problema está cerrado.

simplemente cree la carpeta / static en el proyecto raíz y coloque su file.css dentro de / static, luego a la estructura del encabezado html corvejón.

import Head from 'next/head';
<Head>
          <meta charset="utf-8" />
          <link rel="stylesheet" href="/static/css/custom.css" />
</Head>

y luego use className en cualquier lugar!

@comus

Muy completo e inteligente ... gracias por esto ... he estado buscando este tipo de solución todo el día ...

simplemente cree la carpeta / static en el proyecto raíz y coloque su file.css dentro de / static, luego en la estructura del encabezado html hock.

import Head from 'next/head';
<Head>
          <meta charset="utf-8" />
          <link rel="stylesheet" href="/static/css/custom.css" />
</Head>

y luego use className en cualquier lugar!

Cree una carpeta 'pública' en la raíz de su aplicación (donde se encuentra el archivo package.json).

¡Se está agregando soporte a través del # 8626!

¿Fue útil esta página
0 / 5 - 0 calificaciones