Next.js: Vous importez des fichiers CSS?

Créé le 27 déc. 2016  ·  102Commentaires  ·  Source: vercel/next.js

Parfois, il est agréable de diviser votre CSS dans un fichier .css séparé. J'ai essayé de faire ce qui suit:

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

Ensuite, dans index.js, j'ai essayé de faire:

import css from './index.css'

Et dans next.config.js:

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

Mais malheureusement, ça continue de me donner:

 ERROR  Failed to compile with 1 errors

This dependency was not found in node_modules:

* ./index.css

On dirait qu'il ne se résout pas au bon endroit pour une raison quelconque, le component.js local fonctionne bien via import component from './component.js' , donc je ne suis pas sûr de ce qui se passe ici.

Commentaire le plus utile

Voici une solution simple pour importer des fichiers CSS à l'aide de babel-plugin-inline-import :

.babelrc

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

page / composant

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

Tous les 102 commentaires

Vous voulez dire que cela ne fonctionne pas sur le serveur?
Je pense que nous n'avons pas encore de solution de contournement pour cela. cc @arunoda

oh oui, je suppose qu'il devrait y avoir un moyen pour que la configuration du webpack dans next.config.js fonctionne des deux côtés pour que cela fonctionne.

J'ai une sorte de problème similaire dans la mesure où je n'arrive tout simplement pas à faire en sorte que Next joue bien avec CSS ou SASS. J'ai un répertoire components avec des composants React standard que j'importe dans mes pages mais chaque fois que j'essaye d'importer des fichiers SASS (ou CSS), j'obtiens un ~ "vous devez utiliser le chargeur approprié pour ce fichier" message d'erreur de type.

Généralement, dans React, j'importe des fichiers SASS et je fais compiler Webpack à l'aide de chargeurs style, css et sass. J'ai essayé de les ajouter au fichier next.config.js (et NPM les a installés) mais j'obtiens toujours le même message d'erreur.

Mon fichier next.config.js :

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

Désolé si ces questions semblent stupides ou si j'ai raté quelque chose d'évident dans la documentation qui leur donne les réponses, mais si quelqu'un a un exemple fonctionnel d'importation / compilation de SASS (ou du moins de CSS) dans un composant ou une page avec tout ce qu'il faut ajouter aux next.config.js pour les charger / les compiler, je l'apprécierais énormément. Merci!

J'utilise css-modules-require-hook
pour faire fonctionner le CSS.

@spacedragon Avez-vous un exemple comment intégrer css-modules-require-hook avec Next.js? J'ai du mal à le faire fonctionner.

J'ai toujours des problèmes avec la compilation de SASS si quelqu'un pouvait éclairer comment faire cela ou simplement importer un fichier CSS dans Next, ce serait apprécié (via un exemple de code).

Il est intéressant de noter que le fichier README a été mis à jour pour supprimer l'exemple de chargeur SVG et modifié pour indiquer que l'ajout de chargeurs pour des fichiers tels que SVG, CSS et SASS est déconseillé. Je ne sais pas pourquoi le CSS intégré est OK, mais le CSS importé ne l'est pas, mais je suis sûr qu'il y a une bonne raison. Je ne suis actuellement pas sûr de la meilleure stratégie pour gérer les CSS et SASS définis / intégrés dans le JS.

@MikeDigitize Voir les commentaires sur # 627 et # 638.

Il est en fait possible et assez facile de traiter les styles côté serveur.

directement dans le nœud:

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

via le registre 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 des chargeurs Webpack:

J'utilise personnellement un chargeur de style isomorphe car il me permet d'intégrer le CSS critique lors du rendu sur le serveur. Le rechargement à chaud et d'autres éléments liés à DX fonctionnent également. Je ne suis pas vraiment fan de CSS dans JS car cela complique l'utilisation de composants tiers et enlève en quelque sorte le C de CSS.

@viktorbezdek Avez-vous utilisé avec succès le chargeur de style isomorphe avec next.js?

@noeljackson Pas vraiment, mais j'ai l'intention de le faire. Next.js semble prometteur et pourrait me faire gagner beaucoup de temps si je le fais fonctionner. Je l'examinerai dans une ou deux semaines et soumettra une demande d'extraction si je réussis.

@viktorbezdek Je mettrai une prime sur celui-ci, car c'est vraiment crucial pour un projet sur

Y a-t-il une solution à cela? Je voudrais voir une solution pour ne pas avoir à inclure le CSS globalement.

FWIW, je viens de mettre mes fichiers CSS dans le dossier /static . Pas super colocation, mais pas grand-chose non plus.

Il y aura une solution. Je n'ai tout simplement pas réussi à le terminer. J'ai localement le premier prototype qui semble fonctionner, mais il faut quelques heures pour le terminer. Je suis sûr que j'aurai fini après le week-end. Restez à l'écoute.

@matthewmueller Vous utilisez des modules CSS?

@viktorbezdek Merci d'avoir travaillé là-dessus! Le support des modules CSS (ou similaire) est important pour ce projet IMO. Styled jsx, convient aux situations simples mais est difficile à lire pour les composants fortement stylisés.

Un plugin Babel comme celui-ci serait-il une option (côté serveur également)? https://github.com/gajus/babel-plugin-react-css-modules

J'ai essayé de faire fonctionner cela mais pas de chance: /

J'ai des modules CSS qui fonctionnent en quelque sorte avec babel-plugin-css-modules-transform . Voir mon exemple hacky dans ma fourchette .

L'inconvénient est que vous devez tuer le serveur et le redémarrer à chaque fois que vous modifiez le CSS.

Certains composants React exposent le style par défaut via une ressource statique import capable. Par exemple, pour importer le style par défaut de https://github.com/react-component/slider, on utilisera:

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

Il est bien sûr possible de copier-coller cette feuille de style dans le répertoire static/ mais elle ne restera pas synchronisée avec le style en amont lors d'une future mise à jour du composant, et elle ne correspond pas à ce que la documentation de ce composant recommande.

Le problème est que ces fichiers CSS introduisent des effets globaux. Nous devons être capables de _capturer_ le CSS et de le placer dans le cycle de vie React, afin qu'il soit démonté, rendu par le serveur, etc.

De nombreuses bibliothèques font cela, mais je ne pense pas que ce soit un bon modèle.

Je ne suis pas familier avec les composants internes de Zeit Next, mais une analyse statique de import pourrait-elle être utilisée pour enregistrer / capturer le CSS?

Nous pourrions, mais ce serait vraiment étrange. Similaire à quelque chose qui est en dehors de render() s'insérant comme par magie dans le cycle de vie de vos composants.

// J'ai pensé que je partagerais ça pour n'importe qui d'autre

Eh bien ... j'ai juste passé un peu trop de temps à essayer de pirater CSS ici, MAIS j'ai atterri sur une solution qui fonctionne (pour moi). Certes, c'est un hack, mais le rechargement à chaud fonctionne, tout comme la construction côté serveur.

En utilisant (_shudder_) gulp, avec ce gulpfile (https://gist.github.com/auser/25e88e39d83413773c01f4c000ec2806) tous les fichiers **/*.scss sont concaténés et poussés dans un composant Styles lequel je monte la page comme élément "normal".

J'espère que cela aidera quelqu'un d'autre jusqu'à ce que nous puissions obtenir un véritable support postcss dans la prochaine étape.

Merci pour le hack @auser , j'ai regardé la configuration du webpack toute la journée sans chance!

Éditer:
Btw, vous devez ajouter un analyseur sass au gulpfile!

Oui et non ... J'utilise juste l'extension .scss pour différencier les fichiers css purs des fichiers précompilés. Puisque postcss (avec precss ) imite assez bien sass, je n'en ai pas. N'hésitez pas à modifier vous-même avec un analyseur sass.

On dirait que c'est actuellement la meilleure solution, en utilisant gulp pour compiler le fichier css et le construire en ligne ou même simplement dans / static si cela ne vous dérange pas de ne pas recharger à chaud.

L'importation css + le rechargement à chaud fonctionnent correctement. Le css est importé sous forme de chaîne et l'utilisateur peut l'insérer dans la page comme n'importe quelle autre chaîne. Jetez un œil à cet exemple, aidez-moi à tester et les RP sont les bienvenus!

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

Je pense que cet exemple devrait en faire des exemples officiels de next.js. Le fait-il? @rauchg @arunoda @nkzawa (désolé si j'ai tagué quelqu'un qui n'est pas directement impliqué)

@davibe merci pour votre démo et babel-plugin-wrap-in-js

Dans l'exemple, je vois l'utilisation d'un fichier CSS et d'un fichier SCSS. Savez-vous si cela fonctionnerait avec postcss & cssnext?

@ khrome83 Je ne vois pas pourquoi, je pense que c'est juste une question d'ajuster .babelrc et next.config.js

@davibe J'ai constaté que je ne pouvais pas déployer mon application en fonction de votre configuration. La compilation n'a pas pu lire next/babel dans le fichier .babelrc . J'ai soumis un problème, mais j'espère vraiment qu'une solution émergera de tout cela. Manque la facilité de import file.css de create-react-app , mais je sais qu'il doit y avoir une solution à venir :)

La solution que je veux est probablement le long de ces lignes:

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

Nous pourrions prendre en charge l'importation de .css (en le transpilant simplement dans un module qui exporte une chaîne) (et de même nous pourrions prendre en charge .svg en le transpilant dans un composant de réaction pur)

et de même, nous pourrions prendre en charge .svg en le transpilant en un composant de réaction pur

C'est une astuce assez simple. Je vais créer un exemple de base montrant comment j'ai géré cela dans un autre projet =)

EDIT: voir https://github.com/zeit/next.js/pull/982

Basé sur l'exemple @davibe, j'ai créé https://github.com/moxystudio/next.js-style-loader qui, espérons-le, facilitera l'ajout de fichiers css dans les projets next.js. C'est similaire au style-loader de webpack en ce sens qu'il ajoutera / supprimera des feuilles de style au fur et à mesure que l'utilisateur naviguera. Il prend également en charge SSR.

Cela fonctionne bien avec css-loader (avec et sans modules css), postcss-loader , sass-loader et éventuellement d'autres. Notez que lorsque css-loader est utilisé, son option url doit être définie sur false beucase next.js, les images, les polices, etc. doivent vivre /static . Vous trouverez toutes ces informations dans le README.

Profitez-en et faites-moi part de vos commentaires!

Merci pour le repo! Cela a fonctionné pour importer les fichiers css. J'essaye blueprintjs et il semble que le css se charge correctement! Cependant, la règle @ font-face que le css inclut ne semble pas fonctionner. :

--------------------Éditer----------------------

Cela fonctionne réellement, mon mauvais!
Cependant, les icônes ne sont pas chargées car le routage nextjs par défaut ne permet pas de diffuser du contenu statique en dehors de / static / et le chemin relatif le fait en fait se charger avec un chemin non autorisé.

@pencilcheck oui vous devez utiliser des chemins pointant vers / static, peut-être que je le préciserai plus clairement dans le README.

Existe-t-il une solution de contournement concernant le chemin relatif inclus dans les fichiers css tels que les polices atm? Ou je dois simplement copier tous les fichiers de polices et css dans un dossier statique pour que cela fonctionne?

@pencilcheck les fichiers CSS peuvent rester en dehors de la statique. Vos images et polices doivent être à l'intérieur de static et vous les référencez avec /static/file .

J'ai compris. Cependant, j'utilise blueprint, qui est un package npm, je voudrais pouvoir ne pas avoir à modifier les fichiers à l'intérieur de node_modules.

@pencilcheck Ce n'est malheureusement pas possible. next.js est très strict dans la façon dont il gère les images et autres actifs. Ne polluons pas cette conversation et veuillez créer un problème dans le repo du prochain chargeur de style si vous le pouvez.

@tgoldenberg pouvez-vous mieux décrire le problème ou me dire comment le reproduire? veuillez vous référer à mon référentiel. Il est plus facile pour moi de suivre les problèmes là-bas.

@davibe , cela a fini par être un problème en utilisant yarn sur npm install . Yarn a lancé des erreurs inexplicables, mais une fois que je l'ai retiré, l'exemple a bien fonctionné en production.

Je viens de passer 4 heures à essayer de mettre cela en place et j'ai pensé que cela pourrait intéresser quiconque cherchant à gagner du temps. Il applique les styles automatiquement lors du changement (comme dans l'exemple actuel), exécute le CSS via PostCSS et vous donne des noms de modules locaux à partir de css-loader . L'absence de ce dernier a été pour moi un facteur décisif majeur dans l'état actuel des exemples «css global» / «import 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
Remarquez le hack incroyable avec exports-loader . Il doit y avoir un meilleur moyen, sûrement ???

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

J'ai moi-même proposé une solution, qui est très similaire à ce que @satazor a publié plus haut dans le fil: https://github.com/jozanza/next-css-json-loader.

Ajoutez simplement quelques lignes à votre 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;
  },
};

Les styles sont importés en tant qu'objets js, il est donc très facile à utiliser avec glamor et des solutions similaires:

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

À votre santé! 🍻 :)

Existe-t-il un moyen de faire en sorte que cela fonctionne pour importer des fichiers de démarque sous forme de chaînes? J'utilise actuellement raw-loader, mais comme il s'agit d'un plugin webpack, il ne fonctionne pas sur le serveur.

@kristojorg

Je viens d'écrire un plugin babel pour l'importation de démarques. Sur mon mobile en ce moment, mais si vous affichez mon GitHub, vous le verrez.

@ khrome83 qui semble génial. Au plaisir de l'essayer

Merci @ khrome83! Je vais essayer

Je devais le faire très rapidement, donc je n'ai pas mis à jour le readme. Mais vous l'incluez simplement en tant que plugin babel, puis utilisez

importer un fichier depuis 'File.md';

Je l'ai fait fonctionner, merci !! Très utile

C'est hors sujet, mais comme le problème est clos, je me sens libre d'élaborer :)

Pour le démarquage, vous pouvez faire 2 choses.

(1)
La première consiste à inclure le fichier markdown sous forme de chaîne, puis à le traduire en html / react au moment de l'exécution. Vous pouvez le faire en utilisant le chargeur générique examples/with-globa-stylesheet/.babelrc pour css.

(2)
Une autre chose que vous pouvez faire est de traduire markdown au moment de la transpilation à l'aide de markdown-in-js
Cela peut être plus intéressant dans certains scénarios car le document de démarquage est déjà pré-rendu donc à l'exécution, il est plus rapide (il exécute juste js). En outre, la bibliothèque vous permet d'injecter des composants React personnalisés. Malheureusement, dans ce cas, vous devez écrire le démarque en ligne dans votre source.js comme ceci .

Si vous choisissez (2) sachez également qu'il existe un plugin atom fournissant une syntaxe hilight pour la syntaxe markdown-in-js et il s'appelle language-markdown-in-js

@davibe merci pour le tuyau! Je préférerais que le markdown soit analysé en tant que temps de construction, mais le seul problème que j'ai avec markdown-in-js est d'échapper aux backticks lors de la composition: (. Peut-être que je devrais essayer d'importer sous forme de chaîne en utilisant babel, puis de nourrir cela à markdown-in-js ?

@kristojorg

Il y a ses rendus de démarque. La raison pour laquelle j'ai écrit mon plugin était la même chose. Je tire le markdown sous forme de chaîne, puis je l'exécute via react-markdown. Cela fonctionne de mieux en mieux car je peux transmettre des composants de réaction pour représenter des éléments de rendu de démarque, comme le composant List pour gérer toutes les listes. Fonctionne bien avec Styled JSX.

Y a-t-il une mise à jour à ce sujet? À travers les commentaires ci-dessus, je vois qu'il n'y a toujours pas de solutions parfaites actuellement.
@arunoda
Est-il possible d'avoir un exemple utilisant un chargeur de style isomorphe - https://www.npmjs.com/package/isomorphic-style-loader?

Cela serait parfait!

Quelqu'un a-t-il une solution lors de l'importation d'un composant react à partir du package npm qui à son tour importe un fichier .css ou .scss? donc fondamentalement transpiler les fichiers importés depuis node_modules

J'utilise Create-React-App (CRA) depuis quelques semaines, mais aujourd'hui, je suis tombé sur Next.js et je suis vraiment excité car CRA ne prend actuellement pas en charge le rendu côté serveur (SSR), ce qui est vraiment dommage.
J'adorerais passer à Next.js pour son support SSR prêt à l'emploi, mais ne pas pouvoir importer des fichiers .scss me retient.
Quelqu'un a-t-il trouvé un moyen d'ajouter un chargeur SASS à la configuration Webpack?

D'accord avec cr101, ne pas avoir de support pour CSS / SASS signifie que je dois jeter les frameworks css comme la fondation, ce qui n'est pas une option pour moi.

J'utilisais le repo fourni par @davibe mais il ne le maintient plus, et la dernière version rompt avec la solution qu'il avait .

J'adorerais si quelqu'un a trouvé une solution à cela. La mise à jour vers 2.4.1 était absolument nécessaire en raison du bogue de sécurité, donc je n'ai pas la possibilité de redescendre.

@Yuripetusko @ cr101 @tgoldenberg Absolument d'accord. Je pense honnêtement que la suite est vraiment géniale de pouvoir travailler hors de la boîte. Tout va bien, même la structure codée en dur (comme le répertoire obligatoire /pages , /static etc.). Mais des modules scss totalement non supportés cassent tout pour nous. Nous avons une structure scss très complexe avec des points d'arrêt automatiques et un recalcul des proportions de tout. Nous avons travaillé si dur pour rendre notre structure si parfaite. Ensuite, c'est génial, nous ne pouvons pas simplement jeter tous les scss que nous avons en ce moment. Non pris en charge scss est la seule mais la chose la plus cruciale qui nous empêche de migrer vers ce bel outil.

En fait, # 1615 - il y a des actions en cours. @timmywil essaie de configurer isomorphic-style-loader pour travailler avec next . Tous ceux qui sont intéressés sont invités à se joindre et à participer.

J'ai essayé toutes les solutions, que ce fil pointe vers, mais pourraient faire fonctionner l'une d'entre elles. J'ai donc décidé d'essayer de faire ma propre tentative et je l'ai documenté ici

@almeynman merci! va certainement voir à votre approche!
Au fait, j'ai réussi à faire fonctionner les modules scss en suivant cet exemple. Tout ce que j'ai fait, c'est ajouter sass-loader et activer les sourcemaps.

J'ai réussi à créer next.js suport CSS (même SCSS) de cette manière.

Tout d'abord, dans next.config.js , modifiez la configuration du webpack en ajoutant des chargeurs donnés et une instance 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;
  }
};

Ensuite, dans le code du composant, exigez un fichier de style avec une condition. Cela garantit que seul le regroupement côté navigateur aura un module de style.

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

Si cela ne vous dérange pas les if (process.env.BROWSER) , cela fonctionne parfaitement.

Une bonne approche est ici

@almeynman IMO ce n'est pas une très bonne approche car vous chargez le code CSS pour l'ensemble du site Web sur chaque page au lieu de ne charger que les styles CSS pertinents pour cette page.
Importer uniquement les fichiers .scss dont vous avez besoin au lieu du CSS pour l'ensemble du site Web réduirait considérablement la taille des pages en ne chargeant que le code CSS dont vous avez besoin.

@ cr101 Salut, je ne le savais pas. Je n'ai pas vraiment utilisé cette configuration, je l'ai juste publiée pour référence pour les autres (je pensais que c'était bien ...). J'utilise toujours mon approche décrite dans le billet de blog . Si vous pouviez me donner des commentaires sur cette configuration, ce serait génial

Plus d'exemples et de discussions si quelqu'un est intéressé:

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

Sur la base de ce qui précède et de ce fil, j'ai pu utiliser PostCSS pour transformer:

  • Fichier SCSS global (les modules sont les mêmes, vous avez juste besoin d'un point d'entrée pour pré-compiler tous vos CSS pour la production).
  • CSS tiers séparé avec des polices personnalisées référencées via une URL relative (résolue par la magie de l'inlining).

en un seul fichier CSS à /static/styles/app.css pour servir en production, le rechargement à chaud fonctionnant toujours. Notez l'utilisation de styled-jsx mais cela peut être fait sans, en utilisant <style dangerouslySetInnerHTML={} />

postcss.config.js

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

next.config.js

Des chargeurs pour transformer .scss en mode dev pour le rechargement à chaud et l'extraction en un seul fichier .css dans prod. Cela me donne build/app.css donc sur la version de production, j'ai ajouté cp build/app.css static/styles/app.css après next build pour qu'il soit disponible en exportation statique et intégré dans l'en-tête personnalisé comme indiqué ci-dessous.

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

en-tête personnalisé

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>

J'espère que cela t'aides. Faites-moi savoir si quelqu'un a besoin de plus de précisions. Dans l'attente de plus de solutions également. J'espère que quelqu'un pourra éventuellement proposer un bon plugin car c'est encore une intégration assez délicate et lourde.

Au lieu d'extraire tous vos fichiers .scss un seul fichier CSS, il serait bien préférable de compiler chaque fichier .scss importé dans son propre fichier CSS. De cette façon, vous ne chargerez que les styles CSS dont vous avez besoin sur chaque page.
Je ne sais pas comment vous feriez cela.

Veuillez vérifier ma demande de tirage, je pense avoir une bonne solution:
https://github.com/zeit/next.js/pull/2638

@ cr101 c'est vrai en fait. Nous importons notre propre bibliothèque d'interface utilisateur interne dans différents projets, il y a donc toujours une énorme partie d'un fichier à charger (pas idéal, je sais, travaillant toujours sur la modularisation de cette bête). Ce serait la prochaine étape de compile and serve 1 file à X number of files at X locations . Cela devient plus compliqué lorsque vous prenez en compte les compromis entre la division en petits morceaux CSS par rapport aux versions externes cachable ET performantes hébergées sur CDN, donc je pense que ce sera un projet amusant mais impliquant en soi. EDIT - définitivement hors de portée de ce que Next est censé gérer, le mieux que nous devrions viser est un plugin ou un modèle Next.

Je ne sais pas si cela pose un problème de performances, mais c'est une solution assez simple si vous utilisez des composants stylisés ou similaires, créez simplement un 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>
);

Ce que j'aime dans cette approche, c'est que je peux personnaliser à partir du CSS source (ce que je dois faire la plupart du temps de toute façon), sans avoir à écrire des remplacements en plus des règles d'origine si j'ai importé le .css fichier à partir de node_modules .

Voici une solution simple pour importer des fichiers CSS à l'aide de babel-plugin-inline-import :

.babelrc

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

page / composant

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 c'est une belle solution mais j'obtiens toujours des erreurs (j'importe le build .css depuis https://github.com/Hacker0x01/react-datepicker). Etes-vous sûr de ne rien avoir d'autre en jeu ici? D'après les erreurs, il semble qu'il ait besoin d'un autre niveau de chargement CSS.

@hilarykitz , la solution @stovmascript fonctionne pour moi, pouvez-vous nous envoyer l'erreur que vous obtenez?

@stovmascript - comment vous débarrassez-vous du cache Babel.

  1. Créer un fichier CSS
  2. Importer le fichier
  3. Appliquer
  4. Changer de fichier CSS - ajouter un nouveau sélecteur et un nouveau style
  5. Témoin que Babel Cache conserve l'ancienne version

@ khrome83 vous devrez effacer les node_modules / .cache

J'ai trouvé une meilleure solution en utilisant le plugin babel-inline-loader qui efface le cache et fonctionne avec ce qui précède. Le problème avec cette méthode est que vous ne pouvez appliquer que des styles globaux. Lors de l'utilisation dans une balise non <style jsx global> , cela n'ajoutera pas le data-jsx, ce qui va à l'encontre de l'objectif.

J'ai trouvé une meilleure solution en utilisant le plugin babel-inline-loader qui efface le cache et fonctionne avec ce qui précède. Le problème avec cette méthode est que vous ne pouvez appliquer que des styles globaux. Lors de l'utilisation dans un non

J'ai ajouté un exemple utilisant la solution de @stovmascript :

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

Comment incluez-vous plus d'un css externe?
J'utilise 2 bibliothèques qui en ont besoin dans le même composant, chacune fonctionne séparément, mais je ne sais pas comment les combiner.

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

@almeynman obtient ceci:

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

@CHarnel essayez de mettre les deux dans la chaîne de modèle

@CHarnel essayez cette approche
<style jsx global>{ $ {rtStyle} $ {dpStyle} }</style>

@alanhr

j'essaye de mettre ces css dans un fichier js et de l'exporter

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

export default bootstrap + styles

et puis juste

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

Avec https://github.com/sheerun/extroted-loader que j'ai créé, vous pouvez utiliser ExtractTextPlugin à la fois pour le développement et la production, pas besoin de html différent en développement ou d'injection de css dans js.

@comus J'ai utilisé votre approche, ça marche bien, merci.

@sheerun gentil, merci

J'ai soumis un exemple encore plus complet à next.js:
https://github.com/zeit/next.js/pull/3451

Cela fonctionnait avant nextjs v4

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

Quelle est la raison d'utiliser cette approche pour charger des styles globaux jsx? <style jsx global>{ rtStyle }{dpStyle}</style>

Je me suis créé une solution basée sur emit-files-loader . Si quelqu'un est intéressé, je peux le publier ici, mais il repose sur une configuration de serveur personnalisée - en gros, vous devez être capable de servir statiquement un répertoire unique dans .next build dir. Il pourrait probablement être configuré sans serveur en s'appuyant sur la structure de chemin /_next/... du serveur.

Sinon, vous pouvez écrire import stylesheet from './styles/style.[scss|less|stylus|w/e]'; et ce sera le chemin public vers votre fichier de feuille de style, vous pouvez donc le mettre dans un <link> . Il inclut ?[hash] pour la mise en cache permanente et il effectue un rechargement à chaud.

@timneutkens J'ai vu celui-ci, y a-t-il une estimation sur "très bientôt"? Je vois que c'est déjà à Canary.
J'avais juste besoin d'une solution tout de suite, j'ai passé 2-3 jours à en chercher une et j'ai réussi à rédiger la mienne, ce qui est essentiellement une "solution facile". Je pense même à le combiner avec extract-text-webpack-plugin afin que l'on puisse joindre statiquement tous les fichiers .[css|stylus|less|scss] séparés et les avoir tous disponibles en tant que ressource statique unique comme il le ferait normalement sans suivant.

Le principal problème derrière ces problèmes, je pense, c'est qu'il y a beaucoup de "magie" en arrière-plan derrière les versions de production et de développement, avec un rechargement à chaud et des trucs ... On pourrait probablement lire la source et voir comment les choses sont assemblées. , mais ce serait génial si quelqu'un qui l'a construit écrivait des documents là-dessus, je pense que plus de gens pourraient contribuer.

@nikolakanacki très bientôt 🙏 🤐

je pense même à le combiner avec extract-text-webpack-plugin afin de pouvoir joindre statiquement tous les fichiers séparés. [css | stylus | less | scss] et les avoir tous disponibles comme une seule ressource statique comme il le ferait normalement sans next .

Les plugins que j'ai écrits pour la prochaine v5 le font déjà, ils seront bientôt open source 👍

En ce qui concerne l'écriture de documents sur les internes, nous prévoyons de documenter comment tout fonctionne après la sortie de la v5 🙏

@timneutkens Merci!

@timneutkens merci pour la mise à jour, veuillez poster une mise à jour ici lorsque cette chose arrivera!

des nouvelles à ce sujet?

Je ne sais pas à quelles autres nouvelles vous vous attendez 🤔

Cela a été publié dans Next.js v5.
C'est même dans le readme https://github.com/zeit/next.js#importing -css - sass - less - stylus-files

En outre, le PR mentionné a été fusionné et ce problème est clos.

créez simplement le dossier / static dans le projet racine, et placez votre file.css dans / static, puis à Header html structure hock.

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

puis utilisez className n'importe où!

@comus

Très complet et intelligent..merci pour cela..J'ai cherché ce genre de solution toute la journée.

créez simplement le dossier / static dans le projet racine, et placez votre file.css dans / static, puis dans Header html structure hock.

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

puis utilisez className n'importe où!

Créez un dossier «public» à la racine de votre application (où se trouve le fichier package.json).

Le support est ajouté via # 8626!

Cette page vous a été utile?
0 / 5 - 0 notes