Webpack + vue-loader + postcss-modules приводит к пустому объекту $ style - PullRequest
0 голосов
/ 27 июня 2019

В моем приложении я инициализирую приложение Vue, которое использует отдельные файлы .vue.
Я использую Webpack для объединения и vue-loader + postcss-modules для генерации классов с областью действия.

Но по какой-то причине я не могу получить доступ к сгенерированным классам внутри моих компонентов ($style объект пуст).Я объясню проблему ниже и создаю этот репо в качестве примера.

Мой hello.vue компонент выглядит следующим образом:

<template>
  <div :class="$style.hello">
    Hello World!
  </div>
</template>

<script>
export default {
  name: "hello",
  created() {
    console.log(this.$style); // <- empty object :(
  }
};
</script>

<style module>
.hello {
  background: lime;
}
</style>

hello.vue.json генерируется должным образом (сопоставление модулей CSS):

{"hello":"_hello_23p9g_17"}

Стили с областями видимости добавляются в заголовок документа и при использовании mini-css-extract-plugin он входит в app.css :

._hello_23p9g_17 {
  background: lime;
}

Кто-нибудь знает, в чем проблема и, возможно, как это исправить?

Ниже моих файлов конфигурации.

webpack.config.js (обрезано для удобства чтения)

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const VueLoaderPlugin = require("vue-loader/lib/plugin");

module.exports = {
  entry: {
    app: "./src/index.js"
  },
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "build")
  },
  resolve: {
    extensions: [".js", ".vue", ".json", ".css"],
    alias: {
      vue: "vue/dist/vue.esm.js"
    }
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.vue$/,
        loader: "vue-loader"
      },
      {
        test: /\.css$/,
        use: [
          "vue-style-loader",
          // MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              // modules: true,
              importLoaders: 1
            }
          },
          "postcss-loader"
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: "[name].css"
    }),
    new VueLoaderPlugin()
  ]
};

postcss.config.js

module.exports = {
  ident: "postcss",
  plugins: {
    "postcss-preset-env": { stage: 0 },
    "postcss-modules": {}
  }
};

РЕДАКТИРОВАТЬ:

FYI, установка modules: true в параметрах css-loader работает в том смысле, что она заполняет объект $style(см. docs ):

{
  test: /\.css$/,
  use: [
    MiniCssExtractPlugin.loader,
    {
      loader: "css-loader",
      options: {
        modules: true
      }
    }
  ]
}

Но в нашем приложении мы используем postcss-loader (согласно docs ), который заботится обо всех преобразованиях, включая область видимости.Включение modules: true и postcss-modules конфликтует и нарушает классы / отображение (как и ожидалось).

Другими словами, я ищу способ пропустить параметр modules: true и включитьмодули CSS, использующие postcss-modules вместо.

1 Ответ

0 голосов
/ 28 июня 2019

Найден обходной путь: вручную импортируйте стили из файла JSON.
Если кто-нибудь знает лучший способ, сообщите мне:)

hello.vue.json

{"hello":"_hello_fgtjb_30"}

hello.vue

<template>
  <div :class="style.hello">
    Hello World!
  </div>
</template>

<script>
import style from "./hello.vue.json";

export default {
  name: "hello",
  beforeCreate() {
    this.style = style;
  },
  created() {
    console.log(this.style);
  }
};
</script>

<style module>
.hello {
  background: lime;
}
</style>

Это работает только при использовании postcss-modules (загружается из конфигурации с помощью postcss-loader в моем случае) вместо использования modules: true:

{
  test: /\.css$/,
  use: [
    MiniCssExtractPlugin.loader,
    {
      loader: "css-loader",
      options: {
        importLoaders: 1
      }
    },
    "postcss-loader"
  ]
};

См. этот PR в качестве полного примера.

...