Webpack和sass-loader文件的导入顺序问题

3

我正在调查React,并开始尝试使用sass-loader处理CSS / SCSS模块。我已经完成了大部分设置,但我遇到了一个问题,我不太确定该如何解决,下面是一个场景:

ComponentA.jsx

import React from 'react';
import ComponentB from './app/components/ComponentB.jsx';

// Importing Core CSS module for component A
require("./ComponentA.scss");

export default class ComponentA extends React.Component{

  constructor(){
    ...
  }

  render(){
    return (
      <div>
          <ComponentB />
      </div>
    );
  }
}

ComponentB.jsx

import React from 'react';

// Importing CSS module for component B with some overriding content for component A
require("./ComponentB.scss");

export default class ComponentB extends React.Component{

  constructor(){
      ...
  }

  render(){
    return (
      ...
    );
  }
}

webpack.config.js

var path = require("path");
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  devServer: {
    contentBase: path.join(__dirname, "../build")
  },
  entry: path.join(__dirname,"../app/ComponentA.jsx"),
  module:{
    loaders: [
      {
        test: /\.jsx?$/,
        loader: 'babel', 
        query: {
          presets: ['react', 'es2015']
        }
      },
      { 
        test: /\.(scss|css)$/, 
        loader: ExtractTextPlugin.extract(['css','sass'])
      },
      ...
    ]
  },
  output: {
    path: path.join(__dirname, "..", "build"),
    filename: "bundle.js",
    publicPath: "/"
  },
  plugins: [
    new ExtractTextPlugin(
      "style.css", 
      { allChunks: true }
    )
  ]
};

从这个设置中,Webpack按预期工作并创建了新文件style.css(当然是虚拟的,因为我在开发中),但是... SCSS内容文件的渲染顺序不是我想象中的那样。
结果的style.css内容排列如下:
  • ComponentB.scss内容
  • ComponentA.scss内容
而不是:
  • ComponentA.scss内容
  • ComponentB.scss内容
这是一个问题,因为为了覆盖Component A基础CSS,我需要webpack和sass-loader按层次顺序合并文件。
因此,问题是: 如何配置sass-loader以按树形结构加载模块? 甚至更简单的是... 有更好的方法吗?
1个回答

1
你需要将React中的组件视为自包含实体,即使涉及样式表也是如此。这不仅涉及JavaScript和JSX(或一般标记),还包括CSS(或SCSS)。
因此,通常首选方法是使用本地CSS,以及最少量的全局样式。我建议您在您的情况下也这样做:将ComponentA和ComponentB中的某些样式移动到全局范围内(可以将其视为关键CSS),并为每个组件添加覆盖它们的本地样式。
使样式本地化的方法是添加“:local”前缀,可能包含在一个容器中(即ComponentA)中,如下所示:
:local(.ComponentA) { 
  background: red;

  & > img{
    width: 100%;
  }
}

值得一提的是,这将把您的SCSS文件转换为内联样式。在许多情况下,这可以提高感知性能和首次绘制速度。

在这里阅读更多相关信息


1
谢谢您的回答!我已经阅读了您提供的信息中关于local-css的内容。它似乎非常适合我所提供的场景,而且功能也很有趣。 - E. Salazar
现在,试图获得更广泛的视角......我理解创建ExtractTextPlugin的原因是为了分离和压缩组件使用的CSS数据。在这种情况下,这不是打破了“要求”CSS页面的目的吗?或者简单地说,有哪些情况下内联CSS会更好? - E. Salazar
你仍然可以使用require并在所需本地化的类中添加:local,以便在编译时进行内联。但是你不必担心这个问题。这样做的好处当然是CSS文件不会在所有页面上加载,而只会在需要它的页面上加载。如果你想了解更多信息,请点击这里 - Dan Mindru
顺便说一下,如果您觉得这个答案有帮助,请接受并点赞。谢谢! :) - Dan Mindru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接