我知道这是一个多余的问题,但我故意打开了这个问题。 我花了三天时间设置 next.js 样板(使用 redux、redux-saga 等),两天时间我一直在设置加载外部 css 和 scss 文件。 我已经检查了with-global-stylesheet和with-scoped-stylesheet-and-postcss示例,但它们中的每一个都有在先前问题中提到的主要问题。 我已经看到太多开放和封闭的问题都在用 hacks 解决这个问题……我认为最好不要让问题去寻找最佳解决方案,而是使用当前可用的解决方案来解决它,直到找到更好的解决方案。 因为现在很多人都有这个问题,希望现在就解决!
我同意,只有 styled-jsx 有干净的(包括热重载)支持,这就是阻止我将 Next.js 用于任何事情的原因,但当我需要一些快速原型设计时。
我认为 CSS 的 CSS Modules 范围问题的解决方案是一个更清晰的解决方案,加上 CSS Modules 仍然可以将类传递给子组件(尝试在使用babel-plugin-inline-react-svg
导入的 SVG 上放置一个非全局类带有样式的 jsx)。
那和我更喜欢标准化.css
文件以尽可能防止框架锁定,并在生产中使用外部 CSS 文件进行缓存(如果您不幸还是要支持IE8)。
海量 +1
使用 next.js 几乎不可能实现像外部 css/scss 这样简单的事情,这让我感到非常沮丧,这使得它对我 90% 的应用程序毫无用处。
我正在使用引导程序,我需要一个配置,其中将有一个全局引导程序 css 导入,并添加外部范围的 css。
虽然我们设法使用样式化 jsx 1(用于处理编译的 webpack)使用外部手写笔,但由于引入了处理单独 css 文件的中断更改,因此很难在样式化 jsx 2 上弄清楚。
目前的做法:
import ComponentStyles from './footer.styl';
...
<style jsx>
{ComponentStyles}
</style>
很高兴看到https://github.com/zeit/next.js/tree/master/examples/with-styled-jsx-scss使用外部 scss 文件。
我们在设置环境时经历了同样的磨难。
最终我们解决了一个带有 scss+post css 和丢失网格的全局样式表。
热重载有效,所以虽然它不是一个理想的解决方案(由于全局样式表被一次性加载),但它是一个不错的折衷方案。
依赖关系
"autoprefixer": "^7.1.6",
"babel-plugin-module-resolver": "^2.7.1",
"babel-plugin-wrap-in-js": "^1.1.1",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"pixrem": "^4.0.1",
"postcss-easy-import": "^3.0.0",
"postcss-loader": "^2.0.8"
在package.json
...
"postcss": {
"plugins": {
"lost": {},
"postcss-easy-import": {
"prefix": "_"
},
"autoprefixer": {},
"pixrem": {}
}
}
...
在next.config.js
webpack: (config, { dev }) => {
config.module.rules.push(
{
test: /\.(css|scss)/,
loader: 'emit-file-loader',
options: {
name: 'dist/[path][name].[ext]'
}
}
,
{
test: /\.css$/,
use: ['babel-loader', 'raw-loader', 'postcss-loader']
}
,
{
test: /\.s(a|c)ss$/,
use: ['babel-loader', 'raw-loader', 'postcss-loader',
{ loader: 'sass-loader',
options: {
includePaths: ['styles', 'node_modules']
.map((d) => path.join(__dirname, d))
.map((g) => glob.sync(g))
.reduce((a, c) => a.concat(c), [])
}
}
]
}
)
return config
}
在pages/_document.js
...
import stylesheet from 'styles/main.scss'
...
<Head>
<style dangerouslySetInnerHTML={{ __html: stylesheet }} />
</Head>
...
然后您可以从 /styles/main.scss 开始管理您的样式
希望能帮助到你
我对这两个样式示例( with-global-stylesheet和with-scoped-stylesheets-and-postcss )中的每一个的问题是,它们都不容易与 Jest 和 Snapshot 测试与快照中的 CSS 集成。 已经有人成功地让 Jest 与 Webpack 一起工作,但那是通过专门跳过 CSS。
运行babel-jest
预处理器文件,如this SO answer中所述,似乎是一个糟糕的黑客攻击。
似乎获得外部 CSS 就像with-global-stylesheet你必须使用 Webpack,但要使用 Jest 你不能依赖 Webpack,只能依赖 Babel。
有人在这个空间有想法吗?
我面临着类似的问题。 我是 nextjs 的新手,我无法使示例“with-external-scoped-css”正常工作。 有时,我的 css 已加载,有时未加载。 不知道是不是你说的这个问题。
解决了此加载器的外部样式问题https://github.com/coox/styled-jsx-css-loader
@ilionic我已经检查过你的解决方案。 这很棒! 谢谢 :)
@arefaslani我不认为这个问题已经结束。
从 HTTP v1 开始,加载大量 CSS 仍然是一个可怕的性能负担,它显着增加了首次绘制的时间。
适当的外部样式支持将允许导入 CSS 并导致不是内联...
Also, this suggestion doesn't resolve use cases where a CSS framework like bootstrap needs to be included from node_modules. Including Bootstrap as an inline CSS on every page would be horrible. And would negate the benefits of browser caching, e.t.c
In short, I really don't think this issue can be closed... It's still very much an ongoing problem.
@israelidanny我知道你对 bootstrap 的意思,这不是灵丹妙药。 我们正在提取引导框架的核心部分来分离 css 文件,以便浏览器可以缓存它。 不理想,但是处理预处理器和 CSS 框架的这种尴尬推动了更新的 css-in-js 方法并减少了对 CSS 框架的依赖。
@ilionic我明白你在说什么,但仍然 - 拥有大量的内联 CSS 对性能不利(特别是第一帧的时间)。 我有很多项目我们对此进行了大量优化。
失去这一切是一种耻辱,特别是考虑到我们可以拥有服务器渲染的 DOM。
也许关闭此问题,但打开一个新问题,专门针对让我们链接外部 CSS 的解决方案?
忽视明显流行的开发实践会很奇怪。
@israelidanny同意,我们仍在为 CSS 性能而苦苦挣扎,并且没有进行重大重写,不清楚如何解决它,因此这个问题确实更深入。 在这种情况下,styled-jsx 可能是更相关的 repo?
@ilionic嗯,我不知道 styled-jsx 存储库是正确的地方。
问题不在于他们,问题在于启用 next.js 对外部 css 文件的支持,这可能涉及也可能不涉及 styled-jsx。
你怎么认为?
@israelidanny这不是最好的解决方案,但无论如何它都有效。 但你是对的。 在没有缓存的情况下在每个页面中内嵌所有 css 并不是最好的解决方案。 在这部分我也同意你的看法:
问题不在于他们,问题在于启用 next.js 对外部 css 文件的支持,这可能涉及也可能不涉及 styled-jsx。
并且绝对不同意@ilionic在:
在这种情况下,styled-jsx 可能是更相关的 repo
我使用styled-jsx/css loader管理了一个解决方案。 你可以从https://github.com/P233/nextjs-with-scss看到代码
但是,我注意到@import
ed scss 文件没有被监视并且不会触发热重载,这真的让我感到沮丧。
我创建了https://github.com/sheerun/extracted-loader来重新加载提取的样式表文件。 即使对于开发,它也能很好地工作,所以dangerouslySetInnerHTML
不是必需的。
你这样使用它:
config.module.rules.push({
test: /\.css$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
/* Your configuration here */
}))
})
config.plugins.push(new ExtractTextPlugin('index.css'))
@sheerun ,谢谢,但是我如何将我的 css 注入到组件中?
您不用注入,而是使用 ExtractTextPlugin 提取所有内容并编写以下内容:
<Head>
<link rel='stylesheet' type='text/css' href="/static/index.css" />
</Head>
在你的组件中
import './styles.scss'
应该够了
好的,但现在我有一个错误:
./components/Home/Home.js
找不到模块:错误:无法解析“D:\Sites\work\VisualProposal”中的“css-loader”
@ ./components/Home/Home.js 13:0-22
@ ./pages? 条目
@ 多 ./pages? 条目
我的 Home.js 组件:
import { observer } from 'mobx-react';
import './Home.scss'
import MainSection from './MainSection/MainSection'
import Sections from './Sections/Sections';
import Features from './Features/Features'
import Pricing from './Pricing/Pricing';
import Footer from './Footer/Footer'
const Home = () => {
return (
<div className="Home">
<MainSection/>
<Sections/>
<Features/>
<Pricing/>
<Footer/>
</div>
)
};
export default observer ( Home );
我的 next.config.js:
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
webpack: function ( config, { dev } ) {
config.module.rules.push({
test: /\.(sa|sc|c)ss$/,
use: ['extracted-loader'].concat(ExtractTextPlugin.extract({
use: [
"babel-loader",
{
loader: 'css-loader',
options: {
url: true,
minimize: !dev,
sourceMap: dev,
importLoaders: 2
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: dev,
plugins: [
require('autoprefixer')({
/* options */
})
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: dev
}
}
]
}))
});
config.plugins.push(new ExtractTextPlugin('index.css'));
if ( config.resolve.alias ) {
delete config.resolve.alias['react'];
delete config.resolve.alias['react-dom']
}
for (let index = 0; index < config.plugins.length; index += 1) {
if (config.plugins[index].constructor.name === "UglifyJsPlugin") {
config.plugins.splice(index, 1, new UglifyJSPlugin({
sourceMap: true,
parallel: true,
}));
break;
}
}
return config
}
};
那么我做错了什么?
我在样式表 img[src] 中添加了非常高级的 SCSS 示例,url()。 它应该与 now.sh 一起工作,并正确配置了热重载和导出:
https://github.com/sheerun/extracted-loader/tree/master/examples/with-next
@psycura我看到你使用 Windows 所以它可能不适合你,但请发送修复 PR
👎 遗憾的是 Nextjs 不允许使用外部 css 文件。 我想在我的项目中使用大量带有自己的样式表的即用型软件包。 但我不能! 我尝试了几种选择,但没有一个真正有效:已经为此花了一天时间。
@mkozhukharenko它适用于 css 和 scss 文件。 我将使用https://github.com/coox/styled-jsx-css-loader添加一个示例。 它将外部 css 加载为作用域或全局 styled-jsx。 对于通用的全局 scss,我建议使用 node-sass 和 postcss。
@arefaslani我尝试了所有选项,但都不适合我。 我对这个框架完全失望。 这么简单的任务怎么会这么难? 我不会再使用这种固执己见的框架框架。
@mkozhukharenko看这个例子: https :
只需尝试向您的文件中添加更多 css,您就会发现styled-jsx
无法处理。 我收到 'jsx-undefind' can't be cound 或'jsx-4231512' can't be found 错误
@arefaslani有没有办法在你的例子中使用这种模式?
import classes from './styles.scss'
const MyComponent = () => (
<header className={classes.header}>Hello</header>
)
@protoEvangelion不幸的是,目前它仅适用于 styled-jsx。
好的,谢谢您的快速回复:)
很遗憾,next.js 的构建一开始没有考虑重用现有资源。 只为 css 文件设置复杂的规则是多么浪费时间。
我正在研究这个问题的解决方案,允许所有 webpack 加载器工作。
我还想指出,我个人不喜欢人们在这个问题上的语气。
我完全理解你想导入 css。 我们非常清楚这一要求。 这就是为什么我花了一周的时间研究最好的解决方案👍
很快就会有更多的介绍。 到那时,请大家节日快乐🎅😄
Hi, 各位, 我在别的github 发现了一个解决方案,
使用skeleton-loader 遵照BEM规则达到类似css-modules 一样的效果,
因为会需要产生.scss.json, 之后再使用trash将产生的.scss.json 删除虽然感觉不是很理想, 但给各位发想看是否有其他更好的方法
Hi, everybody, I found a solution on another github,
Use skeleton-loader to comply with BEM rules to achieve the same effect as css-modules,
Because it will need to generate. Scss.json, then use the trash will be generated. Scss.json delete
Although it feels less than ideal, give it to you to see if there are any other better ways
https://github.com/imagine10255/nextjs-boilerplate/tree/feature/180105/skeleton-scss-module-ben/imagine10255
@timneutkens你的解决方案怎么样?
我创建了一个 Next 样板,支持导入 scss、css 和更多功能。 看看它,如果你喜欢它,给它一颗星;)
https://arefaslani.github.io/next-boilerplate
@Bobeta我已经开始工作了,在提交 PR 之前我想修复一些边缘情况。
@timneutkens很
@Bobeta我相信他会在发布并准备好供我们使用时在此线程上发布。
@jthegedus我相信他也会,但我想知道估计,以便人们可以根据@timneutkens做出决定
最有用的评论
我还想指出,我个人不喜欢人们在这个问题上的语气。
我完全理解你想导入 css。 我们非常清楚这一要求。 这就是为什么我花了一周的时间研究最好的解决方案👍
很快就会有更多的介绍。 到那时,请大家节日快乐🎅😄