Next.JS:使用全局 scss 中的 SASS 变量
Posted
技术标签:
【中文标题】Next.JS:使用全局 scss 中的 SASS 变量【英文标题】:Next.JS: Using SASS variables from global scss 【发布时间】:2020-07-12 01:30:40 【问题描述】:我有一个 Next.js 应用程序,其中在 pages/_app.js
文件中导入了一个 main.scss
全局 css 文件。
_app.js
import '../global-styles/main.scss'
export default function MyApp( Component, pageProps )
return <Component ...pageProps />
此文件中的样式有效。
我还使用 [component].module.scss 将一些模块化 scss 文件附加到组件。
我在variables.scss
文件中写入了一个变量,这是我在main.scss
中@import
的文件之一,
variables.scss
$mobile: 750px;
main.scss
@import './fonts.scss';
@import './variables.scss';
@import './global.scss';
但是,当我尝试在我的模块化 css 中使用这个变量时,我得到一个错误
./module-styles/navbar.module.scss (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-3-1!./node_modules/postcss-loader/src??__nextjs_postcss!./node_modules/resolve-url-loader??ref--5-oneOf-3-3!./node_modules/sass-loader/dist/cjs.js??ref--5-oneOf-3-4!./module-styles/navbar.module.scss)
SassError: Undefined variable: "$mobile".
on line 19 of /Users/Parv/Documents/reactx/module-styles/navbar.module.scss
>> @media (max-width: $mobile)
---------------------------^
我的问题是,为什么我在 main.scss 中声明的全局变量没有通过?
【问题讨论】:
【参考方案1】:它与 Next.js 无关,但与 sass-loader 的工作方式有关。 每次从 js 文件导入 scss 文件都被视为一个隔离 sass env,因此,没有“全局变量”这样的东西。
此行为要求您从使用其中一个变量的每个 scss 文件中导入 variables.scss
文件。
旁注,重要的是这些常见的scss
文件(例如您的variables.scss
)不会包含“常规”css,因为如果是这样,它们将被复制很多次(进口量)。
【讨论】:
【参考方案2】:我通过将全局变量添加到 next.config.js 来解决它。这不是一个好的解决方案,但它确实有效。
module.exports =
sassOptions:
includePaths: [path.join(__dirname, 'styles')],
prependData: `
$primary-font-regular: 'Gotham';
$primary-font-medium: 'Gotham';
$default-font-size: 16px;
$h1: 5.208vw;
$h4: 1.458vw;
$primary-color: #000000;
$gray: #CCCCCC;
`,
,
;
您可以点击此链接获取答案:https://github.com/vercel/next.js/pull/12277
【讨论】:
【参考方案3】:更简单的方法是通过变量导入添加文件并将别名添加到 tsconfig
sassOptions:
includePaths: ['./src'],
prependData: `@import "~@styles/variable.scss";`,
更新:
在文件 next.config.js 中需要添加这段代码(如果没有这个文件,你需要创建它)
module.exports = (phase, defaultConfig) =>
if ('sassOptions' in defaultConfig)
defaultConfig['sassOptions'] =
includePaths: ['./src'],
prependData: `@import "~@styles/variables.scss";`,
return defaultConfig;
在文件 tsconfig.json 中需要添加别名
"baseUrl": ".",
"paths":
...
"@styles/*": [
"src/styles/*"
],
...
然后在variable.scss中创建带有样式的文件:src/styles/variable.scss,你可以导入其他scss文件
【讨论】:
嗨 Sergey,您介意添加一下您是如何为 tsconfig 设置的吗?我尝试按照上面键入的方式添加它,但看起来 tsconfig 希望我们为每个属性名称和对象名称添加引号。 嗨,我更新了帖子,在 tsconfig 中只需要为样式文件夹添加别名 嗨 Sergey,这仍然给我以下错误:``` 错误 - ./scss/_variables.scss 无法从自定义 以外的文件导入全局 CSS。由于样式表的全局特性,为了避免冲突,请将所有第一方全局 CSS 导入移至 pages/_app.js。或者将导入转换为组件级 CSS(CSS 模块)。阅读更多:nextjs.org/docs/messages/css-global``` variables.scss 文件中应该只有 scss 变量、mixins 或函数。选择器不可用,因为它包含所有 scss 文件。 .module.scss 也是【参考方案4】:只需将其添加到您的 next.config.js 文件并重新启动
const path = require('path')
module.exports =
sassOptions:
includePaths: [path.join(__dirname, 'styles')],
prependData: `@import "main.scss";`
【讨论】:
以上是关于Next.JS:使用全局 scss 中的 SASS 变量的主要内容,如果未能解决你的问题,请参考以下文章
webpack 配置scssless全局样式(自定义的,vue-cli2/3)