【问题标题】:Render normalize.css + emotion styles with Next.js使用 Next.js 渲染 normalize.css + 情感样式
【发布时间】:2018-06-09 08:43:24
【问题描述】:

我正在尝试将 Normalize.css 添加为全局并为我的 CSS 模块使用情感。

首先我的.babelrc

{
  "presets": [
    ["env", {
      "modules": false,
      "useBuiltIns": true
    }],
    "next/babel"
  ],
  "plugins": [
    "syntax-dynamic-import",
    "transform-runtime",
    "transform-decorators-legacy",
    "transform-class-properties",
    "transform-object-rest-spread",
    "es6-promise",
    ["module-resolver", {
      "root": ["./src"],
      "alias": {
        "styles": "./styles",
        "assets": "./assets",
      },
      "cwd": "babelrc"
    }],
    ["inline-import", { "extensions": [".css"] } ],
    ["emotion", { "inline": true }]
  ]
}

添加 Normalize.css

在我的_document.js 中,我添加了规范化

import Document, { Head, Main, NextScript } from 'next/document';
import normalize from 'normalize.css/normalize.css';
import { extractCritical } from 'emotion-server';

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const page = renderPage();
    const styles = extractCritical(page.html);
    return { ...page, ...styles };
  }

  constructor(props) {
    super(props);
    const { __NEXT_DATA__, ids } = props;
    if (ids) {
      __NEXT_DATA__.ids = ids;
    }
  }

  render() {
    return (
      <html>
        <Head>
          <title>SSR</title>
          <style jsx global>{normalize}</style>
          <style dangerouslySetInnerHTML={{ __html: this.props.css }} />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

shown here

用 Emotion 添加我的 css 模块

import React, { Component } from 'react';
import Breadcrumb from 'components/Breadcrumb';
import Link from 'next/link';
import styled, { hydrate, keyframes, css, injectGlobal } from 'react-emotion';

// Adds server generated styles to emotion cache.
// '__NEXT_DATA__.ids' is set in '_document.js'
if (typeof window !== 'undefined') {
  hydrate(window.__NEXT_DATA__.ids);
}


  const basicStyles = css`
    background-color: white;
    color: cornflowerblue;
    margin: 3rem 0;
    padding: 1rem 0.5rem;
  `

  const Basic = styled.div`
    ${basicStyles};
  `

export default class extends Component {
  render() {
    return (
      <Basic>
        <p>Basic style rendered by emotion</p>
      </Basic>);
  }
}

shown here

问题

错误:样式表:insertRule 仅接受字符串。 在不变量(/home/riderman/WebstormProjects/tmp/node_modules/styled-jsx/dist/lib/stylesheet.js:274:11) 在 StyleSheet.insertRule (/home/riderman/WebstormProjects/tmp/node_modules/styled-jsx/dist/lib/stylesheet.js:125:7) 在/home/riderman/WebstormProjects/tmp/node_modules/styled-jsx/dist/stylesheet-registry.js:88:29 在 Array.map (本机) 在 StyleSheetRegistry.add (/home/riderman/WebstormProjects/tmp/node_modules/styled-jsx/dist/stylesheet-registry.js:87:27) 在 JSXStyle.componentWillMount (/home/riderman/WebstormProjects/tmp/node_modules/styled-jsx/dist/style.js:58:26) 在解决(/home/riderman/WebstormProjects/tmp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2616:12) 在 ReactDOMServerRenderer.render (/home/riderman/WebstormProjects/tmp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2746:22) 在 ReactDOMServerRenderer.read (/home/riderman/WebstormProjects/tmp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2722:19) 在 renderToStaticMarkup (/home/riderman/WebstormProjects/tmp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2991:25)

添加

查看源代码here

https://gitlab.com/problems/test-emotion-plus-global-nextjs

【问题讨论】:

    标签: css-modules next.js emotion server-side-rendering


    【解决方案1】:

    在 Zeit 的 styled-jsx 页面上似乎有一个问题:https://github.com/zeit/styled-jsx/issues/298

    根据这个问题,要么是外部样式,要么是您需要将css 标记添加到您的模板文字中。

    查看您的代码,您正在使用css 标记,并且看不到任何会导致此问题的外部样式。如果你没有得到明确的答案,我会说用 Zeit 跟进问题 298。 HTH,干杯!

    编辑

    摆脱那里的 jsx 样式,只需将 normalize 添加到您的全局模板字符串中:

    injectGlobal`
        ${normalize}
        html, body {
          padding: 3rem 1rem;
          margin: 0;
          background: papayawhip;
          min-height: 100%;
          font-family: Helvetica, Arial, sans-serif;
          font-size: 24px;
        }
      `;
    

    【讨论】:

    • 我没有使用style-jsx。不相关。
    • 您正在使用&lt;style jsx global&gt;,所以看起来您正在尝试使用。一个简单的解决方法是摆脱您的&lt;style jsx global&gt;... 并使用模板字符串注入规范化,我将使用该示例更新我的答案。
    【解决方案2】:

    我对此有一个额外的答案,它在TypeScriptNextJS 9 中运行良好。它还直接根据您的 node_modules 保留您的导入。

    Import raw-loader 用于模块:

    yarn add raw-loader
    

    global.d.ts 中,为 raw-loader 定义一个钩子

    declare module '!!raw-loader!*' {
      const contents: string;
      export = contents;
    }
    

    在我的_document.tsx 内部有一个名为 Meta 的组件(_app.tsx 也可以,但_document 确保 SSR),我有这个

    import normalizeCss from '!!raw-loader!normalize.css';
    
    const Meta = () => (
      <div>
        <Global
          styles={css`
            ${normalizeCss}
            body {
              // ...
            }
          `}
         ></Global>
      </div>
    );
    
    export default Meta;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-15
      • 1970-01-01
      • 2023-02-14
      • 2018-09-15
      • 2021-09-21
      • 2021-09-15
      • 2021-04-30
      • 2021-10-23
      相关资源
      最近更新 更多