Next.js: composant de style remplacé lors d'un rechargement à chaud

Créé le 28 mars 2018  ·  27Commentaires  ·  Source: vercel/next.js

  • [x ] J'ai recherché les problèmes de ce référentiel et je pense qu'il ne s'agit pas d'un doublon.

Comportement prévisible


Ma page contient ce code très basique :

import React from 'react'
import styled from 'styled-components'

const Title = styled.h1`
  color: pink;
  font-size: 50px;
`

export default () => <Title>My page</Title>

Lorsque je rafraîchis la page, je m'attends à ce que le titre soit de couleur rose

Comportement actuel


La première fois que la page est construite, le titre apparaît en rose. Lorsque je rafraîchis la page, la couleur rose n'est plus respectée.
Si je change la couleur du code en autre chose et que j'enregistre le fichier, la page sera mise à jour. Mais encore une fois, lors du rafraîchissement, les modifications sont à nouveau perdues. Je n'ai aucune idée de ce qui pourrait causer cela. Toute aide est appréciée.

Votre environnement


| Technologie | Versions |
|---------|---------|
| suivant | dernier |
| nœud | |
| système d'exploitation | arc |
| navigateur | vivaldi |

good first issue

Commentaire le plus utile

Ayant également ce problème

Modifier (solution) :

Ce problème est lié au fait que la configuration de babel n'est pas correctement configurée. Si vous regardez l'exemple officiel de NextJS avec des composants stylisés, vous remarquerez qu'ils ont un fichier .babelrc avec :

{
    "presets": ["next/babel"],
    "plugins": [["styled-components", { "ssr": true }]]
}

Ensuite, vous devez ajouter ce plugin aux devDependencies dans votre fichier package.json

"devDependencies": {
    "babel-plugin-styled-components": "^1.8.0"
},

Ensuite, exécutez votre commande d'installation, yarn install ou npm install et vous serez prêt à partir !

PS : assurez-vous de n'avoir qu'un seul onglet ouvert pour votre travail de développement localhost !

Tous les 27 commentaires

J'ai le même bug, avec une configuration différente. J'ai un monorepo avec deux dossiers :

  • app , avec mon application next.js
  • ui , avec ma 'bibliothèque ui' en utilisant des composants de style

Je l'ai dans un exemple de dépôt : https://github.com/lucleray/ssr-ui-library

Lorsque je mets à jour la couleur d'arrière-plan, par exemple, dans le dossier ui, et que j'enregistre le fichier, la page est mise à jour.
Mais alors, si je rafraîchis la page, les mises à jour sont perdues.

Est-ce que cela a quelque chose à voir avec l'ordre d'injection des feuilles de style dans <head> ?

@ianregister Non, l'ordre de l'injection dans <head> n'est pas lié

Le problème est que le serveur et le client ne rendent pas le même code pour les feuilles de style

J'ai le même bug et ce n'est pas que sur les styles. Le rechargement à chaud reprendra les modifications, mais pas l'actualisation du navigateur. Je dois réexécuter le serveur (node ​​server.js) afin de récupérer la dernière mise à jour. J'utilise [email protected] , je

@lucleray , essayez ceci:

Assurez-vous d'avoir babel-plugin-styled-components tant que dépendance et dans votre package.json, dites à babel que vous effectuez un rendu côté serveur.

Pensez qu'il s'agit simplement d'un problème de configuration auquel vous êtes confronté.

package.json
```json
"babelle": {
"env": {
"développement": {
"préréglages": ["suivant/babel"],
"plugins": [
[
"composants stylisés",
{
"ssr": vrai,
"displayName": vrai
}
]
]
},
"production": {
"préréglages": ["suivant/babel"],
"plugins": [
[
"composants stylisés",
{
"ssr": vrai,
"displayName": false
}
]
]
}
}
}

@tvthatsme J'ai ajouté babel-plugin-styled-components à la fois dans la bibliothèque d'interface utilisateur et dans l'application elle-même, mais j'ai toujours le même problème.

Vous pouvez vérifier ici :
https://github.com/lucleray/ssr-ui-library/blob/master/app/.babelrc
https://github.com/lucleray/ssr-ui-library/blob/master/ui/.babelrc

Je ne suis pas sûr que ce soit la configuration (configuration du pack Web) ou un bogue quelque part.

avoir un problème similaire où toute modification d'un composant (non liée aux styles) provoquera une erreur "Avertissement : Prop className ne correspond pas. Serveur :" sur la nouvelle page matérielle suivante. Besoin de redémarrer le serveur pour qu'il disparaisse.

@sea129 avez-vous pu réparer?

Lol, j'ai le même problème ici. @valeeum avez-vous pu le résoudre ?

J'ai fait quelques recherches sur ce problème, et je pense qu'il pourrait s'agir d'un lien vers une sorte de "mise en cache Webpack".

J'utilise le code ici comme exemple du problème : https://github.com/lucleray/ssr-ui-library

Le app utilise Next.js et a une dépendance sur le ui . J'utilise l'espace de travail de fil pour les lier, mais cela pourrait être un yarn link plus simple.

Côté serveur, le bundle n'inclut pas le module ui et le traite comme external (car il est dans node_modules).
Côté client, le bundle comprend le module ui .

Il apparaît ainsi dans les bundles .next/static (côté client) :

/***/ "../ui/bundle.js":
/*!***********************!*\
  !*** ../ui/bundle.js ***!
  \***********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, '__esModule', { value: true });

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var styled = _interopDefault(__webpack_require__(/*! styled-components */ "../node_modules/styled-components/dist/styled-components.browser.esm.js"));

const UiButton = styled.button`
  background: black;
`;

exports.UiButton = UiButton;


/***/ }),

Par contre, dans les bundles .next/server (côté serveur), cela se présente comme ceci :

/***/ "@monorepo/ui":
/*!*******************************!*\
  !*** external "@monorepo/ui" ***!
  \*******************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = require("@monorepo/ui");

/***/ }),

Ce qui est étrange, c'est que module.exports = require("@monorepo/ui") devrait se résoudre au package ui et fonctionner correctement. Mais il semble qu'il soit mis en cache et ne résout pas le package ui réel.

Si je change la couleur de fond du bouton dans le ui en bleu par exemple. Le rechargement à chaud met à jour la page correctement. Mais si je rafraîchis, la page est rendue côté serveur avec l'ancienne couleur (vert dans mon exemple). C'est comme si le bundle côté serveur ne résolvait pas la dépendance @monorepo/ui pour aller dans le package réel, mais en utilisait une version mise en cache.


Il l'a résolu en configurant webpack pour traiter @monorepo/ui pas comme une dépendance externe et le regrouper dans les bundles côté serveur, comme ceci : https://github.com/lucleray/ssr-ui-library/blob/ webpack-config/app/next.config.js

J'aimerais quand même comprendre ce qui se passe

require a un cache intégré ( require.cache ), c'est un comportement attendu pour les dépendances dans node_modules, car nous ne regrouperons rien dans node_modules sur le serveur (pour la vitesse de compilation).

D'accord, c'est logique.

Le problème est donc que le hot-reloader ne recharge pas les modifications de code dans les dépendances externes, côté serveur, n'est-ce pas ?

Dans l'exemple que j'ai partagé, je m'attends à ce que mes modifications de code soient chargées à la fois côté client (ce qui est le cas) et côté serveur (ce qui n'est pas le cas) en mode développement.

Le problème est donc que le hot-reloader ne recharge pas les modifications de code dans les dépendances externes, côté serveur, n'est-ce pas ?

Exactement, nous ne supprimons que les chemins complets de require.cache.

Comment pensez-vous que je pourrais résoudre ce @timneutkens ?

Dois-je supprimer @monorepo/ui des dépendances externes afin qu'il soit regroupé dans les bundles côté serveur ? Cela fonctionne mais puisque je suis déjà en train de le transpiler, ne vaudrait-il pas mieux l'exiger ?

Cela peut être aussi simple que d'utiliser https://github.com/martpie/next-plugin-transpile-modules pour activer la compilation de modules.

@timneutkens Pourquoi cela a-t-il été fermé ? ce problème existe toujours sur la dernière version

Toujours aussi ce problème

j'ai toujours ce problème aussi

Idem aussi ici

Ayant également ce problème

Modifier (solution) :

Ce problème est lié au fait que la configuration de babel n'est pas correctement configurée. Si vous regardez l'exemple officiel de NextJS avec des composants stylisés, vous remarquerez qu'ils ont un fichier .babelrc avec :

{
    "presets": ["next/babel"],
    "plugins": [["styled-components", { "ssr": true }]]
}

Ensuite, vous devez ajouter ce plugin aux devDependencies dans votre fichier package.json

"devDependencies": {
    "babel-plugin-styled-components": "^1.8.0"
},

Ensuite, exécutez votre commande d'installation, yarn install ou npm install et vous serez prêt à partir !

PS : assurez-vous de n'avoir qu'un seul onglet ouvert pour votre travail de développement localhost !

d'accord les gens. voici la soluce. créez un _document.js à la racine du répertoire et ajoutez ceci.

import Document, { Head, Main, NextScript } from 'next/document'
import { ServerStyleSheet } from 'styled-components'

class MyDocument extends Document {
  static getInitialProps ({ renderPage }) {
    const sheet = new ServerStyleSheet()
    const page = renderPage(App => props => sheet.collectStyles(<App {...props} />))
    const styleTags = sheet.getStyleElement()
    return { ...page, styleTags }
  }

  render () {
    return (
      <html>
        <Head>
          <title>Your site title</title>
          {this.props.styleTags}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

export default MyDocument

puis npm install --save -D babel-plugin-styled-components

créez également une application personnalisée dans le répertoire des pages, _App.js et ajoutez :

import React from "react";
import App from "next/app";

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;
    return <Component {...pageProps} />;
  }
}

export default MyApp;

vous êtes tous ensemble

Ayant également ce problème

Modifier (solution) :

Ce problème est lié au fait que la configuration de babel n'est pas correctement configurée. Si vous regardez l'exemple officiel de NextJS avec des composants stylisés, vous remarquerez qu'ils ont un fichier .babelrc avec :

{
    "presets": ["next/babel"],
    "plugins": [["styled-components", { "ssr": true }]]
}

Ensuite, vous devez ajouter ce plugin aux devDependencies dans votre fichier package.json

"devDependencies": {
    "babel-plugin-styled-components": "^1.8.0"
},

Ensuite, exécutez votre commande d'installation, yarn install ou npm install et vous serez prêt à partir !

PS : assurez-vous de n'avoir qu'un seul onglet ouvert pour votre travail de développement localhost !

Cela fonctionne, merci

Malheureusement, c'est toujours un problème.

J'assiste à quelque chose de bizarre cependant :

Si tu as

styled.h1`
color: red;
`

au chargement initial, il est rouge, lorsque vous le modifiez en

styled.h1`
color: purple;
`

il est ignoré, le texte devient noir, pas de styles.
Lorsque vous rechargez la page, elle devient violette comme prévu.
Mais lorsque vous changez ensuite la couleur en red , HMR fonctionne correctement et le texte devient rouge.
Vous pouvez le faire avec autant de couleurs si vous le souhaitez, comme si une sorte de mise en cache était en cours.

Ainsi, lorsque vous ajoutez un nouveau style via HMR, il est ignoré, mais lors du rendu initial, il est placé dans le cache, et si vous utilisez ce style ultérieurement via HMR, cela fonctionnera. Il n'est donc pas fourni correctement au navigateur sur HMR ?

Je n'ai pas de connaissances sur les composants internes de SC et Next.js, ce ne sont donc que mes suppositions.

ÉDITER:
cela a bien fonctionné sur les composants stylisés 5.0.0-rc.2

Je ne sais pas à quel point cette information sera pertinente, mais comment je l'ai corrigé pour moi-même, j'ai suivi l'exemple du prochain dépôt et intégré les bits manquants par morceaux
https://github.com/zeit/next.js/tree/canary/examples/with-typescript-styled-components

J'utilisais next.js et la solution @MaxMcKinney fonctionnait pour moi. Assurez-vous simplement que vous avez correctement configuré les préférences .babelrc car c'est un format ou des tableaux et des objets assez déroutants à suivre.

C'était mon fichier .babelrc par exemple :

{
    "presets": [
        [
            "next/babel",
            {
                "styled-jsx": {
                    "plugins": [
                        "styled-jsx-plugin-postcss"
                    ]
                }
            }
        ]
    ],
    "plugins": [
        [
            "styled-components",
            {
                "ssr": true
            }
        ]
    ]
}

Ce problème se produira si vous clonez et construisez sur l'un des exemples Next.js qui n'ont pas les mêmes dépendances package.json et les mêmes paramètres .babelrc . En plus de la solution MaxMckinney, assurez-vous que vous avez la bonne dépendance dans package.json . Il me manquait carrément "styled-components": "^5.0.0"

Dans mon cas, ajoutez simplement les fichiers _app.js et _document.js sous les pages floder, cela fonctionne bien.

// _app.js
import App from 'next/app'
import { ThemeProvider } from 'styled-components'

const theme = {}

export default class MyApp extends App {
    render() {
        const { Component, pageProps } = this.props
        return (
            <ThemeProvider theme={theme}>
                <Component {...pageProps} />
            </ThemeProvider>
        )
    }
}
// _document.js
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }
}

Dans mon cas, ajoutez simplement les fichiers _app.js et _document.js sous les pages floder, cela fonctionne bien.

// _app.js
import App from 'next/app'
import { ThemeProvider } from 'styled-components'

const theme = {}

export default class MyApp extends App {
    render() {
        const { Component, pageProps } = this.props
        return (
            <ThemeProvider theme={theme}>
                <Component {...pageProps} />
            </ThemeProvider>
        )
    }
}
// _document.js
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }
}

Comment dois-je l'utiliser dans Material-UI ?

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