Изолировать стили в разных макетах (webpack, реагировать)

У меня есть два макета (LayoutWithShortHeader, TestLayout) и такие маршруты:

export default (
  <Router history={createBrowserHistory()}>

    <Route path="/" component={ LayoutWithShortHeader }>
      <IndexRoute component={ Index }/>
    </Route>

    <Route path="/" component={ TestLayout }>
      <Route path="ddd" component={ TestPage }/>
      <Route path="not-found" component={ NotFound }/>
    </Route>

    <Redirect from="*" to="/not-found"/>

  </Router>
);

Когда я открываю / DDD страница состоит из TestLayout с TestPage внутри. К сожалению, у него есть стили из LayoutWithShortHeader (импорт "./layout.sass"; внутри LayoutWithShortHeader), и я не знаю почему.

TestLayout.jsx:

'use strict';

import React from 'react';

const TestLayout = React.createClass({

  propTypes: {
    children: React.PropTypes.object
  },

  getInitialState() {
    return {};
  },

  render() {
    return (
      <div>
        { this.props.children }
      </div>
    );
  }
});

export default TestLayout;

Конфигурации Webpack:

webpack.common.config.js:

'use strict';

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Sprites = require('sprite-webpack-plugin');
const autoprefixer = require('autoprefixer');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.(js|jsx)$/,
        include: path.join(__dirname, 'src'),
        loaders: ['react-hot', 'babel', 'eslint']
      },
      {
        test: /\.css$/,
        loaders: ['style', 'css']
      },
      {
        test: /\.sass$/,
        loaders: ['style', 'css', 'postcss', 'sass?indentedSyntax']
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loaders: [
          'file?hash=sha512&digest=hex&name=[hash].[ext]',
          'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
        ]
      },
      {
        test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
        loader: 'file-loader'
      },
      {
        test: require.resolve('jquery'),
        loader: 'expose?jQuery'
      },
      {
        test: require.resolve('jquery'),
        loader: 'expose?$'
      }
    ]
  },
  postcss: function() {
    return [autoprefixer({ browsers: ['last 3 versions'] })];
  },
  devtool: 'source-map',
  resolve: {
    extensions: ['', '.js', '.jsx', '.json']
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Netology',
      template: './src/index.html',
      scriptFilename: 'application.js'
    }),
    new Sprites({
      'source': __dirname + '/src/images/for_sprites/',
      'imgPath': __dirname + '/src/images/',
      'cssPath': __dirname + '/src/stylesheets/',
      'multiFolders': true
    })
  ],
  resolve: {
    root: path.resolve(__dirname),
    alias: {
      js: 'src/javascripts',
      fonts: 'src/fonts',
      components: 'src/components'
    },
    extensions: ['', '.js', '.jsx', '.sass']
  }
};

webpack.config.js: "использовать строгое";

const path = require('path');
const webpack = require('webpack');
const friendlyFormatter = require('eslint-friendly-formatter');
let config = require('./webpack.common.config');

config.entry = [
  'webpack-dev-server/client?http://0.0.0.0:3000',
  'webpack/hot/only-dev-server',
  './src/javascripts/main.js'
];

config.output = {
  path: path.join(__dirname, 'build'),
  filename: 'application.js',
  publicPath: '/'
};

config.eslint = {
  formatter: friendlyFormatter
};

config.plugins.push(
  new webpack.NoErrorsPlugin(),
  new webpack.HotModuleReplacementPlugin()
);

module.exports = config;

Так как же выделить стили одного макета из стилей другого?

1 ответ

Наконец-то все заработало. Добавьте это для стилей в вашем компоненте.

   componentWillMount() {
      styles.use();
    }

    componentWillUnmount() {
      styles.unuse();
    }

В вашем веб-пакете для настройки sass используйте следующие стили.

loaders: ['style/useable', 'css', 'postcss', 'sass?indentedSyntax']

Лучшим решением будет создать декоратор, чтобы легко применить его ко всем компонентам.

import React, { Component } from 'react';

function LazyLoadStyles(styles) {
   return (BaseComponent) => class StyledComponent extends Component {

     componentWillMount() {
       styles.use();
      }

     componentWillUnmount() {
       styles.unuse();
     }

     render() {
       return <BaseComponent {...this.props} />;
     }
  };
}

export default withStyles;

Тогда вы можете использовать его в своем компоненте, как

import lazyLoadStyle from './LazyLoadStyles';
import st as './Page.sass'

@lazyLoadStyle(st)
class Mycomponent extends React.Component {

....
}

Изменить: Переименуйте конфликтующие файлы.sass в.useable.sass и измените загрузчик следующим образом:

 {
    test: /\.sass$/,
    loaders: ['style', 'css', 'postcss', 'sass?indentedSyntax']
  },
  {
     test: /\.useable.sass$/,
     loaders: ['style/useable', 'css', 'postcss', 'sass?indentedSyntax']
  },

Тогда во всех ваших модулях есть конфликтующие CSS. Вы должны либо использовать style.use() и unuse(), либо использовать предоставленный декоратор.

Другие вопросы по тегам