SassError: Invalid CSS after "" with Rails 6, Webpacker, and Vue

SassError: Invalid CSS after "" with Rails 6, Webpacker, and Vue

我刚刚用 webpackervue[开始了一个新的 rails-6 项目=56=]。我想在 sass 中使用 vue 组件样式,但是 sass-loader throughs:

Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js) SassError: Invalid CSS after "": expected 1 selector or at-rule, was ".foo"

有人以前看过这个吗?或者,我该如何调试这里出现的问题?

组件foo.vue

<template>...</template>
<script>...</script>
<style lang="sass">
  .foo
    margin: 0
    padding: 0
</style>

删除 sass 代码的初始缩进没有帮助。

版本

  • rails6.1.3.1
  • webpacker 5.2.1
  • 节点 14.16.1

项目设置

rails new --database=postgresql --skip-test foo
rails webpacker:install:vue
yarn add vue-turbolinks
rails webpacker:install:coffee
yarn add coffee-loader@1
yarn add sass-loader@10

package.json

{
  "name": "foo",
  "private": true,
  "dependencies": {
    "@popperjs/core": "^2.9.2",
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "5.2.1",
    "@tabler/core": "tabler/tabler",
    "bootstrap": "^5.0.0-beta3",
    "coffee-loader": "1",
    "coffeescript": "1.12.7",
    "sass-loader": "10",
    "tabler": "^1.0.0-alpha.8",
    "turbolinks": "^5.2.0",
    "vue": "^2.6.12",
    "vue-loader": "^15.9.6",
    "vue-select": "^3.11.2",
    "vue-template-compiler": "^2.6.12",
    "vue-turbolinks": "^2.2.2"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.11.2"
  }
}

我还添加了 vue-selectbootstraptabler。但我认为他们不会干涉。

Webpack 配置config/webpack/environment.js

const { environment } = require('@rails/webpacker')
const coffee =  require('./loaders/coffee')
const { VueLoaderPlugin } = require('vue-loader')
const vue = require('./loaders/vue')

environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin())
environment.loaders.prepend('vue', vue)
environment.loaders.prepend('coffee', coffee)
module.exports = environment

布局application.html.haml

!!!
%html
  %head
    %title Foo
    = csrf_meta_tags
    = csp_meta_tag
    = stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
  %body
    #vue_app
      = yield

packs/application.js

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"

Rails.start()
Turbolinks.start()
ActiveStorage.start()

import 'bootstrap'
import '@tabler/core'

import TurbolinksAdapter from 'vue-turbolinks'
import Vue from 'vue/dist/vue.esm'

Vue.use(TurbolinksAdapter)

document.addEventListener('turbolinks:load', () => {
  const app = new Vue({
    el: '#vue_app',
    data: () => {
      return {}
    },
    components: {}
  })
})

Sass 使用花括号: .foo { 保证金:0 }

您可以尝试在根 HTML 文件中包含 <%= stylesheet_pack_tag 'application', media: 'all' %>

我认为它会起作用。

Sass 对比 SCSS

two syntax variants:

There are two syntaxes available for Sass. The first, known as SCSS (Sassy CSS) and used throughout this reference, is an extension of the syntax of CSS. This means that every valid CSS stylesheet is a valid SCSS file with the same meaning. This syntax is enhanced with the Sass features described below. Files using this syntax have the .scss extension.

The second and older syntax, known as the indented syntax (or sometimes just “Sass”), provides a more concise way of writing CSS. It uses indentation rather than brackets to indicate nesting of selectors, and newlines rather than semicolons to separate properties. Files using this syntax have the .sass extension.

另请参阅:, https://sass-lang.com/documentation/syntax

sass-loader 使用哪种语法?

sass-loader默认根据文件扩展名选择语法:

The indentedSyntax option has true value for the sass extension.

这意味着原始的sass语法(缩进语法)仅在文件扩展名为.sass时使用。在扩展名为 .vue 的 vue 组件中,sass-loader 默认使用较新的“scss”语法。

如何配置 sass-loader 以使用 sass 语法(缩进语法)?

sass-loader documentation有说明如何在webpack配置中指定indentedSyntax: true

// webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              sassOptions: {
                indentedSyntax: true
              },
            },
          },
        ],
      },
    ],
  },
};

然而,webpacker, the webpack configuration is composed automatically. So, one needs to modify the existing configuration object:

// config/webpack/environment.js

const { environment } = require('@rails/webpacker')

// To get an overview, have a look at `environment.loaders`.
console.log(environment.loaders)

const { merge } = require('webpack-merge')
const sassConfig = environment.loaders.find(el => el.key == 'sass')
const sassLoader = sassConfig.value.use.find(el => el.loader == 'sass-loader')

sassLoader.options = merge(sassLoader.options, {
  sassOptions: {
    indentedSyntax: true
  }
})

module.exports = environment

这需要 webpack-mergeyarn add webpack-merge

我相信有更好的方法来做到这一点。请随时添加答案或评论!