Next.js: 使用 normalize.css 的首选方法?

创建于 2016-12-08  ·  27评论  ·  资料来源: vercel/next.js

以高性能方式加载 normalize.css(最好来自 NPM)的理想方法是什么? 我想避免将其作为静态资产加载,并仅为一点点 CSS 引入标头请求。

Glamour 有额外的glamor/reset ,但它比规范化要简单得多,而且不是我想要的(我不太确定如何将额外内容从 next 加载到 Glamour 中)。

最有用的评论

@jaydenseric你是正确的 Normalize.css 是 CSS 的 jQuery。 浏览器的 HTML 元素的默认样式仍然非常不一致,Normalize.css 有助于解决这个问题。 Normalize.css 是现代项目的旧版浏览器支持所必需的。

所有27条评论

您可以使用next/head

@nkzawa我已经使用next/head来加载一些全局样式,但是在项目中没有css-loader ,我怎么可能需要来自node_modules的 CSS 文件? 这是否可以在用户端缓存,或者是否会在每个标头请求中增加有效负载?

您想将style定义为next/head $ 中的文本,例如:

<Head>
  <style>{`
    body {
      margin: 0;
    }
  `}</style>
</Head>

您必须将normalize.css转换为.json或将组件转换为require ,但这将是目前 IMO 的最佳方式。 如果您在所有页面上都需要该文件,那么它将捆绑为一个块并且只加载一次,这样它就不会膨胀有效负载。

https://github.com/zeit/next.js/pull/222发布时,您也可以使用css-loader

谢谢。 这是我想的,但不知道目前是否有更自动的加载方式。 我想我可以在本地运行 Webpack 或 Gulp 以在下次访问之前进行转换。

很高兴知道 next 使用了常见的分块。 我现在对把东西塞进脑袋感觉好多了。 谢谢回答我的问题!

2016 年 12 月 9 日 01:11,Naoyuki Kanezawa [email protected]写道:

您想将样式定义为 next/head 中的文本,例如:




您必须将 normalize.css 转换为 .json 或需要的组件,但这将是目前 IMO 的最佳方式。 如果您在所有页面上都需要该文件,那么它将捆绑为一个块并且只加载一次,这样它就不会膨胀有效负载。

当 #222 发布时,您也可以使用 css-loader。


您收到此消息是因为您编写了该主题。
直接回复此电子邮件,在 GitHub 上查看它,或将线程静音。

想指出,glamor 实际上使用normalize.css ,尽管它是一个过时的版本 v3.0.2
https://github.com/threepointone/glamor/blob/master/src/reset.js

提出了拉取请求
https://github.com/threepointone/glamor/pull/154

只需导入import 'glamor/reset'即可。

如果您需要 5.0 或等待合并拉取请求,请随意使用我的 fork :)

@FrancosLab感谢您的提示! 我遇到了glamor/reset ,但没有注意到 normalize 是其中的一部分——我认为 glamor 的 README 中没有提到它。 谢谢你的公关!

那么对于[email protected]来说,现在最好的方法是什么? 我花了很多时间试图模仿with-global-stylesheet示例所做的事情,但没有成功。

因为normalize.css是一个包,仅仅复制文件是不够的(Node 的 require 解析使用package.main )。 此外, emit-file-loader (以及file-loader )似乎与示例 repo 的行为不同。 似乎将选项name=dist/[path][name].[ext]传递给加载程序时, path总是以-开头,导致文件在.next/dist/-/node_modules/normalize.css/normalize.css中,这是一个问题.

解决这个问题的方法基本上是将整个normalize.css文件复制到static文件夹中,或者可能将整个内容内联到style标记中(我正在使用样式化组件不过,用于造型)。

我尝试使用webpack-copy-plugin但看起来static文件夹不是从.next的,而是实际上来自根文件夹本身<root-folder>/static (其中pages生活)所以这也不起作用。

现在 Next.js 不依赖于 Glamour,有什么建议可以继续前进吗?

编辑:相关: https ://github.com/zeit/styled-jsx/issues/83,https://github.com/zeit/styled-jsx/pull/100,https : //github.com/zeit/ next.js/issues/544

with-global-stylesheet示例刚刚在此处更新:#1327!

1327 仍然不适用于像import 'normalize.css'这样简单的东西。 主要问题似乎是因为 Webpack 不在服务器上运行,所以无法在服务器中运行的任何文件上导入非 js 文件。

@migueller也许可以在 v2.0 之后切换到通用 Webpack ...: https ://github.com/zeit/next.js/issues/1245

@sedubois ,热切期待! 😄

你可以在那里添加你的投票😉

伙计们,我一直在通过sass-loader导入normalize $ ,即使没有刚刚合并的includePaths 。 您所要做的就是安装normalize-scssnormalize.css的 Sass 端口)并在您的最高级别(自定义_document 、布局或页面)添加<strong i="10">@import</strong> '~normalize-scss';会像with-global-stylesheet那样包含一个scss样式表。

现在,如果您宁愿导入原始文件,我敢打赌您可以使用babel-plugin-module-resolvernode_modules设置别名,就像我在示例中使用styles所做的那样,然后使用 js 导入它+ <style dangerouslySetInnerHTML={{ __html: normalize }} />

@orlin ,你不能简单地用 JS 导入它,因为它不会通过 Webpack,它会在服务器中引发错误。

@migueller ,它应该可以正常工作,就像在with-global-stylesteet示例中从js导入scss一样。 cssscss都由next.config.js中的 Webpack 加载器处理并转换为 js。 我只是没有提供import normalize from '...'因为我需要安装normalize.css并设置一个babel-plugin-module-resolver别名来为您提供一个有效的...路径。

@orlin

我已经克隆了这个例子,添加了normalize.css ,并玩了一下。 你是对的,有可能让它工作!

不过,我必须为其进行自定义配置,其中发出文件的输出名称是dist/[path]index.js ,因为如果您不复制package.json则 Node 的require不会找到它。 因为您不希望其他样式出现这种行为(存在于您的源代码中而不是node_modules ),所以您必须为 normalize.css (以及您可能正在使用的其他包)设置一个 Webpack 规则。

这可以作为一个短期修复,但如果有一些开箱即用的东西肯定会很好,正如在 #1245 和https://github.com/zeit/styled-jsx/pull/100#issuecomment中讨论的那样-277133969

@rauchg ,你认为为node_modules中存在的包做一个例子是个好主意吗? 我不介意制作一个新示例或扩展with-global-stylesheet示例。

@migueller将其添加到同一个示例中可能会更可取

@migueller我找到了一种超级干净的“最佳实践”方法来做到这一点。 将在with-global-stylesheet上做一个 PR ...我希望你没有花太多时间来破解它。

全局样式,包括重置或规范化,无论如何都是反模式。 组件应该控制自己的样式。 Normalize 是 CSS 的 jQuery。

@jaydenseric你是正确的 Normalize.css 是 CSS 的 jQuery。 浏览器的 HTML 元素的默认样式仍然非常不一致,Normalize.css 有助于解决这个问题。 Normalize.css 是现代项目的旧版浏览器支持所必需的。

这是我使用的方法:(https://github.com/zeit/next.js/#custom-document)

// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'
import flush from 'styled-jsx/server'

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const { html, head, errorHtml, chunks } = renderPage()
    const styles = flush()
    return { html, head, errorHtml, chunks, styles }
  }

  render() {
    return (
      <html>
        <Head>
          <title>My page</title>
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css" />
        </Head>
        <body className="custom_class">
          {this.props.customValue}
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

@vinzcelavi为什么要刷新样式?

@sospedra我不知道😬 也许它可以帮助: https ://github.com/zeit/styled-jsx#styled -jsxserver

您可能不想这样做,而是根据更新的文档调用Document.getInitialPropshttps ://github.com/zeit/next.js/#custom -document

为什么在Head中放置一个带有 CDN url 的link标记不是很好? 它对我有用。

@janoist1我认为这里的问题是我们希望从下一个开始规范化自己,而不是依赖外部 CDN。 它在开发中很好,但我不想在生产中依赖任何外部的东西。

如果使用next-css不是您的选择,这里有两种解决此问题的方法(也许您正在使用 CSS 模块,因此从 _app 导入 CSS 文件不会全局应用)。

我们首先在Head中为normalize.css包含一个link $,然后通过<style type='text/css'>{globalStyles}</style>应用一些自定义全局样式

import React from 'react'
import Document, { Head, Main, NextScript } from 'next/document'

const globalStyles = `
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
`

export default class MyDocument extends Document {
  render () {
    return (
      <html>
        <Head>
          <meta name='viewport' content='width=device-width, initial-scale=1' />
          <meta charSet='utf-8' />

          <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css' />

          <style type='text/css'>{globalStyles}</style>
        </Head>

        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}
此页面是否有帮助?
0 / 5 - 0 等级