Webpack sass 加载器无法识别全局变量文件
Posted
技术标签:
【中文标题】Webpack sass 加载器无法识别全局变量文件【英文标题】:Webpack sass loader does not recognize global variables file 【发布时间】:2016-06-02 16:28:11 【问题描述】:我有这个 sass 目录:
- _vars.scss
- main.scss
//vars.scss
$base-container: 1400px;
//main.scss
@import './vars';
在我的其他 js 文件中:
require('./some-module-sass-file');
//some-module-sass-file.scss
.container
width: $base-container;
问题是我在 vars 文件 中有全局变量,而 some-module-sass-file 无法识别它们并抛出错误:
undefined variable $base-container
【问题讨论】:
什么错误?顺便说一句,您如何导入vars
文件但拥有 _vars
文件并不明显(注意前导下划线)。
这肯定不是完整的错误消息。为了提供帮助 - 完整提供并正确格式化作为问题的一部分。
所以some-module-sass-file.scss
不会导入全局变量文件。
不,main.scss 可以
而some-module-sass-file.scss
没有。不清楚为什么 main 的导入会影响其他任何东西。
【参考方案1】:
不使用 sass-resources-loader:
感谢@Arseniy-II 帮助我得到这个答案,连同这个线程: https://github.com/webpack-contrib/sass-loader/issues/218
在你的 webpack 模块规则中使用加载器选项,你可以为 sass-loader 分配一个数据属性,然后你应该能够按预期使用所有 sass 函数:
module:
rules: [
// Apply loader
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
loader: 'sass-loader',
options:
data: '@import "path/to/global.scss";',
includePaths:[__dirname, 'src']
,
,
],
,
],
【讨论】:
这不是公认的答案吗?谢谢先生。 我猜这不是一个可接受的答案,因为提供给数据的全局会产生重复 重写 bulma 的 css 变量对我有用 小心这种方法,因为它会注入代码,因此会破坏您的源映射 在 webpack 4 中,Options such as data and file are unavailable and will be ignored.【参考方案2】:您必须将vars
文件导入使用这些变量的每个 Sass 部分,因为每个部分都是自己编译的;除非您专门导入它们,否则这些文件都不会“了解”其他文件。
如果你不想在每个 Sass 文件中都输入import
s,你可以查看baggage-loader,它会自动为你添加它们。
【讨论】:
第三方库呢?我遇到了麻烦,因为一些深度依赖无法解决它内置的变量... @tutuca 不确定我能否在没有更多信息的情况下提供帮助。这里的 TLDR 是 webpack 需要的每个 Sass 文件都是独立编译的。我想如果你包含 3rd 方 sass,它没有理由不能按预期工作,只要你在使用它的任何地方都包含它 这种方法的问题是你可能会在不知不觉中破坏基于加载顺序的优先规则。例如,如果您在一个文件中覆盖 twitter bootsrap 中的某些内容,然后在另一个 scss 文件中覆盖 twitter bootstrap 中的另一个内容,那么您的第一个覆盖将被第二个 scss 文件顶部的 bootstrap 覆盖。至少这是我在自己的应用程序中看到的。 @cdmo 值得注意的是,基于模块化/组件的架构倾向于避免那些基于顺序的行为。例如,给每个元素一个描述性的类名(不是 ID)并专门针对元素,而不是依赖于级联和继承的样式。你确实失去了 CSS 的一些“优雅”,但能够开发和重用独立模块是 IMO 的一个很好的权衡。 公平点,这是要避免的,“语义类”通常是一条更顺畅的路径。 :100:【参考方案3】:简答:Sass resources loader
长答案:
sass-resources-loader 允许在每个所需的 sass 文件中使用变量、mixins 等。
因此您可以在 vars.scss 中包含变量:
$main: #073288;
$secondary: #F6A906;
然后照常使用它们:
.my-component
background-color: $main;
color: $secondary;
你需要做的就是
安装 sass-resources-loader:
npm install sass-resources-loader --save-dev
然后配置你的 webpack.config:
loader: 'sass-resources-loader',
options:
resources: './path/to/vars.scss'
这是来自github 的示例
module:
rules: [
// Apply loader
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader',
loader: 'sass-resources-loader',
options:
resources: ['./path/to/vars.scss', './path/to/mixins.scss']
,
,
],
,
],
如果您对资源路径有疑问,请尝试使用如下路径:
const path = require('path')
resources: [path.resolve(__dirname, './../vars.scss')]
__dirname
在你的 webpack.config 中可用,不需要它。
【讨论】:
我不得不使用 path.resolve 而不仅仅是一个字符串:资源:[path.resolve(__dirname, './../vars.scss')]【参考方案4】:如果你有 Webpack 5 你必须使用 additionalData,其他选项现在无效:
loader: 'sass-loader',
options:
additionalData: '@import path/to/general.sass',
,
如果您这样做,您的通用 sass 或 scss 文件将被添加
【讨论】:
请将您的答案更新为正确的语法附加数据:'@import "path/to/general.sass";',【参考方案5】:Webpack 4 解决方案:
loader: 'sass-loader', options:
sourceMap: true,
prependData: '@import "pathto/vars";'
,
为了@import "pathto/vars";
工作,您需要配置 Webpack 以解析此类导入。所以它只是在前面加上一行。
此解决方案很好,因为您对源映射没有问题,例如使用 sass-resources-loader
【讨论】:
【参考方案6】:你可以使用 text-transform-loader 包。
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
loader: 'text-transform-loader',
options:
prependText: `@import "$path.resolve(__dirname, './base.scss')";`,
]
【讨论】:
以上是关于Webpack sass 加载器无法识别全局变量文件的主要内容,如果未能解决你的问题,请参考以下文章
Sass - 为从文件导入的所有类添加前缀(使用 sass 导入或 webpack 加载器)