webpack vue-loader Postcss-modules会导致空$样式对象



在我的应用中,我正在初始化一个vue应用,该应用使用单个文件.vue组件。
我使用webpack捆绑,vue-loader postcss-modules生成范围的类。

但是由于某种原因,我无法访问组件内的生成类($style对象是空的(。我将在下面解释问题,并创建此repo 为例。

我的 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-track-plugin时,它捆绑在 app.css.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,在css-loader选项中设置modules: true,因为它填充了$style对象(请参阅文档(:

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

但是在我们的应用中,我们使用postcss-loader(根据文档(来照顾包括范围在内的所有转换。启用modules: truepostcss-modules冲突并打破类/映射(如预期(。

换句话说,我正在寻找一种使用postcss-modules的省略modules: true选项的方法。

找到了解决方法:手动从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视为一个完整的例子。

最新更新