Создание серверной части (React) изоморфного веб-приложения с веб-пакетом, включая style-loader для CSS
Я пытаюсь сделать приложение React, которое я разрабатываю, изоморфным. Один изизвестные проблемы с этим это то, что веб-загрузчики позволяютimport/require
не-JavaScript-активов, таких как файлы CSS. например
// ExampleComponent.jsx
import Select from 'react-select';
import 'react-select/dist/react-select.css';
Если приложение создается с помощью Express, то узел получит этот импорт и потерпит неудачу, поскольку он не может обработать файл CSS, он ожидает только JavaScript (и благодаряbabel-register
JSX).
Одним из способов обойти это является использованиеtarget: 'node'
опция в веб-пакете при создании серверного приложения (которое включает в себя все общие части, такие как компоненты, поскольку оно является изоморфным приложением) для создания кода на стороне сервера. Это должно привести кserver.js
строится, который может быть запущен узлом.
Примечание: я знаю, что есть другие способы решения этой конкретной проблемы (например, не использоватьimport/require
включить в это приложение все, что не является jav, ascript, но не практичным на данном этапе разработки.
// 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
ОтВот в стиле лоадер.
Такое ощущение, что я очень близок к созданию этой работы, поэтому любые мысли будут приветствоваться.