Next.js: Importando arquivos CSS?

Criado em 27 dez. 2016  ·  102Comentários  ·  Fonte: vercel/next.js

Às vezes é bom dividir seu CSS em um arquivo .css separado. Tentei fazer o seguinte:

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

Então, no index.js, tentei fazer:

import css from './index.css'

E em next.config.js:

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

Mas, infelizmente, continua me dando:

 ERROR  Failed to compile with 1 errors

This dependency was not found in node_modules:

* ./index.css

Parece que por algum motivo não está indo para o lugar certo, o component.js funciona via import component from './component.js' , então não tenho certeza do que está acontecendo aqui.

Comentários muito úteis

Esta é uma solução simples para importar arquivos 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 comentários

Quer dizer que isso não funciona no servidor?
Acho que ainda não temos uma solução alternativa para isso. cc @arunoda

Certo, acho que deve haver uma maneira de a configuração do webpack em next.config.js funcionar em ambos os lados para que isso funcione.

Eu tenho um problema parecido com o aproximado de que simplesmente não consigo fazer o Next tocar bem com CSS ou SASS. Eu tenho um diretório components com componentes padrão React que importo para minhas páginas, mas sempre que tento importar arquivos SASS (ou CSS) recebo um ~ "você precisa usar o carregador apropriado para este arquivo" digite mensagem de erro.

Geralmente no React eu importo arquivos SASS e faço com que o Webpack compile usando os carregadores style, css e sass. Tentei adicioná-los ao arquivo next.config.js (e o NPM os instalou), mas ainda recebo a mesma mensagem de erro.

Meu arquivo next.config.js :

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

Desculpe se essas perguntas parecem idiotas ou eu esqueci algo óbvio nos documentos que explicam as respostas para elas, mas se alguém tem um exemplo de trabalho de importação / compilação de SASS (ou pelo menos CSS) em um componente ou página com o que quer que seja necessário para adicionar next.config.js para carregá-los / compilá-los, eu apreciaria muito. Obrigado!

Estou usando css-modules-require-hook
para fazer o css funcionar.

@spacedragon Você tem um exemplo de como integrar css-modules-require-hook com Next.js? Estou tendo problemas em fazer funcionar.

Ainda estou tendo problemas para fazer o SASS compilar se alguém pudesse lançar alguma luz sobre como fazer isso ou apenas importar um arquivo CSS dentro do Next, agradeceríamos (por meio de um exemplo de código).

Interessante que o arquivo README foi atualizado para remover o exemplo do carregador SVG e alterado para dizer que adicionar carregadores para arquivos como SVG, CSS e SASS é desencorajado. Não sei por que CSS embutido é OK, mas CSS importado não, mas tenho certeza de que há um bom motivo. No momento, estou incerto sobre a melhor estratégia para lidar com nenhum CSS definido / embutido com JS e SASS.

@MikeDigitize Veja o comentário nos números 627 e 638.

É realmente possível e muito fácil processar estilos no lado do servidor.

diretamente no nó:

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

via 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"]
});

via webpack loaders:

Eu pessoalmente uso o carregador de estilo isomórfico, pois ele me permite embutir CSS crítico durante a renderização no servidor. O recarregamento a quente e outras coisas relacionadas ao DX também funcionam. Não sou muito fã de CSS em JS, pois complica o uso de componentes de terceiros e, de alguma forma, tira o C do CSS.

@viktorbezdek Você usou com sucesso o isomorphic-style-loader com next.js?

@noeljackson Na verdade não, mas pretendo. Next.js parece promissor e pode me poupar muito tempo se eu fizer funcionar. Analisarei isso em uma ou duas semanas e apresentarei a solicitação pull se for bem-sucedido.

@viktorbezdek Vou colocar uma recompensa neste aqui, pois é realmente crucial para um projeto em que estou trabalhando. Eu sei que não sou inepto, mas não entendo como depurar as transformações de babel o suficiente para descobrir isso. Eu tentei a permutação dessas idéias e nada funciona 100%. Consegui fazer o raw-loader puxar uma folha de estilo codificada por dados usando babel-plugin-webpack-loaders, mas nenhum dos carregadores de estilo funciona. Obrigado por participar! :) Muito apreciado.

Existe uma solução para isso? Gostaria de ver uma solução para não ter que incluir css globalmente.

FWIW, acabei de colocar meus arquivos CSS na pasta /static . Não é uma ótima localização, mas também não é um grande negócio.

Haverá uma solução. Só não consegui terminar. Eu localmente o primeiro protótipo que parece funcionar, no entanto, ele precisa de algumas horas para ser concluído. Tenho certeza que vou terminar depois do fim de semana. Fique ligado.

@matthewmueller Você está usando módulos CSS?

@viktorbezdek Obrigado por trabalhar nisso! Suporte a módulos CSS (ou similar) é importante para este projeto IMO. Com estilo jsx, é bom para situações simples, mas é difícil de ler para componentes com muito estilo.

Seria um plugin babel como este uma opção (do lado do servidor também)? https://github.com/gajus/babel-plugin-react-css-modules

Tentei fazer isso funcionar, mas sem sorte: /

Eu tenho módulos CSS funcionando com babel-plugin-css-modules-transform . Veja meu exemplo de hacky em meu garfo .

A desvantagem é que você tem que encerrar o servidor e reiniciá-lo toda vez que fizer uma alteração no CSS.

Alguns componentes React expõem o estilo padrão por meio de um recurso estático import capaz. Por exemplo, para importar o estilo padrão de https://github.com/react-component/slider, um usaria:

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

Com certeza é possível copiar e colar esta folha de estilo no diretório static/ , mas ela não ficará sincronizada com o estilo upstream em uma atualização de componente futura e não corresponde ao que esta documentação de componente recomenda.

O problema é que esses arquivos CSS apresentam efeitos globais. Precisamos ser capazes de _capturar_ o CSS e colocá-lo dentro do ciclo de vida do React, para que seja desmontado, renderizado pelo servidor, etc.

Muitas bibliotecas fazem isso, mas não acho que seja um bom padrão.

Não estou familiarizado com os componentes internos do Zeit Next, mas alguma análise estática de import ser usada para registrar / capturar o CSS?

Poderíamos, mas seria muito estranho. Semelhante a algo que está fora de render() se inserindo magicamente dentro do ciclo de vida de seu componente.

// Achei melhor compartilhar isso com qualquer outra pessoa

Bem ... Eu gastei muito tempo tentando hackear CSS aqui, MAS eu encontrei uma solução que funciona (para mim). É certo que é um hack, mas o recarregamento a quente funciona, assim como a construção do lado do servidor.

Usando (_shudder_) gulp, com este gulpfile (https://gist.github.com/auser/25e88e39d83413773c01f4c000ec2806) todos os arquivos **/*.scss são concatenados e colocados em um componente Styles qual eu monto a página como um elemento "normal".

Espero que isso ajude alguém até que possamos obter um verdadeiro suporte postcss na próxima.

Obrigado pelo hack @auser , estive olhando a configuração do webpack o dia todo sem sorte!

Editar:
A propósito, você precisa adicionar um analisador sass ao gulpfile!

Sim e não ... Eu apenas uso a extensão .scss como uma forma de diferenciar arquivos css puro de pré-compilados. Já que postcss (com precss ) imita bem o atrevimento, eu não tenho um. Sinta-se à vontade para editar você mesmo com um analisador sass.

Parece que atualmente é a melhor solução, usar o gulp para compilar o arquivo css e construí-lo embutido ou apenas em / estático se você não se importar em não ter de recarregar a quente.

Eu tenho o css import + hot reload funcionando de forma limpa. O css é importado como string e o usuário pode embuti-lo na página como qualquer outra string. Por favor, dê uma olhada neste exemplo, ajude-me a testar e os PRs são bem-vindos!

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

Eu acredito que este exemplo deve ser transformado em exemplos oficiais next.js. É mesmo? @rauchg @arunoda @nkzawa (desculpe se

@davibe, obrigado pela sua demonstração e babel-plugin-wrap-in-js

No exemplo, vejo o uso de um arquivo CSS e um arquivo SCSS. Você sabe se isso funcionaria com postcss e cssnext?

@ khrome83 Não vejo por que não, acho que é só uma questão de ajustar .babelrc e next.config.js

@davibe Descobri que não consegui implantar meu aplicativo com base na sua configuração. A compilação não conseguiu ler next/babel no arquivo .babelrc . Enviei um problema, mas estou realmente esperançoso de que uma solução surja a partir de tudo isso. Faltando a facilidade de import file.css de create-react-app , mas sei que deve haver uma solução chegando :)

A solução que desejo provavelmente segue estas linhas:

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

Poderíamos suporta a importação .css (por meio de simplesmente transpiling-lo em um módulo que as exportações uma string) (e da mesma forma podemos apoiar .svg por transpiling-lo em um puro reagir componente)

e da mesma forma podemos suportar .svg, transpilando-o em um componente de reação pura

Este é um truque muito simples. Vou criar um exemplo básico mostrando como lidei com isso em outro projeto =)

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

Com base no exemplo de @davibe, criei https://github.com/moxystudio/next.js-style-loader que, com sorte, facilitará a adição de arquivos css em projetos next.js. É semelhante ao style-loader do webpack, pois adiciona / remove folhas de estilo à medida que o usuário navega. Ele também oferece suporte a SSR.

Funciona bem com css-loader (com e sem módulos css), postcss-loader , sass-loader e possivelmente outros. Observe que quando css-loader é usado, sua opção url deve ser definida como false beucase next.js, imagens, fontes, etc. devem viver /static . Você encontrará todas essas informações no README.

Aproveite e por favor me dê feedback!

Obrigado pelo repo! Funcionou para importar os arquivos css. Estou tentando o blueprintjs e parece que o css está carregando corretamente! No entanto, a regra @ font-face que inclui o css não parece funcionar. :

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

Está realmente funcionando, meu mal!
No entanto, os ícones não estão sendo carregados porque o roteamento nextjs por padrão não permite veicular conteúdo estático fora de / estático / e o caminho relativo realmente faz com que ele seja carregado com um caminho não permitido.

@pencilcheck sim, você deve usar caminhos apontando para / static, talvez eu deixe isso mais claro no README.

Existe alguma solução alternativa em relação ao caminho relativo incluído nos arquivos css, como fontes atm? Ou simplesmente tenho que copiar todos os arquivos de fonte e css para uma pasta estática para que funcione?

@pencilcheck os arquivos CSS podem ficar fora da estática. Suas imagens e fontes devem estar dentro de estática e você as referencia com /static/file .

Entendi. No entanto, estou usando o blueprint, que é um pacote npm, gostaria de não precisar modificar nenhum arquivo dentro de node_modules.

@pencilcheck Infelizmente, isso não é possível. next.js é muito rígido na forma como lida com imagens e outros ativos. Não vamos poluir essa conversa e, por favor, crie um problema no repositório next-style-loader, se possível.

@tgoldenberg você pode descrever melhor o problema ou me dizer como reproduzi-lo? por favor, consulte meu repositório. É mais fácil para mim rastrear problemas lá.

@davibe , acabou sendo um problema usar yarn sobre npm install . O fio estava gerando alguns erros inexplicáveis, mas depois que o removi, o exemplo funcionou bem na produção.

Acabei de passar 4 horas tentando configurar isso e achei que pode ser do interesse de quem quer economizar tempo. Ele aplica estilos automaticamente na mudança (assim como no exemplo atual), executa o CSS por meio de PostCSS e fornece nomes de módulos locais de css-loader . A falta do último foi um grande obstáculo para mim no estado atual dos exemplos “css global” / “importações css”.

component.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 o incrível hack com exports-loader . Tem que haver uma maneira melhor, com certeza ???

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;
    }
};

Eu mesmo encontrei uma solução, que é muito semelhante ao que @satazor postou mais acima no tópico: https://github.com/jozanza/next-css-json-loader.

Basta adicionar algumas linhas ao seu 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;
  },
};

Os estilos são importados como objetos js, portanto, é muito fácil de usar com glamor e soluções semelhantes:

// .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>

Felicidades! 🍻 :)

Existe uma maneira de fazer isso funcionar para a importação de arquivos markdown como strings? Atualmente, estou usando o raw-loader, mas como é um plugin webpack, ele não funciona no servidor.

@kristojorg

Acabei de escrever um plugin babel para importação de markdown. No meu celular agora, mas se você visualizar meu GitHub, você verá.

@ khrome83 isso parece incrível. Ansioso para experimentar isso

Obrigado @ khrome83! Vou tentar

Tive de fazer isso muito rapidamente, por isso não atualizei o readme. Mas você apenas inclui-o como um plugin do babel, e então usa

importar arquivo de 'File.md';

Consegui funcionar, obrigado !! Muito útil

Isso é offtopic, mas como o problema foi encerrado, sinto-me à vontade para explicar :)

Para remarcação, existem 2 coisas que você pode fazer.

(1)
Uma é incluir o arquivo markdown como uma string e então traduzi-lo para html / react em tempo de execução. Você pode fazer isso usando o carregador genérico examples/with-globa-stylesheet/.babelrc para css.

(2)
Outra coisa que você pode fazer é traduzir markdown no momento da transpilação usando markdown-in-js
Isso pode ser mais interessante em alguns cenários porque o documento de redução já está pré-renderizado, portanto, em tempo de execução, é mais rápido (ele apenas executa js). Além disso, a biblioteca permite injetar componentes personalizados do React. Infelizmente, neste caso, você deve escrever a redução inline em seu source.js assim .

Se você escolher (2), também sabe que existe um plugin Atom que fornece luz de fundo de sintaxe para a sintaxe markdown-in-js e é chamado de language-markdown-in-js

@davibe obrigado pela dica! Eu preferiria que o markdown fosse analisado como tempo de compilação, mas o único problema que tenho com o markdown-in-js é escapar dos crases ao compor :(. Talvez eu deva tentar importar como string usando babel e, em seguida, alimentar isso para markdown-in-js ?

@kristojorg

Lá estão seus renderizadores de markdown. A razão pela qual escrevi meu plugin foi a mesma coisa. Eu puxo o markdown como uma corda, então eu o passo por react-markdown. Isso funciona cada vez mais bem porque posso passar componentes de reação para representar peças de renderização de marcação, como o componente de lista para lidar com todas as listas. Funciona bem com JSX com estilo.

Existe alguma atualização sobre isso? Através dos comentários acima, vejo que ainda não há soluções perfeitas atualmente.
@arunoda
É possível ter um exemplo usando isomorphic-style-loader - https://www.npmjs.com/package/isomorphic-style-loader?

Seria perfeito!

Alguém tem uma solução para quando importar um componente react do pacote npm que por sua vez importa o arquivo .css ou .scss? então, basicamente, transpilar arquivos que são importados de node_modules

Estou usando o Create-React-App (CRA) há algumas semanas, mas hoje me deparei com o Next.js e fiquei muito animado porque o CRA atualmente não oferece suporte à renderização do lado do servidor (SSR), o que é uma pena.
Adoraria mudar para Next.js devido ao suporte SSR pronto para uso, mas não conseguir importar .scss arquivos está me impedindo.
Alguém encontrou uma maneira de adicionar um carregador SASS à configuração do Webpack?

De acordo com cr101, não ter suporte para CSS / SASS significa que tenho que descartar frameworks css como o Foundation, o que não é uma opção para mim.

Eu estava usando o repositório fornecido por rompe com a solução que ele tinha .

Adoraria se alguém encontrou uma solução para isso. A atualização para 2.4.1 foi absolutamente necessária devido ao bug de segurança, então não tenho a opção de voltar atrás.

@Yuripetusko @ cr101 @tgoldenberg Concordo plenamente . Eu acho honestamente que o próximo é realmente incrível poder trabalhar fora da caixa. Tudo está bem, mesmo a estrutura codificada (como o diretório /pages obrigatório, /static etc.). Mas módulos scss totalmente sem suporte quebram tudo para nós. Temos uma estrutura scss muito complexa com pontos de interrupção automáticos e recálculo da proporção de aspecto de tudo. Trabalhamos muito para tornar nossa estrutura tão perfeita. O próximo é ótimo, pois não podemos simplesmente jogar fora todas as scss coisas que temos no momento de existir. Sem suporte scss é a única, mas a mais crucial coisa que nos impede de migrar para esta bela ferramenta.

Na verdade, # 1615 - alguma ação está acontecendo. @timmywil está tentando configurar isomorphic-style-loader para trabalhar com next . Todos os interessados ​​são bem vindos a aderir e participar.

Tentei todas as soluções para as quais este tópico aponta, mas consegui fazer qualquer uma delas funcionar. Então decidi tentar fazer minha própria tentativa e eu o documentei aqui

@almeynman obrigado! definitivamente vou ver a sua abordagem!
A propósito, consegui fazer os módulos scss funcionarem seguindo este exemplo. Tudo o que fiz foi adicionar sass-loader e mapas de origem habilitados.

Consegui fazer next.js suport CSS (até mesmo SCSS) desta forma.

Primeiro, em next.config.js , ajuste a configuração do webpack adicionando carregadores dados e uma instância 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;
  }
};

Então, no código do componente, requer arquivo de estilo com condição. Isso garante que apenas o agrupamento do lado do navegador terá o módulo de estilo.

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

Se você não se importar com o if (process.env.BROWSER) , ele funciona perfeitamente.

Uma boa abordagem está aqui

@almeynman IMO, essa não é uma abordagem muito boa, pois você está carregando o código CSS de todo o site em cada página, em vez de apenas carregar os estilos CSS relevantes para aquela página.
Importar apenas os arquivos .scss de que você precisa em vez do CSS para todo o site reduziria muito o tamanho das páginas, carregando apenas o código CSS de que você precisa.

@ cr101 Oi, não sabia disso. Eu realmente não usei aquele setup, apenas postei para referência para outros (achei bom ...). Eu ainda uso minha abordagem descrita na postagem do blog . Se você pudesse me dar algum feedback sobre essa configuração, seria ótimo

Mais exemplos e discussões se alguém estiver interessado:

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

Com base no que precede e neste tópico, consegui usar PostCSS para transformar:

  • Arquivo SCSS global (os módulos são iguais, você só precisa de um ponto de entrada para pré-compilar todo o CSS para produção).
  • Separe CSS de terceiros com fontes personalizadas referenciadas por meio de URL relativo (resolvido por meio de mágica inlining).

em um único arquivo CSS em /static/styles/app.css para servir na produção, com o recarregamento a quente ainda funcionando. Observe o uso de styled-jsx mas pode ser feito sem, 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

Carregadores para transformar .scss no modo dev para recarregamento a quente e extrair para um único arquivo .css em prod. Isso me dá build/app.css então na construção de produção, eu adicionei cp build/app.css static/styles/app.css após next build para tê-lo disponível na exportação estática e incorporar no cabeçalho personalizado conforme mostrado abaixo.

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')])
    ]
  }),
};

cabeçalho personalizado

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 isto ajude. Avise-me se alguém precisar de mais esclarecimentos. Ansioso por mais soluções também. Esperançosamente, alguém pode vir com um bom plugin eventualmente, pois ainda é uma integração complicada e pesada.

Em vez de extrair todos os seus .scss arquivos em um único arquivo CSS, seria muito melhor compilar cada arquivo .scss importado em seu próprio arquivo CSS. Dessa forma, você só carregará os estilos CSS necessários em cada página.
Não tenho certeza de como você faria isso.

Verifique minha solicitação de pull, acho que tenho uma boa solução:
https://github.com/zeit/next.js/pull/2638

@ cr101 isso é verdade, na verdade. Estamos importando nossa própria biblioteca de IU interna para diferentes projetos, portanto, sempre há um grande pedaço de um arquivo para carregar (não é o ideal, eu sei, ainda trabalhando na modularização dessa besta). Seria o próximo passo de compile and serve 1 file para X number of files at X locations . Fica mais complicado quando você leva em consideração as compensações de quebrar em pedaços CSS menores em comparação com versões externas armazenadas em cache E com desempenho de CDN, então acho que será divertido, mas envolvendo o projeto por conta própria. EDITAR - definitivamente muito fora do escopo do que o Next se destina a tratar, o melhor que devemos buscar é um plugin ou padrão do Next.

Não tenho certeza se isso tem algum problema de desempenho, mas esta é uma solução bastante simples se você estiver usando componentes estilizados ou semelhantes, basta fazer um wrapper 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>
);

O que eu gosto nessa abordagem é que posso personalizar a partir do CSS de origem (o que preciso fazer na maioria das vezes de qualquer maneira), sem ter que escrever sobre as regras originais se eu importei .css arquivo de node_modules .

Esta é uma solução simples para importar arquivos 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 é uma bela solução, mas ainda recebo erros (estou importando a compilação .css de https://github.com/Hacker0x01/react-datepicker). Tem certeza de que não tem mais nada em jogo aqui? Pelos erros, parece que ele precisa de outro nível de carregamento de CSS.

@hilarykitz , a solução @stovmascript funciona para mim, você pode nos enviar o erro que está recebendo?

@stovmascript - como você está se livrando do cache do babel.

  1. Criar arquivo CSS
  2. Importar arquivo
  3. Aplique
  4. Alterar arquivo CSS - adicionar novo seletor e estilo
  5. Testemunhe que o Babel Cache mantém a versão antiga

@ khrome83, você precisará limpar o node_modules / .cache

Eu encontrei uma solução melhor usando o plugin babel-inline-loader que limpa o cache e funciona com o acima. O problema com esse método é que você só pode aplicar estilos globais. Ao usar em uma tag diferente de <style jsx global> , ele não adicionará o data-jsx corretamente anulando o propósito.

Eu encontrei uma solução melhor usando o plugin babel-inline-loader que limpa o cache e funciona com o acima. O problema com esse método é que você só pode aplicar estilos globais. Ao usar em um

Adicionei um exemplo usando a solução

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

Como você inclui mais de um css externo?
Utilizo 2 libs que exigem isso no mesmo componente, cada uma funciona separadamente, mas não sei como combiná-las.

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 tente <style jsx global>{ rtStyle }{dpStyle}</style>

@almeynman recebendo isto:

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

@CHarnel tente colocar ambos na string do modelo

@CHarnel tente esta abordagem
<style jsx global>{ $ {rtStyle} $ {dpStyle} }</style>

@alanhr

Eu tento colocar esses css em um arquivo js e exportá-lo

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

export default bootstrap + styles

e então apenas

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

Com https://github.com/sheerun/extracted-loader que criei, você pode usar ExtractTextPlugin para desenvolvimento e produção, sem necessidade de html diferente no desenvolvimento ou injetando css em js.

@comus usei sua abordagem, funciona bem, obrigado.

@sheerun legal, obrigado

Enviei um exemplo ainda mais abrangente para next.js:
https://github.com/zeit/next.js/pull/3451

Isso costumava funcionar antes do nextjs v4

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

Qual é a razão de usar esta abordagem para carregar estilos globais jsx? <style jsx global>{ rtStyle }{dpStyle}</style>

Eu fiz para mim uma solução baseada em emit-files-loader . Se alguém estiver interessado, posso postá-lo aqui, mas ele depende de uma configuração de servidor personalizada - basicamente, você precisa ser capaz de servir estaticamente um único diretório dentro de .next diretório de construção. Provavelmente, ele poderia ser configurado sem um servidor, dependendo da estrutura de caminho /_next/... do servidor.

Fora isso, você pode escrever import stylesheet from './styles/style.[scss|less|stylus|w/e]'; e ele será o caminho público para seu arquivo de folha de estilo, então você pode colocá-lo em <link> . Inclui ?[hash] para cache permanente e faz hot-reload.

@timneutkens eu vi este, existe uma estimativa de "muito em breve"? Vejo que já está no canário.
Eu só precisava de uma solução imediatamente, passei 2-3 dias procurando uma e consegui escrever minha própria solução, que é basicamente uma "solução fácil". Estou até pensando em combiná-lo com extract-text-webpack-plugin para que se possa juntar estaticamente todos os .[css|stylus|less|scss] arquivos separados e tê-los todos disponíveis como um único recurso estático, como faria normalmente sem o próximo.

O principal problema por trás desses problemas, eu acho, é que há muita "mágica" acontecendo no fundo por trás da produção e das compilações de desenvolvimento, com recarregamento a quente e outras coisas ... Alguém poderia provavelmente ler o código-fonte e ver como as coisas são montadas , mas seria incrível se alguém que o construiu escrevesse alguns documentos sobre isso, acho que mais pessoas poderiam contribuir.

@nikolakanacki muito em breve 🙏 🤐

estou até pensando em combiná-lo com o plugin extract-text-webpack-plugin para que se possa unir estaticamente todos os arquivos. [css | stylus | less | scss] e tê-los todos disponíveis como um único recurso estático, como faria normalmente sem os próximos .

Os plug-ins que escrevi para a próxima v5 já fazem isso, eles serão liberados em breve 👍

Em relação à escrita de documentos internos, estamos planejando documentar como tudo funciona após o lançamento da v5 🙏

@timneutkens Obrigado!

@timneutkens obrigado pela atualização, poste uma atualização aqui quando isso pousar!

Alguma novidade sobre isso?

Não tenho certeza de que outras notícias você está esperando 🤔

Isso foi lançado no Next.js v5.
Está até no readme https://github.com/zeit/next.js#importing -css - sass - less - stylus-files

Além disso, o PR mencionado foi mesclado e este problema foi encerrado.

apenas crie a pasta / static no projeto raiz e coloque seu arquivo.css dentro de / static, então para a estrutura html do cabeçalho hock.

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

e use className em qualquer lugar!

@comus

Muito abrangente e inteligente ... obrigado por isso ... Tenho buscado esse tipo de solução o dia todo ...

apenas crie a pasta / static no projeto raiz e coloque seu arquivo.css dentro de / static, em seguida, em Header html structure hock.

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

e use className em qualquer lugar!

Crie uma pasta 'pública' na raiz do seu aplicativo (onde o arquivo package.json está localizado).

O suporte está sendo adicionado via # 8626!

Esta página foi útil?
0 / 5 - 0 avaliações