隔离不同布局的样式(webpack,反应)

时间:2016-01-20 16:19:27

标签: reactjs webpack react-router webpack-style-loader

我有两个布局(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:     'use strict';

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 个答案:

答案 0 :(得分:0)

终于让它为我工作了。为组件中的样式添加此项。

   componentWillMount() {
      styles.use();
    }

    componentWillUnmount() {
      styles.unuse();
    }

sass 的webpack配置中,使用以下样式。

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()或使用提供的装饰器。