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

22s*_*elk 12 sass webpack vue.js

与Material Component Web的示例一样,我希望能够从我node_modules这样导入SCSS :

@import '@material/elevation/mdc-elevation';
Run Code Online (Sandbox Code Playgroud)

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

File to import not found or unreadable: @material/elevation/mdc-elevation.
Run Code Online (Sandbox Code Playgroud)

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

我很确定问题出在我的webpack配置中,但我无法弄清楚在哪里.

他们在Material Components WebVue.js示例中做了什么才能使其工作?

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

提前致谢!

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

22s*_*elk 13

得到它了.

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

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

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

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

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

看到不同?我将它扩展为一个包含loader名称和options对象的对象,而不是'sass-loader'字符串,因为options它只适用于sass-loader.

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

有关详细信息,请查看此文档页面.https://webpack.js.org/configuration/module/#rule-use

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

里面的.vue文件

这在.vue文件中不起作用,因为默认情况下vue-loader只使用没有任何选项的sass-loader .因此,如果您希望它能够工作,您可能需要使用vue-loader自己的选项,如其文档中所述.

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


Bye*_*bye 9

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

我和@material和Vue有同样的问题.我设法解决了问题,而没有use直接调整属性.

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

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

你也可以看到sass,并scss在该地图.

步骤3:更改的值sassscss给:

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

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

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

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

第6步:然后运行npm run dev它应该工作.

为什么这样做?

图书馆

我挖了一下,结果是sass-loader使用node-sass,它有一些选项,比如includePaths@ 22samuelk提到的一个选项.IncludePaths告诉node-sass或者更确切地说底层库LibSass包含来自该目录/路径的sass文件.

Vue公司

Sass-loader选项

默认情况下,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配置vue-loader.conf.js工作如下:

它使用返回的映射cssLoaders()来构建webpack所期望的加载器.{key:value}然后通过提供key用于test:加载器对象的文件扩展名来使用返回的map().将value被用作加载器对象.这是这样的:

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

key文件扩展名在哪里.在这种情况下,将是sassscss.并且//ld//是装载机你用哪个.这在步骤3中显示'sass'.

希望这能清除一些东西.我花了一段时间,因为我刚开始使用Vue.