É um problema redundante, eu sei, mas abri esse problema intencionalmente. Faz três dias que estou configurando um boilerplate next.js (com redux, redux-saga, ...) e faz dois dias que estou preso na configuração do carregamento de arquivos css e scss externos. Verifiquei os exemplos with-global-stylesheet e with-scoped-stylesheet-and-postcss , mas cada um deles tem problemas importantes mencionados em edições anteriores. Já vi muitos problemas abertos e fechados que estão resolvendo esse problema com hacks ... Eu acho uma boa ideia que ao invés de deixar o problema para encontrar a melhor solução, resolva-o com as soluções atuais disponíveis até encontrar uma melhor. Porque muitos têm esse problema agora e querem vê-lo resolvido agora!
Eu concordo, apenas styled-jsx tem suporte limpo (incluindo recarregamento a quente) e é isso que me impede de usar Next.js para qualquer coisa, exceto quando eu preciso de um prototipagem rápida.
Acho que a solução para os problemas de escopo de CSS dos Módulos CSS é muito mais limpa, além disso, com os Módulos CSS ainda é possível passar classes para componentes filhos (tente colocar uma classe não global em um SVG importado com babel-plugin-inline-react-svg
com jsx com estilo).
Isso e eu prefiro ter arquivos .css
padronizados para evitar o bloqueio de estrutura o máximo possível e arquivos CSS externos em produção para armazenamento em cache (e para fazer polyfills MQ como Respond.js funcionarem se você tiver o azar de ainda tem que oferecer suporte ao IE8).
Massive +1
É uma grande frustração que algo tão simples como css / scss externo seja quase impossível de conseguir com next.js, o que o torna inútil para 90% dos meus aplicativos.
Estou trabalhando com bootstrap e preciso de uma configuração onde haverá uma importação css de bootstrap global, com adição de css com escopo externo.
Embora tenhamos conseguido trabalhar com o stylus externo com jsx 1 estilizado (webpack para lidar com a compilação), tivemos dificuldade em descobrir no jsx 2 estilizado desde que introduziu uma mudança significativa no manuseio de arquivos css separados.
Abordagem atual:
import ComponentStyles from './footer.styl';
...
<style jsx>
{ComponentStyles}
</style>
Seria ótimo ver https://github.com/zeit/next.js/tree/master/examples/with-styled-jsx-scss trabalhando com arquivos scss externos.
Passamos pela mesma provação ao configurar o ambiente.
Eventualmente, estabelecemos uma folha de estilo global com scss + post css com lost-grid.
O recarregamento a quente funciona, portanto, embora não seja a solução ideal (devido à folha de estilo global ser carregada de uma só vez), é um compromisso ok.
Dependências
"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"
Em package.json
...
"postcss": {
"plugins": {
"lost": {},
"postcss-easy-import": {
"prefix": "_"
},
"autoprefixer": {},
"pixrem": {}
}
}
...
Em 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
}
Em pages/_document.js
...
import stylesheet from 'styles/main.scss'
...
<Head>
<style dangerouslySetInnerHTML={{ __html: stylesheet }} />
</Head>
...
E você pode gerenciar seus estilos começando em /styles/main.scss
Espero que ajude
Meu problema com cada um desses dois exemplos de estilo ( with-global-stylesheet e with-scoped-stylesheets-and-postcss ) é que nenhum deles é simples de integrar com o teste Jest e Snapshot com o CSS no instantâneo. Tem havido pessoas que conseguem fazer o Jest trabalhar com o Webpack, mas isso é especificamente ignorando o CSS.
Executar um arquivo de pré-processador babel-jest
conforme descrito nesta resposta do SO parece um hack muito ruim.
Parece obter CSS externo como with-global-stylesheet, você deve usar o Webpack, mas para usar o Jest você não pode confiar no Webpack, apenas no Babel.
Alguém tem ideias neste espaço?
Estou enfrentando um problema semelhante. Sou novo no nextjs e não consigo fazer o exemplo "with-external-scoped-css" funcionar corretamente. Às vezes, meu css está carregado e às vezes não. Não sei se é o mesmo assunto de que você está falando.
Resolvidos problemas de estilos externos com este carregador https://github.com/coox/styled-jsx-css-loader
@ilionic Eu verifiquei sua solução. É ótimo! Obrigado :)
@arefaslani Não creio que este assunto esteja encerrado.
A partir do HTTP v1 ainda é uma taxa de desempenho horrível para carregar toneladas de CSS, aumenta drasticamente o tempo para desenhar pela primeira vez.
O suporte de estilo externo adequado permitiria a importação de CSS e resultaria em um não é um inline ...
Also, this suggestion doesn't resolve use cases where a CSS framework like bootstrap needs to be included from node_modules. Including Bootstrap as an inline CSS on every page would be horrible. And would negate the benefits of browser caching, e.t.c
In short, I really don't think this issue can be closed... It's still very much an ongoing problem.
@israelidanny Eu sei o que você quer dizer sobre bootstrap, não é uma solução mágica. Estamos extraindo partes centrais da estrutura de bootstrap para separar o arquivo css para que os navegadores possam armazená-lo em cache. Não é o ideal, mas essa estranheza de lidar com pré-processadores e frameworks CSS empurrando para abordagens css-in-js mais recentes e cortando dependências em frameworks CSS.
@ilionic eu entendo o que você está dizendo, mas ainda assim - ter toneladas de CSS embutido é ruim para o desempenho (especificamente o tempo para o primeiro quadro). Tive alguns projetos em que otimizamos fortemente para isso.
É uma pena perder tudo isso, especialmente considerando o fato de que podemos ter o DOM renderizado pelo servidor.
Talvez feche este problema, mas abra um novo, especificamente para uma solução que nos permita vincular CSS externo?
Seria estranho ignorar uma prática de desenvolvimento claramente prevalente.
@israelidanny concorda, ainda estamos lutando com o desempenho do CSS e sem grandes reescritas não sabemos como resolvê-lo, então, de fato, esse problema é mais profundo. Provavelmente styled-jsx é um repo mais relevante neste caso?
@ilionic hmm, não vejo como o styled-jsx repo seria o lugar certo.
O problema não é com eles, o problema é habilitar o suporte de next.js para arquivos css externos, o que pode ou não envolver algo a ver com styled-jsx.
O que você acha?
@israelidanny Não era a melhor solução, mas funciona mesmo assim. Mas você está certo. Ter todo o css embutido em cada página sem cache não é a melhor solução. Também concordo com você nesta parte:
O problema não é com eles, o problema é habilitar o suporte de next.js para arquivos css externos, o que pode ou não envolver algo a ver com styled-jsx.
e discordo totalmente de @ilionic em:
Provavelmente styled-jsx é um repo mais relevante neste caso
Consegui uma solução com o carregador styled-jsx / css . Você pode ver o código em https://github.com/P233/nextjs-with-scss
No entanto, percebi que os arquivos @import
ed scss não são observados e não acionam o hot reload, o que realmente me deixa frustrado.
Criei https://github.com/sheerun/extracted-loader para recarregar os arquivos de folha de estilo extraídos. Funciona muito bem mesmo para desenvolvimento, então dangerouslySetInnerHTML
não é necessário.
Você o usa assim:
config.module.rules.push({
test: /\.css$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
/* Your configuration here */
}))
})
config.plugins.push(new ExtractTextPlugin('index.css'))
@sheerun , obrigado, mas como
Você não injeta, você extrai tudo com ExtractTextPlugin e escreve o seguinte:
<Head>
<link rel='stylesheet' type='text/css' href="/static/index.css" />
</Head>
em seus componentes, algo como
import './styles.scss'
deve ser suficiente
ok, mas agora tenho um erro:
./components/Home/Home.js
Módulo não encontrado: Erro: Não é possível resolver 'css-loader' em 'D: \ Sites \ work \ VisualProposal'
@ ./components/Home/Home.js 13: 0-22
@ ./pages?entry
@ multi ./pages?entry
meu componente Home.js:
import { observer } from 'mobx-react';
import './Home.scss'
import MainSection from './MainSection/MainSection'
import Sections from './Sections/Sections';
import Features from './Features/Features'
import Pricing from './Pricing/Pricing';
import Footer from './Footer/Footer'
const Home = () => {
return (
<div className="Home">
<MainSection/>
<Sections/>
<Features/>
<Pricing/>
<Footer/>
</div>
)
};
export default observer ( Home );
meu next.config.js:
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
webpack: function ( config, { dev } ) {
config.module.rules.push({
test: /\.(sa|sc|c)ss$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
use: [
"babel-loader",
{
loader: 'css-loader',
options: {
url: true,
minimize: !dev,
sourceMap: dev,
importLoaders: 2
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: dev,
plugins: [
require('autoprefixer')({
/* options */
})
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: dev
}
}
]
}))
});
config.plugins.push(new ExtractTextPlugin('index.css'));
if ( config.resolve.alias ) {
delete config.resolve.alias['react'];
delete config.resolve.alias['react-dom']
}
for (let index = 0; index < config.plugins.length; index += 1) {
if (config.plugins[index].constructor.name === "UglifyJsPlugin") {
config.plugins.splice(index, 1, new UglifyJSPlugin({
sourceMap: true,
parallel: true,
}));
break;
}
}
return config
}
};
Então, o que estou fazendo de errado?
Eu adicionei um exemplo bastante avançado com SCSS, url () na folha de estilo, img [src]. Deve funcionar de fábrica com now.sh e ter recarregamento a quente e exportação configurados corretamente:
https://github.com/sheerun/extracted-loader/tree/master/examples/with-next
@psycura Vejo que você usa o Windows, então pode não funcionar para você agora, mas por favor, envie uma correção de PR
👎 pena para Nextjs que não permite trabalhar com arquivos css externos. Existem muitos pacotes prontos para uso com suas próprias folhas de estilo que eu gostaria de usar em meu projeto. Mas não posso! Tentei várias opções mas nenhuma funciona: já passei um dia nisso.
@mkozhukharenko Funciona com arquivos css e scss. Vou adicionar um exemplo com https://github.com/coox/styled-jsx-css-loader . Ele carrega css externo como jsx com escopo ou estilo global. Para scss global geral, sugiro o uso de node-sass e postcss.
@arefaslani Tentei todas as opções, nenhuma funcionou para mim. Estou totalmente desapontado com este quadro. Como na terra uma tarefa tão fácil poderia ser difícil? Não vou usar esse quadro teórico novamente.
@mkozhukharenko Veja este exemplo: https://github.com/arefaslani/next.js/tree/canary/examples/with-external-scoped-scss. Estou criando uma solicitação pull para adicioná-la aos principais exemplos de repo.
apenas tente adicionar muito mais css ao seu arquivo e você verá que styled-jsx
não pode lidar com isso. Estou recebendo 'jsx-undefind' não pode ser encontrado ou erros 'jsx-4231512' não foram encontrados
@arefaslani Existe alguma maneira de usar esse padrão com seu exemplo?
import classes from './styles.scss'
const MyComponent = () => (
<header className={classes.header}>Hello</header>
)
@protoEvangelion Infelizmente, atualmente ele funciona apenas com styled-jsx.
Aww ok obrigado pela resposta rápida :)
É uma pena que a construção de next.js não pense em reutilizar o recurso existente no início. Que perda de tempo configurando regras complexas apenas para um arquivo css.
Estou trabalhando em uma solução para esse problema que permite que todos os carregadores de webpack funcionem.
Também gostaria de salientar que, pessoalmente, não gosto do tom que as pessoas estão dando nesta edição.
Eu entendo perfeitamente que você deseja importar css. E estamos bem cientes desse pedido. É por isso que passei a semana passada trabalhando na melhor solução possível 👍
Mais sobre isso em breve. Até então, por favor, seja gentil e feliz feriado 🎅😄
Olá a todos, encontrei uma solução em outro github,
Use skeleton-loader para seguir as regras BEM para obter o mesmo efeito que css-modules,
Porque você precisará gerar .scss.json e, em seguida, usar a lixeira para excluir os .scss.json gerados. Embora não pareça ideal, gostaria de enviar a você para ver se existem outros métodos melhores.
Hi, everybody, I found a solution on another github,
Use skeleton-loader to comply with BEM rules to achieve the same effect as css-modules,
Because it will need to generate. Scss.json, then use the trash will be generated. Scss.json delete
Although it feels less than ideal, give it to you to see if there are any other better ways
@timneutkens Como está indo sua solução?
Eu criei um texto padrão do Next que oferece suporte à importação de scss, css e muitos outros recursos. Dê uma olhada e se gostou, dê uma estrela;)
https://arefaslani.github.io/next-boilerplate
@Bobeta Já está funcionando, há alguns casos
@timneutkens Bom saber! Quando você espera que seja publicado?
@Bobeta Tenho certeza que ele
@jthegedus Tenho certeza que ele também, mas estou pensando em estimativas para que as pessoas possam basear suas decisões naqueles @timneutkens
Comentários muito úteis
Também gostaria de salientar que, pessoalmente, não gosto do tom que as pessoas estão dando nesta edição.
Eu entendo perfeitamente que você deseja importar css. E estamos bem cientes desse pedido. É por isso que passei a semana passada trabalhando na melhor solução possível 👍
Mais sobre isso em breve. Até então, por favor, seja gentil e feliz feriado 🎅😄