【问题标题】:Isolate styles in different layouts (webpack, react)隔离不同布局中的样式(webpack、react)
【发布时间】:2016-04-26 14:24:33
【问题描述】:

我有两种布局(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 的样式(import './layout.sass'; inside 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;

那么如何将一种布局的样式与另一种布局的样式隔离开来呢?

【问题讨论】:

  • 能否分享一下 webpack.config 文件。不看你是如何捆绑样式的。很难知道正确的原因。
  • 添加了 webpack 配置
  • 你可以尝试在常见的 webpack 配置中的 css 之后和 postcss 之前添加'localIdentName=[name]-[local]' 看看会发生什么。
  • 出现错误:./src/javascripts/global_styles.js 中的错误模块未找到:错误:无法解析 /storage/development/netology_fronts/ 中的模块 'localIdentName=[name]-[local]' src/javascripts @ ./src/javascripts/global_styles.js 7:0-42 ./src/javascripts/global_styles.js 中的错误 找不到模块:错误:无法解析模块“localIdentName=[name]-[local]” /storage/development/netology_fronts/src/javascripts @ ./src/javascripts/global_styles.js 9:0-38 ./src/components/layouts/LayoutWithShortHeader/LayoutWithShortHeader.jsx 中的错误 ...
  • 对不起。将['style', 'css', 'postcss', 'sass?indentedSyntax'] 更改为'[style', 'css?localIdentName=-[name][local]', 'postcss', 'sass?indentedSyntax]'

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


【解决方案1】:

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

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

【讨论】:

  • 没有错误和样式刚刚从布局中消失。我在布局中包含这样的样式:从'./layout_with_header.sass'导入样式;。这是我的带有模块版本的 package.json,可能会有所帮助pastebin.com/ypurgbYt
  • 现在我收到一个奇怪的错误:pastebin.com/Dg6ZzMzS。文件中的样式:pastebin.com/DQef7Nhp。附言我正在尝试不使用装饰器。
  • 你能把文件寄给我吗?我会尝试修复并将它们送回。你能发送 LayoutWithShortHeaderTestLayout、他们的 sass 文件和 webpack.config。如果需要,只需将清理后的版本发送给我即可。它与样式加载器有关。将为您节省大量时间。
猜你喜欢
  • 2019-06-09
  • 2020-10-18
  • 1970-01-01
  • 2021-09-04
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
  • 1970-01-01
相关资源
最近更新 更多