(React)与webpack同构的webapp的服务器部分,包括CSS的样式加载器

我正在尝试使我正在开发的React应用程序是同构的。 这样做的一个已知的问题是,webpack加载器允许import/require非JavaScript资产,如CSS文件。 例如

 // ExampleComponent.jsx import Select from 'react-select'; import 'react-select/dist/react-select.css'; 

如果使用Express构build应用程序,则节点将获取到此导入,并因为无法处理CSS文件而失败,因此仅期望JavaScript(并且感谢babel-register JSX)。

其中一个解决方法是在构build服务器端应用程序(包括所有通用部分,如组件,因为它是一个同构应用程序)时,使用webpack中的target: 'node'选项来构build服务器端代码。 这应该会导致server.js被构build,然后可以由节点运行。

注:我知道还有其他的方法来解决这个问题(比如不使用import/require来包含任何不是javascript的东西,但是在这个应用程序开发的这个阶段是不实际的。

 // webpack.config.js var webpack = require('webpack'); var path = require('path'); module.exports = [ // Client build { entry: { 'bundle.min': [ 'bootstrap-webpack!./bootstrap.config.js', 'babel-polyfill', './client/index.jsx' ], 'bundle': [ 'bootstrap-webpack!./bootstrap.config.js', 'babel-polyfill', './client/index.jsx' ] }, output: { path: './dist', filename: '[name].js' }, plugins: [ new webpack.optimize.UglifyJsPlugin({ include: /\.min\.js$/, minimize: true }) ], module: { loaders: [ { test: /\.jsx$/, loader: 'babel-loader', exclude: /node_modules/, query: { plugins: ['transform-runtime'], presets: ['react', 'es2015', 'stage-0'] } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/, query: { plugins: ['transform-runtime'], presets: ['es2015', 'stage-0'] } }, { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.png$/, loader: "url-loader?limit=100000" }, // Bootstrap { test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff'}, { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' }, { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' }, { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml' } ] }, resolve: { extensions: ['', '.js', '.jsx', '.json'] } }, // Server build { entry: './server/server.jsx', target: 'node', node: { console: false, global: false, process: false, Buffer: false, __filename: false, __dirname: false, }, output: { path: './dist', filename: 'server.js', }, module: { loaders: [ { test: /\.jsx$/, loader: 'babel-loader', exclude: /node_modules/, query: { plugins: ['transform-runtime'], presets: ['react', 'es2015', 'stage-0'] } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/, query: { plugins: ['transform-runtime'], presets: ['es2015', 'stage-0'] } }, { test: /\.json$/, loader: 'json-loader' }, { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.png$/, loader: "url-loader?limit=100000" }, // Bootstrap { test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff'}, { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream' }, { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file' }, { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml' } ] }, resolve: { extensions: ['', '.js', '.jsx', '.json'] } } ]; 

问题在于,样式加载器使用了在节点环境中显然不存在的window

 $ node dist/server.js /Users/dpwrussell/Checkout/ExampleApp/dist/server.js:25925 return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase()); ^ ReferenceError: window is not defined 

从这里风格加载器。

感觉就像我非常接近做这个工作,所以任何想法都会受到欢迎。

答案并不是在你的服务器构build中使用style-loader :它的唯一目的是把CSS变成一个<style>元素,并把它插入到DOM中。 大多数人似乎使用ExtractTextPlugin来收集他们的CSS包含在服务器端。