我正在尝试制作一个我正在开发的同构 React 应用程序。 known problems with doing this之一是 webpack 加载器允许 import/require
非 JavaScript 资源,例如 CSS 文件。例如
// ExampleComponent.jsx
import Select from 'react-select';
import 'react-select/dist/react-select.css';
如果使用 Express 构建应用程序,则 Node 将进行此导入并失败,因为它无法处理 CSS 文件,它只需要 javascript(并且感谢 babel-register
JSX)。
解决这个问题的方法之一是在构建服务器应用程序时使用 webpack 中的 target: 'node'
选项(其中包括所有公共(public)部分,例如组件,因为它是同构应用程序) )来构建服务器端代码。这应该会生成一个可以由 Node 运行的 server.js
。
注意:我知道还有其他方法可以解决这个特定问题(例如不使用 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 环境中不存在。
$ 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
来自here在样式加载器中。
感觉我已经非常接近完成这项工作了,所以欢迎任何想法。
最佳答案
答案是不要使用style-loader
在你的服务器构建中:它的唯一目的是获取 CSS,将其变成 <style>
元素,并将其插入到 DOM 中。大多数人似乎使用 ExtractTextPlugin收集他们的 CSS 以包含在服务器端。
关于node.js - 使用 webpack 构建 (React) 同构 web 应用程序的服务器部分,包括 CSS 样式加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36020514/