styled-jsx
支持,可能会更优化将CSS导入JavaScript应用程序是Webpack等现代捆绑程序流行的一种做法。
但是,正确导入CSS十分棘手:与JavaScript不同,所有CSS都是全局范围的。 这意味着它不太适合捆绑。 尤其是多个页面之间的捆绑,其中样式在每页的CSS文件中分开,并且加载顺序很重要。
根据我们的测量, Next.js超过50%的用户使用的WebPack捆绑.css
文件,无论是通过@zeit/next-css
, @zeit/next-sass
, @zeit/next-less
,或自定义设置。 通过与公司交谈进一步证实了这一点。 有些通过导入CSS来具有所有样式,有些则将其用于全局样式,然后使用CSS-in-JS解决方案来对组件进行样式设置。
当前,我们有这三个插件可让您导入CSS,但是它们在CSS排序和某些加载问题中存在常见问题。 这样做的原因是@zeit/next-css
不对全局样式强制执行约定。 全局CSS可以导入到项目中的每个组件/ JavaScript文件中。
为了解决这些常见问题并使用户更轻松地导入CSS,我们计划引入对CSS导入的内置支持。 这将与styled-jsx相似,如果不使用该功能,将不会产生内置时间或运行时开销。
这项工作还使我们能够改善开发人员对该解决方案的体验。
Next.js应该支持现代CSS,并代表用户将其降级。 这种方法类似于我们支持现代JavaScript并将其编译到ES5的方式。
默认情况下,我们应该:
在开发过程中,应自动应用CSS编辑,类似于JavaScript热加载。
在生产中,应从JavaScript包中完全提取所有CSS,并将其发送到.css
文件中。
此外,此.css
应该(如果可能)进行代码拆分,以便在页面加载时仅下载关键路径CSS。
Next.js仅允许您在自定义pages/_app.js
内导入Global CSS 。
这是一个非常重要的区别(也是其他框架中的设计缺陷),因为允许将全局CSS导入应用程序中的任何位置,意味着由于CSS的级联性质,因此无法将任何代码拆分。
这是有意的约束。 因为例如当在组件中导入全局CSS时,从一页移动到另一页时,它的行为会有所不同。
使用范例
/* styles.css */
.red-text {
color: red;
}
// pages/_app.js
import '../styles.css'
export default () => <p className="red-text">Hello, with red text!</p>
Next.js将允许在您的应用程序中的任何地方使用纯CSS模块。
组件级CSS必须遵循命名CSS文件.module.css
的约定,以表明其意图与CSS模块规范一起使用。
与本地类名称(例如.foo :global(.bar) { ... }
结合使用时,可以使用:global()
CSS Modules说明符。
使用范例
/* components/button.module.css */
.btnLarge {
padding: 2rem 1rem;
font-size: 1.25rem;
}
.foo :global(.bar) {
/* this is allowed as an escape hatch */
/* (useful when controlling 3rd party libraries) */
}
:global(.evil) {
/* this is not allowed */
}
/* components/button.js */
import { btnLarge } from './button.module.css'
// import '../styles.css'; // <-- this would be an error
export function Button({ large = false, children }) {
return (
<button
className={
large
? // Imported from `button.module.css`: a unique class name (string).
btnLarge
: ''
}
>
{children}
</button>
)
}
我猜想像@zeit/next-sass
这样的插件已经可以使用当前支持的CSS模块, .module.scss
也可以使用吗? 还是短语“纯CSS模块”仅意味着.module.css
?
对我来说,大多数项目对Sass的支持都是成功还是失败。
为了支持此RFC(内置支持),将不建议使用@zeit/next-css/sass/less/stylus
插件。 我们仍在讨论sass在何种程度上将成为核心与插件的一部分。 我当前的想法是,当您添加node-sass
它将启用sass支持。 与我们对TypeScript所做的类似。 我们之所以不将其添加为依赖项,是因为由于本机绑定等原因,它相当大且安装非常缓慢。
这真让人兴奋! 就像今天一样,我被冲突的CSS类名绊倒了!
问题,它如何与TypeScript一起使用? 我未启用css-module的一个原因是,导入css模块会给任何对象(也许有点神奇,像.foo-bar
会变成一个名为fooBar
?的字段),这不是TS友好的。 由于默认情况下,现在Next是TS,因此我想我们可以在此问题上做得更好?
我不确定“自动为用户修复已知的flexbug”是否是个好主意。
我担心我们会陷入混乱的局面,在这种情况下,npm上的第三方组件库(包括css样式表)在nextjs环境中的行为将不同于其他环境(例如create-react-app)。
@TheHolyWaffle修复已知的flexbug会产生更可预测的行为-这也是Create React App所做的。
@zenozen根据CSS Modules规范,它不会对您的camelcase起到任何作用。 如果使用带破折号( class-name
)的类名,则需要在对象上显式访问它。
例如
import Everything from './file.module.css'
// later on
Everything['class-name']
对于TS,我们不打算使用任何魔术来处理这些类型,但是定义TS类型来处理这些文件非常容易。
declare module '*.module.css' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.module.scss' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.module.sass' {
const classes: { readonly [key: string]: string };
export default classes;
}
无论我们在这里做什么,都可以确保使用自定义PostCSS插件仍然很容易,就像现在使用@zeit/next-css
? 如果我们失去对此的支持,那将是真正的遗憾– CRA不支持此功能,因此,不可能以任何合理的方式使用Tailwind CSS之类的工具。
在这方面,我会小心这三个功能:
- 使用Autoprefixer自动添加特定于供应商的前缀(不支持旧版Flexbox)
- Polyfill或编译Stage 3+ CSS功能及其等效功能
- 自动为用户修复已知的“ flexbug”
...因为这一切都是通过PostCSS完成的,因此PostCSS插件的顺序在最终用户的控制之下非常重要。
我建议,如果您要默认启用这三个插件,则用户应该可以通过提供自己的postcss.config.js
文件来完全覆盖默认的PostCSS配置。 如果采用这种方法,他们将不得不手动添加这些插件,但是我认为必须要有一定程度的控制。
TL; DR请注意不要破坏用户对PostCSS的完全控制的能力,因此,我不能使用CRA,因此,如果不能再使用Next,我将感到非常难过。
@adamwathan的补充-非常高兴在这里获得有关postcss选项自定义外观的详细信息。 能够通过下一个插件以及postcss.config.js
修改postcss配置真是太好
我认为最好为所有css导入启用css模块(不仅对于.module
后缀),而且我们要成为全局的,我们需要指定.global
后缀。
CSS模块会很棒。 我认为保持*.module.(css|scss)
规范很好,因为它确实与create-react-app
对齐,允许打字稿键入,并允许Next.js新用户轻松迁移
使用typescript,您可以通过使用typed-css-modules和typed-scss-modules为每个*.(css|scss)
文件生成*.d.ts
来强制执行CSS模块类型,但是如果您不想这样做,并且仍然需要自动补全功能,可以使用以下VS Code扩展名:
https://marketplace.visualstudio.com/items?itemName=clinyong.vscode-css-modules
@adamwathan放心,我们将允许PostCSS配置! 我们不确定_exact_实现的外观如何,但是它应该随CSS pull request自然出现。
这很棒!! 有时间表吗? 今年会发生吗?
@andreisoare我们将合并此RFC的全球部分: https :
我们将继续尽快支持CSS模块!
如果我们可以继续在项目根目录中使用常规的postcss.config.js文件,则@adamwathan @Timer会很棒,因为我们现在可以使用next-sass
。
很高兴看到这成为核心。
RFC将支持AMP关键路径渲染吗?
记录下来,如果可以的话,应该使用styled-jsx,因为它允许您将css,html和js封装为1个想法,即一个组件。 如果您还没有意识到这一点(这是next.js用户的注意事项,而不是维护者的注意事项),那么您不必像bootstrap一样购买整个CSS UI Kit,您可以尝试1个组件,如果没有不能满足您的需求,您就可以将它扔掉,而不必承担处理外部CSS依赖包的负担。
我认为传播这些知识也非常重要,因为CSS经常被误解或事后思考,并且经常成为开发人员工作的祸根。 但是,通过适当的抽象,实际上可以很容易地进行推理。
仅仅因为“很多人”正在导入他们的CSS并不意味着这是一个好主意。
我认为关于react的最强大的功能之一就是它为您封装了CSS,HTML和JS。 并且如果您对CSS进行了侧向加载(导入),那么您可以从中受益,这是有益的反应。
记录一下:CSS-in-CSS(或HTML)是样式的高效传输层,将js和样式并置在一个文件中并不比将它们并置在一个目录中更好。
更重要的是-出于性能考虑,大多数上一代CSS-in-JS都会在构建时将CSS提取到CSS,因此必须正确管理静态CSS。 但是,尚未公开Next支持此类提取的方式。
记录一下:smile ::在诸如Bootstrap之类的框架上使用SASS,LESS仍然是一件很重要的事情,并且效果非常好! 封装不得在JS级别上发生。 使用BEM是替代方法。 支持这两种方式至关重要。
@timer这个(https://github.com/zeit/next.js/pull/8710)的前半部分是否意味着CSS的路径拆分现在可以工作了? 还是那还会来?
(相关,https://github.com/zeit/next-plugins/issues/190)
全局CSS不能拆分路径,因此不能。 仅CSS模块(在组件级别导入)会进行路径拆分。 👍
是否有解释如何影响问题#9392和#9385? 只是为了了解幕后发生的事情。 这样,我就可以解决如何在我的代码库中解决问题了。
你好我们正在寻求将React应用程序升级到next.js,主要是为了利用出色的工具和服务器端渲染。
但是对我们来说,能够使用CSS模块是一个非常困难的要求。 我们尝试使用CSS的下一个插件,但因#9392#9385等问题而遭受严重破坏。
CSS模块是否有任何ETA支持(甚至是实验性的)? 有什么办法可以加快其发展?
所以我们不能在组件级别导入css吗?
您可以,您只需要立即使用变通办法,直到问题解决。 我认为您可以在next-css问题上找到适合您的
抱歉,您遇到了一个愚蠢的问题:就全球CSS而言,这与仅在头部添加一个链接有何不同/更好?
@otw如果导入全局CSS,它将与其余代码一起通过构建管道,因此将其最小化,然后成为next.js构建和输出的一部分
取决于您是否有利。 我想大多数人都期待CSS模块,以便仅在加载特定组件时才加载特定组件所需的CSS。
就上下文而言,我们有一个开发人员团队,在过去两年中一直使用NextJS为早期创业公司构建将近40个Web应用程序。
我想借此机会概述我们如何设计应用程序样式,以显示当前需求,痛点,有关我们面临的某些必需npm的警告以及对拟议更改的某些担忧。
npm ci
来重建整个node_modules
文件夹,清除浏览器缓存,cache clear force console命令全部不起作用,因为这里有一些全局npm缓存。 因此,当更新导入到应用于组件的CSS / SASS模块中的文件时,我们非常希望热重装能够正常工作。 简而言之,组件执行的所有SASS处理都应注意导入的更改并保持有效的热重装。 这可以通过前面的项目符号中提到的webpack loader选项解决。我们对用组件CSS / SASS模块阻止全局选项的想法有些担心,因为我们有一些用例需要根据组件触摸html,body和root div标签以及生成的HTML的情况。由于通过门户等进行放置,因此该组件内不需要存在这些组件。我认为我们可以通过全局SASS和某些重组来解决其中的一些问题,因此我们不依赖于加载哪个组件来应用特定的全局CSS。
我们想要完全控制PostCSS,而不必处理被迫应用一组特定的默认值的情况。
抱歉,这是一个很长的答复,但我认为我们有一些值得分享的见解。 如果您有任何疑问,欢迎随时与我们联系,我们期待看到NextJS团队提出的下一个建议(双关语)!
@Soundvessel ,
我们对用组件CSS / SASS模块阻止全局选项的想法有些担心,因为我们有一些用例,需要根据组件触摸html,body和root div标签以及生成的HTML的情况。在所述组件内部不需要存在
如果我对您的理解正确,那么您仍然应该能够在CSS模块中使用:global
来实现这一目标。
@ Daniellt1
如果我对您的理解正确,那么您仍然应该能够在CSS模块中使用
:global
来实现这一目标。
请参阅上面的注释
与本地类名称结合使用时,允许使用CSS模块说明符
就我们的布局组件而言,我们的目标是<html>
, <body>
和没有本地类名的root div。
在有关此主题的视频中还提到他们正在考虑完全阻止:global
选项,考虑到大量的npms和CMS API会产生无法触及的标记,这对我来说没有意义通过作用域的CSS模块。
嘿@Soundvessel-这是我为团队内部录制的视频(您是如何访问的?),它不直接代表nextjs团队的观点,也不能保证自制作以来的最新信息在实验的早期阶段。 认为RFC是该主题的标准
我也要感谢您提出的解决方案,该解决方案允许使用CSS / SASS而不是在CSS解决方案中使用复杂的JS,而该解决方案需要其他语法(例如camelCased属性等)。具有多年直接使用HTML / CSS的经验,并且使我们不必将代码中看到的内容过于深入地转换为我们在屏幕上调试的内容,就变得更加容易。
只是想补充一下,除非我在上面没有提到,否则Sass的自动检测/启用很酷,但是Sass API选项也需要暴露在某个地方: [email protected]
建立了一个很好的模式,包括允许用户选择要应用的Sass引擎; 他们的选择可以接管1:1 ...
我想建议CSS模块的扩展是可配置的。
也许公开一个数组以支持.module.css
以外的多个扩展?
当您对某些开发人员有很多组件时,创建.module.css
文件并将其导入import "Component.module.css"
对我们来说似乎有些肿。
就我而言,我希望能够创建一个扩展名为.m.css
,说Component.m.css
并将其导入为import "Component.m.css"
除非Next.js团队表示存在一些技术上的困难,否则这将无法完成。
我不认为应该打开任何用于命名扩展的配置,因为这似乎是不必要的占用空间,但是我确实质疑.module.css
扩展的_need_是否这将是实现的一部分:
Next.js仅允许您在自定义页面/_app.js中导入Global CSS。
最初,我认为.module.css
对于构建来说是必要的,以检测应该解析为CSS模块的内容以及不应该解析的内容,但是如果在_app.js
之外的任何组件/页面中导入非模块会出错并中断构建,因此不需要命名约定,因为从_app.js
外部导入的任何内容本质上都应该是CSS模块。
这是纯粹按照惯例而不是被迫吗?
module.css
约定的选择与https://github.com/css-modules/css-modules已建立的修道院冲突
这里的例子:
https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/
和这里:
https://www.gatsbyjs.org/docs/css-modules/
是的,可能使扩展可配置可能会使扩展变得不必要。 但是至少您可以在一个常量文件中定义.module.css
,并且没有在几个地方进行硬编码以通过猴子补丁对其进行更改
@bySabi
提议的实现和create-react-app
之间的区别在于,完全不允许导入“常规样式表”,例如与another-stylesheet.css
链接的示例。 在那种情况下, .module.css
用于确定构建工具应以哪种方式处理哪个样式表。
CSS Modules规范根本没有建立命名约定。
我知道CSS模块不会在文件扩展名上建立任何约定,而是会如何导入模块。
我要去的地方是.module.css
是Next.js团队选择的约定,他们应该“促进”某些用户可以更改它的可能性,即使它是通过执行monkey patching
的安装后模块来完成的。 monkey patching
我认为.module.css
是第一个命名约定|
module.css
约定的选择与css-modules / css-modules已建立的修道院冲突
这里的例子:
create-react-app.dev/docs/adding-a-css-modules-stylesheet
和这里:
gatsbyjs.org/docs/css-modules是的,可能使扩展可配置可能会使扩展变得不必要。 但是至少您可以在一个常量文件中定义
.module.css
,并且没有在几个地方进行硬编码以通过猴子补丁对其进行更改
您在这里与您的观点相矛盾,create-react-app和gatsby正在将.module.css
用于同一功能。 这是一个既定的模式。
但是,更改命名约定不是既定模式,也没有理由在Next.js中允许它。
我认为.module.css是第一个命名约定| Next.Js施加的扩展。 如果我错了,请纠正我。
Next.js在配置选项上建立约定,例如:
pages
目录正在路由pages/api
是API路由.js
.tsx
.tsx
嗨@timneutkens
模式是CSS Modules
如何建立应如何将CSS文件导入JS对象的方式,所涉及CSS的名称是边际的。 在这方面,Next.js并未在新的实现中使用该特定模式。
Gatsby和CRA中的CSS Modules
已在Next之前实现: https :
我不怀疑使用的约定.module.css
,甚至知道我可以将CRA和Gatsby用户与CSS Modules
混淆。 选择一个合适的名字很困难,并不是每个人总是很高兴。
尽管我相信.m.css
约定更好,因为它更短(更适合扩展)和更少的冗余(import语句用于导入模块),但我希望您考虑到这一点。 在常量文件中定义常规,特别是.module.css
可以帮助修补它们。
无论如何,许多祝贺CSS模块。 您做得非常出色,这似乎是“几乎”不可能的任务。
如果我可以在命名约定上加上两分钱:我们有一个使用.pcss
扩展名的组件库,因为我们需要PostCSS进行编译,因此我们决定使用此命名约定,还需要将这些CSS作为模块导入。 您将如何处理此案? 我们目前正在破解Webpack配置并修补加载程序的测试正则表达式,但您可能会觉得它很脏。
我想象.module.css
支持postCSS,就像当前的.css一样。
我知道会发生什么,我想我需要休假。
在查看PR时: https :
我以为我读了这段代码:
index.module.css
.redText {
color: net;
}
import './index.module.css'
export default function Home () {
return (
<div id = "verify-red" className = "redText">
This text should be red.
</div>
)
}
显然与现实无关。 实际上,真正的代码是这样。
import {redText} from './index.module.css'
export default function Home () {
return (
<div id = "verify-red" className = {redText}>
This text should be red.
</div>
)
}
就像CRA或Gatsby中的CSS模块一样。 因此,我感到困惑。
对于这个错误,我深表歉意。
:-(
使用CSS模块时,主要问题是:
在我的项目中使用CSS模块,某些第三方组件也使用CSS模块。
但是...某些第三方组件使用全局CSS。
我认为.module.css
扩展名的解决方案易于理解和实施。
其他框架(CRA,Gatsby)已达成共识。
到目前为止,我还没有遇到有关扩展解决方案的任何问题。
因此,我希望促进.module.css
扩展名的发展。
如果还有关于CSS模块问题的解决方案,那更好。
@bySabi
虽然.m.css
较短,但我认为它不会更好。
是min.css
还是module.css
吗?
@ xyy94813或完全相反,所有css导入都是模块,带有.global.scss
将是全局文件
@felixmosh
但是,对已发布的组件不友好。
我认为该约定是一个很好的默认设置,但是最终应使某些特定于CSS模块的配置选项可用,例如那些传递给css-loader
配置选项,因为某些用户希望控制“范围”设置的方式。输出类名。 可以添加一个选项来提供正则表达式,该正则表达式确定哪些CSS文件作为“模块”加载。
因为某些用户希望控制“作用域”类名称的输出方式
为什么要这样的例子? 我想不到。
举例说明为什么要这么做? 我想不到。
@timneutkens好吧,我可能更喜欢输出一种命名模式,该命名模式基本上与我的全局类的命名模式一致,仅在末尾使用作用域字符串。
除此之外,我还考虑过构建后清除,拆分或加载的场景,在这些场景中我可能希望将某个命名空间列入白名单,但是我还没有解决这个问题
我认为重要的是要记住,一个自以为是的框架旨在为您做出决定,从而消除了初始设置并实现了统一性。
这些决策中的一些应该带有默认值,这些默认值可以通过配置选项或扩展名进行更改,但是随着您使所有内容都可自定义,您将增加代码库,从而创建更多代码来测试,维护和记录文档,进而需要维护这些文档。
如果您达到需要覆盖默认值的地步,那么范围输出哈希模式之类的东西就非常细致,很可能您只是在编写自己需要的自定义加载器。
当与新的React开发人员一起工作时,我总是发现通过className将范围界定样式的概念传达给组件要容易得多。 只需为您组件中的外部元素提供一个唯一的className(通常与您的组件名称相同),然后使用SCSS编写如下样式:
.Navbar {
.logo { ... }
.nav-item { ... }
}
我肯定会看到css-modules
的好处,但是我有点担心,由于不再支持上述方法,Next.js最终对新开发人员变得不那么友好了。 如果您看到很多人遇到CSS订购问题,也许这是一个不错的选择,但是我想知道是否可以至少通过next.config.js
禁用执行css-modules
next.config.js
。 也许我们甚至可以进行构建时检查,以确保所有样式都使用唯一的className进行适当范围划分,尽管不确定在技术上如何可行。
我有点担心,由于不再支持上述方法,Next.js最终对新开发人员变得不那么友好了
除非我误解了,否则我认为CSS模块不是排他性的,而是只有当您导入的文件具有*.module.css
命名模式或*.module.scss
,加载程序才会应用CSS模块的解析器。对于这个问题
@ lunelson-bl
与CRA或Gatsby仅在使用命名模式时才启用解析器相反,它是半排它的。Next将禁止非模块直接导入组件JS。
从RFC:
/* components/button.js */
import { btnLarge } from './button.module.css'
// import '../styles.css'; // <-- this would be an error
为了使用非模块类,您需要将样式表导入到仅导入_app.js
的全局样式表中(如果您希望将它们拆分并与组件文件共存)。 否则,需要将它们直接放入该全局样式表中。
我是next.js的新用户。 在阅读了此问题后,我感到有些困惑。 我认为if next.js支持build-in-css-support ,因此我们不需要@ next-css插件,但是它不起作用,并引发有关“ ModuleParseError”的错误。
如果我在@ next-css插件中添加以添加CSS导入支持,则它可以正常工作,因此如果不使用@ next-css,如何在CSS-support中进行构建,能否提供示例?
谢谢@all。
我是next.js的新用户。 看完这个问题后,我有些困惑。 我认为next.js支持build-css支持,因此我们不需要@ next-css插件,但是它不起作用,也不会收到有关“ ModuleParseError”的错误。
如果我将其添加到@ next-css插件中以添加对CSS导入的支持,那么它将起作用,因此如何在不使用@ next-css的情况下创建css-build,能否举个例子?
谢谢@ALL 。
将配置添加到您的next.config.js中,如下所示:
module.exports = {
experimental: {
css: true
}
}
@erkanunluturk谢谢,没关系,但是有实验功能警告,这有关系吗?
并与antd兼容吗? 我知道可以使用蚂蚁设计。
@Timer您能否提供示例导入蚂蚁设计使用[RFC] CSS支持? 谢谢。
在另一个链接中时,Router.push(“ /”)仍然有问题。 有人有解决方案吗? 请帮我非常感谢
:warning:请停止使用此线程,并希望它能很好地发布跟踪器。 这是RFC,他们仍在实施。
团队的最后一个有意义的评论是https://github.com/zeit/next.js/issues/8626#issuecomment -531415968您可以通过通过https://github.com/zeit/next启用它来评估当前实现
我错过了跟踪工作的可能性。 我们能帮你什么吗? @Timer是否可以将此RFC与里程碑,路线图联系起来? 从RFC中的观点来看,该怎么做?
不知道,如何保持步调:confused:
@StarpTech此RFC已完全实现; 全局CSS和CSS模块根据RFC说明工作。
您可以使用单个实验性标志进行测试!
我将锁定此线程,以防止进一步的通知蔓延。 如果有人发现问题,请打开一个新的问题并通知我们! 当支持正式标记为稳定(默认情况下处于启用状态)时,我们将在此处发布。
登陆9.2: https :
最有用的评论
无论我们在这里做什么,都可以确保使用自定义PostCSS插件仍然很容易,就像现在使用
@zeit/next-css
? 如果我们失去对此的支持,那将是真正的遗憾– CRA不支持此功能,因此,不可能以任何合理的方式使用Tailwind CSS之类的工具。在这方面,我会小心这三个功能:
...因为这一切都是通过PostCSS完成的,因此PostCSS插件的顺序在最终用户的控制之下非常重要。
我建议,如果您要默认启用这三个插件,则用户应该可以通过提供自己的
postcss.config.js
文件来完全覆盖默认的PostCSS配置。 如果采用这种方法,他们将不得不手动添加这些插件,但是我认为必须要有一定程度的控制。TL; DR请注意不要破坏用户对PostCSS的完全控制的能力,因此,我不能使用CRA,因此,如果不能再使用Next,我将感到非常难过。