【问题标题】:How to @import external SCSS properly with webpack and Vue.js?如何使用 webpack 和 Vue.js 正确 @import 外部 SCSS?
【发布时间】:2017-05-13 02:29:09
【问题描述】:

在 Material Component Web 的示例中,我希望能够从我的 node_modules 导入 SCSS,如下所示:

@import '@material/elevation/mdc-elevation';

但是,我在尝试运行 webpack 构建时收到此错误消息:

File to import not found or unreadable: @material/elevation/mdc-elevation.

@import './~/@material/elevation/mdc-elevation.scss'; 也不起作用。

我很确定问题出在我的 webpack 配置中,但我不知道在哪里。

他们在Material Components WebVue.js example 中做了什么才能让它发挥作用?

这是我的npm-debug.log,以备不时之需。 这是相应的 Git 存储库:sk22/spg-tinf-sem03/proj01

提前致谢!

编辑:我希望能够导入 scss 文件,而不是编译后的 css。

【问题讨论】:

标签: sass webpack vue.js


【解决方案1】:

知道了。

这是我的 webpack 2 配置的一部分 module.rules:

{
  test: /\.(sass|scss)$/,
  use: [
    'style-loader',
    'css-loader',
    {
      loader: 'sass-loader',
      options: {
        includePaths: [path.resolve(__dirname, 'node_modules')],
      },
    },
  ],
},

那么我做错了什么? 我的options 对象直接放在规则中,而不是加载器。

旧的 webpack 配置规则如下所示:

{
  test: /\.(sass|scss)$/,
  use: ['style-loader', 'css-loader', 'sass-loader'],
  options: { includePaths: [path.resolve(__dirname, './node_modules')] },
},

看到区别了吗?我没有使用 'sass-loader' 字符串,而是将其扩展为一个对象,其中包含 loader 名称和 options 对象,因为 options 仅适用于 sass-loader

(您也可以删除 path.resolve 并只写“node_modules”,但离开它可能更安全。)

查看此文档页面以获取更多信息。 https://webpack.js.org/configuration/module/#rule-use

如果没有那个加载器,你必须在每个导入前加上一个~,webpack 会将它转换为node_modules 文件夹,至少在我之前的配置中是这样。 但这会破坏像Material Components Web 这样的第3 方SCSS 框架,因为它们使用@import 语句本身没有前导~,例如here

.vue 文件内部

这在 .vue 文件中不起作用,因为 vue-loader 默认只使用 sass-loader 没有任何选项。 所以如果你想让它工作,你可能需要使用 vue-loader 自己的选项,如 in its documentation 所述。

(由于某种我不知道的原因,我无法让它工作......)

【讨论】:

【解决方案2】:

编辑:Webpack 现在有一个关于 sass-loader 的部分:https://webpack.js.org/loaders/sass-loader/ 还提到了包含路径。

@material 和 Vue 也有同样的问题。我设法在不直接调整 use 属性的情况下解决了问题。

解决方案

第 1 步:首先使用 CLI 创建一个默认的 Vue 2.1 项目。 您的文件结构将有一个./build 目录。

第 2 步:打开文件 'utils',您将看到一个 cssLoaders() 函数,它返回 vue-loader 支持的语言的对象/映射。

您会在该地图中同时看到 sassscss

第三步:将sassscss的值改为:

  sass:    generateLoaders('sass', {
    indentedSyntax: true,
    includePaths:   [path.resolve(__dirname, '../node_modules')]
  }),
    scss:    generateLoaders('sass', {
  includePaths: [path.resolve(__dirname, '../node_modules')]
}),

第 4 步:转到您正在使用的 .vue 文件,并将 <style> 元素中的 lang 属性更改为 sassscss

第 5 步:完成后,转到终端/控制台并安装 sass-loader

npm install sass-loader node-sass webpack --save-dev

第 6 步:然后运行 ​​npm run dev,它应该可以工作了。

为什么会这样?

我挖掘了一下,结果发现sass-loader 使用了node-sass,其中有一些选项,例如@22samuelk 提到的includePaths。 IncludePaths 告诉 node-sass 或更确切地说是底层库 LibSass 包含该目录/路径中的 sass 文件。

Vue

Sass 加载器选项

默认情况下,Vue 期望你的资产在你的项目src/assets 文件夹中(如果我错了,请纠正我)。但是,您可以使用~ 表示您希望从项目根目录开始,看起来像`~/node_modules/@material/smth/mdc-smth.scss。

现在,如果您希望您的 sass-loader 使用这些选项以外的其他内容,您需要明确告诉他们。

因此path.resolve(__dirname, '../node_modules' 因为utils 文件位于./build 中,您需要使用sass-loader 的绝对路径来了解查找位置。

Vue-loader 配置

这并不是特定于问题,但vue-loader.conf.js 中定义的 vue-loader 配置的工作方式如下:

它使用cssLoaders() 返回的映射来构建 webpack 期望的加载器。 返回的映射 ({key:value}) 然后通过提供 key 作为在 test: 中用于加载程序对象的文件扩展名来使用。 value 用作加载器对象。 喜欢这样的:

{
  test: /\.(key)$/,
    use: [
  {
    loader: '//ld//-loader',
    options: {
      /*Options passed to generateLoaders('//ld//', options)*/
    },
  },
],
}

其中key 是文件扩展名。在这种情况下,这将是 sassscss//ld//是你要使用的加载器。在Step 3中显示为'sass'

希望这可以解决一些问题。花了我一段时间,因为我刚开始使用 Vue。

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 2019-05-30
    • 2017-10-15
    • 2018-05-23
    • 2017-11-25
    • 2018-07-22
    • 2018-04-27
    • 2017-10-29
    • 2017-02-14
    相关资源
    最近更新 更多