2016-08-14 14 views
0

私はreact、react-router、express、webpackを使って同形アプリを構築しています。今、私はCSSをインポートするためにCSSモジュールを使用したいと思います。React isomorphic appのwebpackでCSSモジュールを使用するには?

index.jsximport './index.css'を使用していますが、クライアントで問題なく動作しますが、サーバーレンダリングでは機能しません。エラーはError: Cannot find module './index.css'です。

コンポーネント/ index.jsx

import React, {Component, PropTypes} from 'react'; 
import style from './index.css'; 

class App extends Component { 
    constructor(props, context) { 
     super(props, context); 
    } 

    render() { 
     return (
      <div id="login"> 
       // ... 
      </div> 
     ); 
    } 
}; 

export default App; 

サーバ/ルータ/ index.js

webpack.config.dev.js

import url from 'url'; 
import express from 'express'; 
import swig from 'swig'; 
import React from 'react'; 
import {renderToString} from 'react-dom/server'; 
import {match, RouterContext} from 'react-router'; 

import routes from '../../client/routes/routes'; 
import DataWrapper from '../../client/container/DataWrapper'; 
import data from '../module/data'; 

const router = express.Router(); 

router.get('*', async(req, res) => { 
    match({ 
    routes, 
    location: req.url 
    }, async(error, redirectLocation, props) => { 
    if (error) { 
     res.status(500).send(error.message); 
    } else if (redirectLocation) { 
     res.status(302).redirect(redirectLocation.pathname + redirectLocation.search); 
    } else if (props) { 
     let content = renderToString(
     <DataWrapper data={data}><RouterContext {...props}/></DataWrapper> 
    ); 
     let html = swig.renderFile('views/index.html', { 
     content, 
     env: process.env.NODE_ENV 
     }); 
     res.status(200).send(html); 
    } else { 
     res.status(404).send('Not found'); 
    } 
    }); 
}); 

export default router; 
(WebPACKの-DEV-サーバ用)

var webpack = require('webpack'); 
var config = require('./config'); 

module.exports = { 
    devtool: 'inline-source-map', 
    entry: [ 
     'webpack-dev-server/client?http://localhost:' + config.webpackPort, 
     'webpack/hot/only-dev-server', 
     './src/client/entry', 
    ], 
    output: { 
     path: __dirname + '/public/js', 
     filename: 'app.js', 
     publicPath: 'http://localhost:' + config.webpackPort + '/public/js', 
    }, 
    plugins: [ 
     new webpack.HotModuleReplacementPlugin(), 
     new webpack.NoErrorsPlugin(), 
     new webpack.DefinePlugin({ 
      "process.env": { 
       NODE_ENV: JSON.stringify('development') 
      } 
     }) 
    ], 
    resolve: { 
     extensions: ['', '.js', '.jsx', '.css'] 
    }, 
    module: { 
     loaders: [{ 
      test: /\.jsx?$/, 
      loader: 'react-hot', 
      exclude: /node_modules/ 
     }, { 
      test: /\.jsx?$/, 
      loader: 'babel-loader', 
      exclude: /node_modules/ 
     }, { 
      test: /\.css$/, 
      loader: 'style-loader!css-loader?modules', 
      exclude: /node_modules/ 
     }, { 
      test: /\.(png|woff|woff2|svg|ttf|eot)$/, 
      loader: 'url-loader', 
      exclude: /node_modules/ 
     }] 
    } 
} 
+1

Webpackの場合、[Isomorphic CSS style loader](https://github.com/kriasoft/isomorphic-style-loader)を使用して、サーバーサイドレンダリング中にクリティカルパスCSSをレンダリングしています。 – HiDeo

+0

@HiDeo反応ルータを使用していますか?多分私にデモを見せることができますか?私はこのローダーを試しましたが、私はサーバー側のコードをどのように処理するのか分かりません。 –

+0

はい、多くのサンプル/スターターがあります。例えば、[Isact Isomorphic Starterkit](https://github.com/RickWong/react-isomorphic-starterkit)では 'isomorphic-style-loader'、' react-router'を使用しますサーバー側リアクションレンダリング。 – HiDeo

答えて

1

この場合、webpackを使用してクライアント側とサーバー側の両方のUIコードをコンパイルすることをお勧めします。 webpack configにtarget: "node"を設定するだけで、Node環境で実行できるバンドルを作成できます。記事はWebPACKのと、サーバー側のコードをコンパイルするために役立つかもしれない

+0

でノードサーバーコードをバンドルする準備ができました。これを行うためのデモをいくつか見せてもらえますか? –

0

http://jlongster.com/Backend-Apps-with-Webpack--Part-I 特にexternalsキーでnode_modulesを除外する方法について。

非常に裸の設定は次のようになります。

'use strict'; 

const path = require('path'); 
const fs = require('fs'); 
const ExtractTextPlugin = require('extract-text-webpack-plugin'); 

const rootDir = path.resolve(__dirname, '..'); 
const distDir = path.join(rootDir, 'dist'); 
const srcDir = path.join(rootDir, 'src'); 

const localStyles = new ExtractTextPlugin('local.css', { allChunks: true }); 

const nodeModules = fs.readdirSync('node_modules') 
    .filter(dir => !dir.startsWith('.')) 
    .reduce((acc, prop) => { 
    acc[prop] = 'commonjs ' + prop; 
    return acc; 
    }, {}); 

const loaders = [ 
    { 
    test: /\.(js|jsx)$/, 
    include: srcDir, 
    exclude: /node_modules/, 
    loader: 'babel', 
    query: { 
     cacheDirectory: true, 
    }, 
    }, 
    { 
    test: /\.css$/, 
    include: srcDir, 
    loader: localStyles.extract(
     'style', 
     'css?modules&localIdentName=[name]-[local]_[hash:base64:5]' 
    ), 
    }, 
    { 
    test: /\.json$/, 
    loader: 'json', 
    }, 
]; 


module.exports = { 

    target: 'node', 

    entry: { 
    server: ['server/index'], 
    }, 

    output: { 
    path: distDir, 
    filename: '[name].bundle.js', 
    }, 

    externals: nodeModules, 

    module: { 
    loaders, 
    }, 

    plugins: [ 
    localStyles, 
    ], 

}; 

別の解決策(WebPACKの自由は)babel-plugin-css-modules-transform を使用することができます。

関連する問題