NextJS 组件级 SASS 样式
Posted
技术标签:
【中文标题】NextJS 组件级 SASS 样式【英文标题】:NextJS component level SASS styling 【发布时间】:2020-06-30 07:23:26 【问题描述】:我正在开发一个简单的 NextJS 应用程序,但在使用 SASS/SCSS 进行组件级样式设置时遇到了问题。当用户第一次登陆页面时一切看起来都很好,但是当用户导航到页面 /about
或从 /about
到 /
时,组件样式没有得到渲染,用户需要刷新页面查看样式????
⚙️ 设置
./package.json
"dependencies":
"@zeit/next-css": "1.0.1",
"@zeit/next-sass": "1.0.1",
"autoprefixer": "^9.7.0",
"next": "^9.3.1",
"node-sass": "4.13.1",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"webpack": "^4.42.0"
./next.config.js
const webpack = require('webpack');
const withSass = require('@zeit/next-sass');
const withCss = require('@zeit/next-css');
module.exports = withCss(
withSass(
webpack(config)
config.module.rules.push(
test: /\.(eot|woff?2|ttf|otf|svg|png|jpe?g|gif)$/,
use:
loader: 'url-loader',
options:
limit: 100000,
,
,
);
return config;
,
),
);
./postcss.config.js
const autoprefixer = require('autoprefixer');
module.exports =
plugins: [autoprefixer],
;
???? 页数
./pages/index.js
import React from 'react';
import Layout from '../components/Layout';
import Home from '../components/Home';
class Index extends React.PureComponent
render()
<Layout>
<Home />
</Layout>
export default Index;
./pages/about.js
import React from 'react';
import Layout from '../components/Layout';
import Company from '../components/Company';
class About extends React.PureComponent
render()
<Layout>
<Company />
</Layout>
export default About;
???? 组件
./components/Layout.js
import React from 'react';
import AppBar from '../AppBar/AppBar';
import './Layout.scss';
class Layout extends React.PureComponent
render()
const children = this.props;
return (
<>
<AppBar />
<main className="Layout">
children
</main>
</>
);
export default Layout;
./components/Layout.scss
.Layout
background: #f00;
./components/AppBar.js
import Link from 'next/link';
import './AppBar.scss';
export default () => (
<header className="AppBar">
<Link href="/">
<a>Home</a>
</Link>
<Link href="/about">
<a>About</a>
</Link>
</header>
)
./components/AppBar.scss
.AppBar
background: #0f0;
./components/Home.js
import './Home.scss';
export default () => (
<div className="Home">Home</div>
)
./components/Home.scss
.Home
background: #00f;
./components/Company.js
import './Company.scss';
export default () => (
<div className="Company">Company</div>
)
./components/Company.scss
.Company
background: #ff0;
【问题讨论】:
你能看到请求文件的“网络”标签吗? 用户从a导航到b时,没有css请求,但是当用户刷新页面时,有http://localhost:3000/_next/static/css/styles.chunk.css?ts=158...
的css请求????
我认为您应该将其作为“变量”导入,然后调用它,如下所示:import css from "../styles.scss" export default () => <div className=css.example>Hello World!</div>
我尝试将它作为一个模块 <Component className=styles.Name />
/,同样的问题正在发生。另外,在我的一个 SCSS 中,我正在导入模块 CCSS。 ??????
【参考方案1】:
这就是我解决问题的方法。 ?
随着 Next.js 9.3 的发布,不再需要 @zeit/next-sass
和 @zeit/next-css
。 ?
我还执行以下操作:
styled-jsx-plugin-sass node-sassa
添加为 dev-dep
创建一个.babelrc
文件并添加以下内容:
"presets": [
[
"next/babel",
"styled-jsx":
"plugins": ["styled-jsx-plugin-sass"]
]
]
所以我有两种选择:
在<style jsx>
上添加我的 sass/scss
将我的组件 sass/scss 文件重命名为 <ComponentName>.module.scss
第二个选项是A的一个痛点,你需要import styles from './ComponentName.module.scss
并将元素类添加为className=styles.ComponentName
或className=styles['ComponentName-button']
。 ?
【讨论】:
是的,这很好,但是如果我想同时使用 CSS 框架类和自定义组件类,例如。className="col-sm-4 bg-success mycomponent__custom-class"
好吧,既然col-sm-4 bg-success
是全球性的,你可以这样做className='col-sm-4 bg-success $styles['ComponentName-custom']'
?
我同意导入 .module.scss 文件并将 classNames 添加到所有内容中很痛苦。你知道你是否可以像 Create-React-App 这样配置 NextJS,你所要做的就是导入 .scss 文件?我宁愿只使用 .scss 文件而不是 .module.scss 或 styled-jsx。
Nextjs repo 本身就有这个 issue 的票,你可以定期查看更新?github.com/vercel/next.js/discussions/14672【参考方案2】:
对于在 nextjs 11 之后寻找有效答案的任何人。您可以参考此repo,或阅读此article 中的完整详细信息
这是我使用过的完整的下一个配置代码
const withTM = require('next-transpile-modules')([]);
const withPlugins = require('next-compose-plugins');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = withPlugins([withTM],
reactStrictMode: true,
webpack: (config, buildId, dev, isServer, defaultLoaders, webpack ) =>
// Find and remove NextJS css rules.
const cssRulesIdx = config.module.rules.findIndex((r) => r.oneOf);
if (cssRulesIdx === -1)
throw new Error('Could not find NextJS CSS rule to overwrite.');
config.module.rules.splice(cssRulesIdx, 1);
// Add a simpler rule for global css anywhere.
config.plugins.push(
new MiniCssExtractPlugin(
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/chunks/pages/[contenthash].css',
chunkFilename: 'static/chunks/pages/[contenthash].css',
),
);
config.module.rules.push(
test: /\.(sa|sc|c)ss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
);
config.module.rules.push(
test: /\.tsx/,
use: [defaultLoaders.babel],
);
return config;
,
);
【讨论】:
以上是关于NextJS 组件级 SASS 样式的主要内容,如果未能解决你的问题,请参考以下文章
当浏览器样式与 nextjs 中带有情感样式组件的服务器不同时,样式不适用于第一个客户端渲染(也不是之后)