2016-08-14 9 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; 
(웹팩-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 스타일 로더] (https://github.com/kriasoft/isomorphic-style-loader)를 사용하여 서버 측 렌더링 중에 중요한 경로 CSS를 렌더링합니다. – HiDeo

+0

@HiDeo 반응 라우터를 사용합니까? 어쩌면 나에게 데모를 보여줄 수 있니? 이 로더를 시도했지만 서버 측 코드를 처리하는 방법을 모릅니다. –

+0

네, 예/예를 들어 [Isom Isomorphic Starterkit] (https://github.com/RickWong/react-isomorphic-starterkit)은'isomorphic-style-loader','react-router'와 함께 사용합니다. 서버 측 반응 렌더링. – HiDeo

답변

1

그런 경우에는 webpack을 사용하여 클라이언트와 서버 측 모두에 대한 UI 코드를 컴파일하는 것이 좋습니다. webpack config에 target: "node"을 설정하면 노드 환경에서 실행할 수있는 번들을 생성 할 수 있습니다. http://jlongster.com/Backend-Apps-with-Webpack--Part-I 특히 externalsnode_modules을 제외하는 방법 : 문서 웹팩와 서버 측 코드를 컴파일하는 데 도움이 될 그건

+0

으로 노드 서버 코드를 번들링 할 준비를하십시오. 이 작업을 위해 데모를 보여줄 수 있습니까? –

0

.

'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, 
    ], 

}; 

또 다른 해결책 (웹팩 무료) babel-plugin-css-modules-transform 를 사용할 수 :

매우 맨손으로 설정처럼 보일 수 있습니다.

관련 문제