在我的 VueJS 应用程序中使用 sass-loader 时,“/deep/”选择器无法正常工作

max*_*uty 7 css sass webpack vue.js vuejs2

在我的 Vue 2.6.10 webpack 应用程序中,我尝试添加 SASS,因为我们的团队希望将遗留应用程序从 LESS 迁移到 SCSS。在我的文档package.json中,我已将这些安装到我的文档devDependencies中:

\n
    \n
  • 萨斯(v.1.32.8)
  • \n
  • sass-loader (v10.1.1)
  • \n
\n

然后将node-sass(v5.0.0)安装到我的dependencies.

\n

我的node版本是:v15.4.0。根据这些文档,node-sass这是v5+的正确版本。

\n

在我的 Vue 组件中,我尝试使用/deep/::v-deep>>>选择器。我组建了一个工作游乐场,其中我有一个ParentComp.vue目标 aChildComp.vue的内部样式,/deep/如下所示:

\n
<style lang="scss" scoped>\n  .parent-container {\n    & /deep/ .child-comp {\n      background-color: tomato;\n      color: white;\n    }\n  }\n</style>\n
Run Code Online (Sandbox Code Playgroud)\n

耶!它在我的操场上运行得很好,使用了我在操场上控制的相同版本的东西。

\n

在我的应用程序中,当我尝试完全相同的设置时,我收到此编译错误:

\n
./src/components/MenuBarComp.vue (./node_modules/css-loader/dist/cjs.js?\n{"sourceMap":true}!./node_modules/vue-loader/lib/style-compiler?\n{"optionsId":"0","vue":true,"id":"data-v-4630c6ac","scoped":true,"sourceMap":true}!\n./node_modules/sass-loader/dist/cjs.js?\n{"additionalData":"/n          @import /"@/styles/_variables.scss/";/n        ","sourceMap":true}!\n./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/MenuBarComp.vue)\n\n\nModule build failed (from ./node_modules/sass-loader/dist/cjs.js):\nSassError: expected selector.\n   \xe2\x95\xb7\n77 \xe2\x94\x82   & /deep/ .child-test{\n   \xe2\x94\x82     ^\n   \xe2\x95\xb5\n  src/components/MenuBarComp.vue 77:5  root stylesheet\n
Run Code Online (Sandbox Code Playgroud)\n

根据我尝试过的许多其他建议::v-deep,我应该尝试使用or >>>。当我尝试使用这些选择器时,它编译得很好并且不再抛出异常,但什么也没有发生。实际上没有任何 CSS 能够像.parent[data-23423423] .child {}. 但后来我看到其他文章介绍了 SCSS 如何不支持这一点。

\n

因此,然后我回去尝试找出可能导致此错误的原因,并且在几天的时间里我尝试了数十种方法来尝试解决此问题,例如:

\n\n

我的 中已经有几个预先存在的 CSS 相关包package.json

\n
    \n
  • css-loader (v.3.1.0)
  • \n
  • 更少 (v3.0.4)
  • \n
  • less-loader (v4.1.0)
  • \n
  • 迷你 CSS 提取插件 (v0.6.0)
  • \n
  • 优化-css-assets-webpack-plugin (v5.0.3)
  • \n
  • postcss-导入 (v11.0.0)
  • \n
  • postcss-loader (v2.0.8)
  • \n
  • postcss-url (v7.2.1)
  • \n
  • vue-style-loader (v3.0.1)
  • \n
\n

最后,这是我的加载器在 webpack 中的设置方式:

\n
  function generateLoaders(loader, loaderOptions) {\n    const loaders = options.usePostCSS\n      ? [cssLoader, postcssLoader]\n      : [cssLoader];\n\n    if (loader) {\n      loaders.push({\n        loader: loader + \'-loader\',\n        options: Object.assign({}, loaderOptions, {\n          sourceMap: options.sourceMap,\n        }),\n      });\n    }\n\n    // Extract CSS when that option is specified\n    // (which is the case during production build)\n    if (options.extract) {\n      return [MiniCssExtractPlugin.loader].concat(loaders);\n    } else {\n      return [\'vue-style-loader\'].concat(loaders);\n    }\n  }\n\n  // https://vue-loader.vuejs.org/en/configurations/extract-css.html\n  return {\n    css: generateLoaders(),\n    postcss: generateLoaders(),\n    less: generateLoaders(\'less\'),\n    sass: generateLoaders(\'sass\'),\n    scss: generateLoaders(\'sass\', {\n      additionalData: `\n          @import "@/styles/_variables.scss";\n        `,\n    }),\n    stylus: generateLoaders(\'stylus\'),\n    styl: generateLoaders(\'stylus\'),\n  };\n};\n
Run Code Online (Sandbox Code Playgroud)\n

我怎样才能让/deep/选择器工作?

\n

max*_*uty 4

这是因为/deep/不支持sass. 您需要明确设置您的sass-loader使用方式,node-sass如下所示:

loader: 'sass-loader', options: { implementation: require('node-sass')
Run Code Online (Sandbox Code Playgroud)

sass-loader他们的页面上有一条注释说:

当心node-sass和sass安装时的情况!默认情况下,sass-loader 更喜欢 sass。为了避免这种情况,您可以使用实现选项。

实现选项接受 sass (Dart Sass) 或 node-sass 作为模块。

所以你的具体代码最终将被sass-loader用作:

scss: generateLoaders('sass', {
  implementation: require('node-sass'),
  additionalData: `
      @import "@/styles/_variables.scss";
    `,
}),
Run Code Online (Sandbox Code Playgroud)