Next.js: Styled-Component überschrieben bei Hot Reload

Erstellt am 28. März 2018  ·  27Kommentare  ·  Quelle: vercel/next.js

  • [x ] Ich habe die Ausgaben dieses Repositorys durchsucht und glaube, dass dies kein Duplikat ist.

Erwartetes Verhalten


Meine Seite enthält diesen sehr einfachen Code:

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

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

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

Wenn ich die Seite aktualisiere, erwarte ich, dass der Titel die Farbe Rosa hat

Aktuelles Verhalten


Wenn die Seite zum ersten Mal erstellt wird, wird der Titel rosa angezeigt. Wenn ich die Seite aktualisiere, wird die rosa Farbe nicht mehr berücksichtigt.
Wenn ich die Farbe im Code in etwas anderes ändere und die Datei speichere, wird die Seite aktualisiert. Aber auch hier gehen die Änderungen beim Aktualisieren wieder verloren. Ich habe keine Ahnung, woran das liegen könnte. Jede Hilfe wird geschätzt.

Ihre Umgebung


| Technik | Version |
|---------|---------|
| weiter | neueste |
| Knoten | |
| Betriebssystem | Bogen |
| Browser | vivaldi |

good first issue

Hilfreichster Kommentar

Habe auch dieses Problem

Bearbeiten (Lösung):

Dieses Problem hängt damit zusammen, dass die Babel-Konfiguration nicht korrekt eingerichtet wurde. Wenn Sie sich das offizielle Beispiel von NextJS mit gestylten Komponenten ansehen, werden Sie feststellen, dass sie eine .babelrc Datei haben mit:

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

Dann müssen Sie dieses Plugin zu den devDependencies in Ihrer package.json Datei hinzufügen

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

Führen Sie dann Ihren Installationsbefehl aus, yarn install oder npm install und dann können Sie loslegen!

PS: Stellen Sie sicher, dass nur ein Tab für Ihre localhost-Entwicklungsarbeit geöffnet ist!

Alle 27 Kommentare

Ich habe den gleichen Fehler, mit einem anderen Setup. Ich habe ein Monorepo mit zwei Ordnern:

  • app , mit meiner next.js-App
  • ui , mit meiner 'UI-Bibliothek' mit Stilkomponenten

Ich habe es in einem Beispiel-Repo: https://github.com/lucleray/ssr-ui-library

Wenn ich beispielsweise die Hintergrundfarbe im ui-Ordner aktualisiere und die Datei speichere, wird die Seite aktualisiert.
Aber wenn ich die Seite aktualisiere, gehen die Updates verloren.

Hat das etwas mit der Injektionsreihenfolge der Stylesheets in <head> zu tun?

@ianregister Nein, die Reihenfolge der Injektion in <head> hängt nicht zusammen

Das Problem ist, dass Server und Client nicht denselben Code für Stylesheets rendern

Ich habe den gleichen Fehler und es ist nicht nur auf Styles. Beim Hot Reload werden die Änderungen übernommen, das Aktualisieren des Browsers jedoch nicht. Ich muss den Server erneut ausführen (node ​​server.js), um das neueste Update abzurufen. Ich verwende [email protected] , reagiere 16.3 und express für den Server.

@lucleray , versuche das:

Stellen Sie sicher, dass Sie babel-plugin-styled-components als Abhängigkeit haben, und teilen Sie babel in Ihrer package.json mit, dass Sie serverseitiges Rendering durchführen.

Denken Sie, dass dies nur ein Konfigurationsproblem ist, mit dem Sie konfrontiert sind.

Paket.json
```json
"baby": {
"env": {
"Entwicklung": {
"Voreinstellungen": ["next/babel"],
"Plugins": [
[
"gestylte Komponenten",
{
"ssr": wahr,
"displayName": wahr
}
]
]
},
"Produktion": {
"Voreinstellungen": ["next/babel"],
"Plugins": [
[
"gestylte Komponenten",
{
"ssr": wahr,
"displayName": falsch
}
]
]
}
}
}

@tvthatsme Ich habe babel-plugin-styled-components sowohl in der UI-Bibliothek als auch in der App selbst hinzugefügt, aber ich habe immer noch das gleiche Problem.

Sie können hier überprüfen:
https://github.com/lucleray/ssr-ui-library/blob/master/app/.babelrc
https://github.com/lucleray/ssr-ui-library/blob/master/ui/.babelrc

Ich bin mir nicht sicher, ob es sich um eine Konfiguration (Webpack-Konfiguration) oder um einen Fehler handelt.

Wenn Sie ein ähnliches Problem haben, bei dem alle Änderungen an einer Komponente (nicht im Zusammenhang mit Stilen) einen Fehler verursachen "Warnung: Prop className stimmte nicht überein. Server:" auf der nachfolgenden harten Seite frisch. Sie müssen den Server neu starten, damit er verschwindet.

@sea129 konnten Sie das

Lol, habe hier das gleiche Problem. @valeeum konntest du es lösen?

Ich habe ein wenig zu diesem Thema recherchiert und denke, es könnte sich um eine Art "Webpack-Caching" handeln.

Ich verwende den Code hier als Beispiel für das Problem: https://github.com/lucleray/ssr-ui-library

app verwendet Next.js und ist abhängig von ui . Ich verwende den Arbeitsbereich von Garn, um sie zu verknüpfen, aber es könnte ein einfacheres yarn link .

Auf der Serverseite enthält das Bundle nicht das Modul ui und behandelt es als external (weil es in node_modules ist).
Auf der Clientseite enthält das Bundle das Modul ui .

In den Paketen .next/static (clientseitig) sieht es so aus:

/***/ "../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;


/***/ }),

Auf der anderen Seite sieht es in den .next/server (serverseitigen) Bundles so aus:

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

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

/***/ }),

Seltsam ist, dass module.exports = require("@monorepo/ui") in das Paket ui werden sollte und einfach gut funktioniert. Aber es scheint, als wäre es zwischengespeichert und wird nicht in das eigentliche ui Paket aufgelöst.

Wenn ich die Hintergrundfarbe des Buttons im ui zum Beispiel auf blau ändere. Der Hot Reloader aktualisiert die Seite korrekt. Wenn ich jedoch aktualisiere, wird die Seite serverseitig mit der alten Farbe gerendert (in meinem Beispiel grün). Es ist, als ob das serverseitige Bundle die @monorepo/ui Abhängigkeit nicht auflöst, um das eigentliche Paket zu erhalten, sondern eine zwischengespeicherte Version davon verwendet.


Es wurde gelöst, indem Webpack so konfiguriert wurde, dass @monorepo/ui nicht als externe Abhängigkeit behandelt und in den serverseitigen Bundles wie folgt gebündelt wurde: https://github.com/lucleray/ssr-ui-library/blob/ webpack-config/app/next.config.js

Ich würde trotzdem gerne verstehen was los ist 🤔

require hat einen eingebauten Cache ( require.cache ) Dies ist das erwartete Verhalten für Abhängigkeiten in node_modules, da wir nichts innerhalb von node_modules auf dem Server bündeln (aus Gründen der Kompilierungsgeschwindigkeit).

Okay, das macht Sinn.

Das Problem ist also, dass der Hot-Reloader die Codeänderungen in externen Abhängigkeiten auf der Serverseite nicht neu lädt, oder?

In dem von mir geteilten Beispiel erwarte ich, dass meine Codeänderungen sowohl auf der Clientseite (was der Fall ist) als auch auf der Serverseite (was nicht der Fall ist) im Entwicklungsmodus geladen werden.

Das Problem ist also, dass der Hot-Reloader die Codeänderungen in externen Abhängigkeiten auf der Serverseite nicht neu lädt, oder?

Genau, wir löschen nur vollständige Pfade aus dem require.cache.

Wie denkst du könnte ich das @timneutkens lösen?

Sollte ich @monorepo/ui aus den externen Abhängigkeiten entfernen, damit es in den serverseitigen Bundles gebündelt wird? Das funktioniert, aber da ich es bereits transpiliere, wäre es nicht besser, es einfach zu verlangen?

Es könnte so einfach sein, wie https://github.com/martpie/next-plugin-transpile-modules zu verwenden, um die

@timneutkens Warum wurde das geschlossen? Dieses Problem besteht immer noch in der neuesten Version

Habe das Problem auch immer noch

Ich habe das Problem auch immer noch

Dito auch hier

Habe auch dieses Problem

Bearbeiten (Lösung):

Dieses Problem hängt damit zusammen, dass die Babel-Konfiguration nicht korrekt eingerichtet wurde. Wenn Sie sich das offizielle Beispiel von NextJS mit gestylten Komponenten ansehen, werden Sie feststellen, dass sie eine .babelrc Datei haben mit:

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

Dann müssen Sie dieses Plugin zu den devDependencies in Ihrer package.json Datei hinzufügen

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

Führen Sie dann Ihren Installationsbefehl aus, yarn install oder npm install und dann können Sie loslegen!

PS: Stellen Sie sicher, dass nur ein Tab für Ihre localhost-Entwicklungsarbeit geöffnet ist!

ok Leute. hier ist die lösung. Erstellen Sie eine _document.js im Stammverzeichnis des Verzeichnisses und fügen Sie diese hinzu.

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

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

Erstellen Sie außerdem eine benutzerdefinierte App im Seitenverzeichnis, _App.js und fügen Sie Folgendes hinzu:

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;

du bist fertig

Habe auch dieses Problem

Bearbeiten (Lösung):

Dieses Problem hängt damit zusammen, dass die Babel-Konfiguration nicht korrekt eingerichtet wurde. Wenn Sie sich das offizielle Beispiel von NextJS mit gestylten Komponenten ansehen, werden Sie feststellen, dass sie eine .babelrc Datei haben mit:

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

Dann müssen Sie dieses Plugin zu den devDependencies in Ihrer package.json Datei hinzufügen

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

Führen Sie dann Ihren Installationsbefehl aus, yarn install oder npm install und dann können Sie loslegen!

PS: Stellen Sie sicher, dass nur ein Tab für Ihre localhost-Entwicklungsarbeit geöffnet ist!

Das funktioniert, danke

Leider ist es immer noch ein Thema.

Ich beobachte jedoch etwas Seltsames:

Wenn Sie haben

styled.h1`
color: red;
`

Beim ersten Laden ist es rot, wenn Sie es ändern auf

styled.h1`
color: purple;
`

es wird ignoriert, Text wird schwarz, keine Stile.
Wenn Sie die Seite neu laden, wird sie wie erwartet lila.
Aber wenn Sie dann die Farbe in red ändern, funktioniert HMR ordnungsgemäß und der Text wird rot.
Sie können dies mit so vielen Farben tun, wie Sie möchten, z. B. wenn eine Art Caching stattfindet.

Wenn Sie also einen neuen Stil über HMR hinzufügen, wird er ignoriert, aber beim ersten Rendern wird er im Cache abgelegt, und wenn Sie diesen Stil später über HMR verwenden, wird es funktionieren. Es wird also auf HMR nicht richtig an den Browser geliefert?

Ich habe keine Kenntnisse über die Interna von SC und Next.js, daher sind dies nur meine Vermutungen.

BEARBEITEN:
bei gestylten Komponenten hat es gut funktioniert 5.0.0-rc.2

Ich bin mir nicht sicher, wie relevant diese Informationen sein werden, aber wie ich es für mich selbst behoben habe, bin ich dem Beispiel aus dem nächsten Repo gefolgt und habe die fehlenden Teile einzeln integriert
https://github.com/zeit/next.js/tree/canary/examples/with-typescript-styled-components

Ich habe next.js verwendet und die @MaxMcKinney- Lösung hat für mich funktioniert. Stellen Sie einfach sicher, dass Sie die Einstellungen von .babelrc richtig konfiguriert haben, da es sich um ein ziemlich verwirrendes Format oder Arrays und Objekte handelt, denen Sie folgen müssen.

Dies war zum Beispiel meine .babelrc Datei:

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

Dieses Problem tritt auf, wenn Sie eines der Next.js-Beispiele klonen und aufbauen, die nicht die gleichen package.json Abhängigkeiten und .babelrc Einstellungen aufweisen. Stellen Sie zusätzlich zur MaxMckinney-Lösung sicher, dass Sie die richtige Abhängigkeit in package.json . Ich habe "styled-components": "^5.0.0" regelrecht vermisst

In meinem Fall fügen Sie einfach die Datei _app.js und _document.js unter Seiten floder hinzu, es funktioniert gut.

// _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()
    }
  }
}

In meinem Fall fügen Sie einfach die Datei _app.js und _document.js unter Seiten floder hinzu, es funktioniert gut.

// _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()
    }
  }
}

Wie soll ich es in der Material-UI verwenden?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

ghost picture ghost  ·  3Kommentare

havefive picture havefive  ·  3Kommentare

YarivGilad picture YarivGilad  ·  3Kommentare

rauchg picture rauchg  ·  3Kommentare

sospedra picture sospedra  ·  3Kommentare