Визуализируйте стили normalize.css + эмоции с помощью Next.js
Я пытаюсь добавить 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>
);
}
}
То же, что показано здесь
Addin мои модули CSS с Emotion
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>);
}
}
То же, что показано здесь
проблема
Ошибка: Таблица стилей:
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/ реагировать-dom / cjs / реагировать-dom-server.node.development.js:2746:22) в ReactDOMServerRenderer.read (/home/riderman/WebstormProjects/tmp/node_modules/ реагировать dom / cjs / реагировать-dom-server.node.development.js:2722:19) на renderToStaticMar Куп (/home/riderman/WebstormProjects/tmp/node_modules/react-dom/cjs/react-dom-server.node.development.js:2991:25)
добавленной
Проверьте исходный код здесь
1 ответ
Похоже, что есть проблема для этого на странице Zeit Styled-JSX: https://github.com/zeit/styled-jsx/issues/298
В соответствии с этим вопросом это либо внешние стили, либо вам нужно добавить css
тег к литералам вашего шаблона.
Глядя на свой код, вы используете css
тег и не вижу каких-либо внешних стилей, которые могут быть причиной этого. Если вы не получите однозначного ответа, я бы сказал, чтобы обсудить вопрос 298 с Zeit. HTH, ура!
редактировать
Избавьтесь от стилей jsx и просто добавьте нормализацию в глобальную строку шаблона:
injectGlobal`
${normalize}
html, body {
padding: 3rem 1rem;
margin: 0;
background: papayawhip;
min-height: 100%;
font-family: Helvetica, Arial, sans-serif;
font-size: 24px;
}
`;
У меня есть дополнительный ответ на этот вопрос, который хорошо работает в TypeScript
а также NextJS 9
. Он также сохраняет ваш импорт напрямую на основе ваших node_modules.
Import raw-loader
для модуля:
yarn add raw-loader
В global.d.ts
, определите ловушку для raw-loader
declare module '!!raw-loader!*' {
const contents: string;
export = contents;
}
В компоненте под названием Meta у меня внутри _document.tsx
(_app.tsx
тоже было бы хорошо, но _document
обеспечивает SSR), у меня такой
import normalizeCss from '!!raw-loader!normalize.css';
const Meta = () => (
<div>
<Global
styles={css`
${normalizeCss}
body {
// ...
}
`}
></Global>
</div>
);
export default Meta;