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 变量的主要内容,如果未能解决你的问题,请参考以下文章

如何组合和使用多个 Next.js 插件

全局SASS/SCSS变量在Vue项目中应用解决方案

将 Sass/Scss 全局加载到 Vue 项目中

webpack 配置scssless全局样式(自定义的,vue-cli2/3)

使用样式化的组件创建像全局变量、函数、mixin 这样的 SASS

sass添加全局函数