Я пытаюсь сделать приложение React, которое я разрабатываю изоморфно. Один из known problems with doing this заключается в том, что загрузчики веб-пакетов допускают import/require
активов, отличных от javascript, таких как файлы CSS. напримерСоздание серверной части (React) изоморфного webapp с webpack, включая загрузчик стиля для CSS
// ExampleComponent.jsx
import Select from 'react-select';
import 'react-select/dist/react-select.css';
Если создание приложения с экспресс затем узел получит в этом импорт и не потому, что он не может обработать файл CSS, он ожидает Javascript только (и благодаря babel-register
JSX).
Один из способов обойти это - использовать опцию target: 'node'
в webpack при создании серверного приложения (которое включает в себя все общие части, такие как компоненты, поскольку это изоморфное приложение) для создания кода на стороне сервера. Это должно привести к созданию 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 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 в стиле погрузчиком.
Похоже, что я очень близок к тому, чтобы делать эту работу, поэтому любые мысли будут приветствоваться.