如何使用webpack和Vue.js正确地@import外部SCSS?

时间:2016-12-28 19:07:52

标签: sass webpack vue.js

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

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

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

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。

2 个答案:

答案 0 :(得分:13)

知道了。

这是我的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')] },
},

看到区别?我将其扩展为包含loader名称和options对象的对象,而不是'sass-loader'字符串,因为options仅适用于sass-loader

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

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

如果没有该加载器,则必须为每个导入添加~前缀,该webpack将转换为node_modules文件夹,至少使用之前的配置。 但这会破坏第三方SCSS框架,例如Material Components Web,因为它们使用的@import语句没有前导~,例如here

内部.vue文件

这在.vue文件中不起作用,因为vue-loader默认情况下只使用sass-loader 而没有任何选项。 因此,如果您希望这样做,您可能需要使用vue-loader自己的选项,如in its documentation所述。

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

答案 1 :(得分:9)

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

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

<强>解决方案

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

第2步:打开“utils”文件,您将看到cssLoaders()函数,该函数返回vue-loader支持的语言的对象/地图。

您将在该地图中看到sassscss

第3步:将sassscss的值更改为:

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

第4步:转到您正在使用的.vue文件,将lang元素中的<style>属性更改为sass或{{ 1}}。

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

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

第6步:然后运行sass-loader,它应该有效。

为什么这样做?

<强>库

我挖了一下,事实证明sass-loader使用了node-sass,其中有一些选项,例如@ 22samuelk提到的npm run dev。 IncludePaths告诉node-sass或者更确切地说底层库LibSass包含来自该目录/路径的sass文件。

<强> Vue公司

Sass-loader选项

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

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

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

Vue-loader配置

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

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

value

{ test: /\.(key)$/, use: [ { loader: '//ld//-loader', options: { /*Options passed to generateLoaders('//ld//', options)*/ }, }, ], } 是文件扩展名。在这种情况下,可以是keysassscss是您要使用的加载程序。其中第3步显示为//ld//

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