Node.js - 在 Server.js 上执行 Node 命令(Express + React + Webpack)
Posted
技术标签:
【中文标题】Node.js - 在 Server.js 上执行 Node 命令(Express + React + Webpack)【英文标题】:Node.js - Executing Node command on Server.js (Express + React + Webpack) 【发布时间】:2017-03-22 06:52:40 【问题描述】:首先,我对这个 Node.js 世界很陌生,所以请多多包涵我的菜鸟。我目前正在着手处理 Node.js + Express + React + Webpack 堆栈。我设法在开发中运行了一些代码,但无法在生产中运行。当我尝试在终端上运行 node server.js 时出现以下错误。
Nicholass-MacBook-Pro:sevva-backend nicholaslie$ node server.js
/Users/nicholaslie/Documents/Sevva/sevva-backend/server.js:7
import React from 'react'
^^^^^^
SyntaxError: Unexpected token import
at Object.exports.runInThisContext (vm.js:76:16)
at Module._compile (module.js:545:28)
at Object.Module._extensions..js (module.js:582:10)
at Module.load (module.js:490:32)
at tryModuleLoad (module.js:449:12)
at Function.Module._load (module.js:441:3)
at Module.runMain (module.js:607:10)
at run (bootstrap_node.js:382:7)
at startup (bootstrap_node.js:137:9)
at bootstrap_node.js:497:3
但是,在我的本地机器(开发环境)中,我可以使用 npm start 很好地运行它。
Nicholass-MacBook-Pro:sevva-backend nicholaslie$ npm start
> sevva-backend@0.0.1 start /Users/nicholaslie/Documents/Sevva/sevva-backend
> if-env NODE_ENV=production && npm run start:prod || npm run start:dev
> sevva-backend@0.0.1 start:dev /Users/nicholaslie/Documents/Sevva/sevva-backend
> webpack-dev-server --progress --profile --colors --inline --content-base public --history-api-fallback
70% 1/1 build modules http://127.0.0.1:3000/
webpack result is served from /
content is served from /Users/nicholaslie/Documents/Sevva/sevva-backend/public
404s will fallback to /index.html
3076ms build modules
8ms seal
6ms optimize
10ms hashing
30ms create chunk assets
23ms additional chunk assets
57ms optimize chunk assets
77ms optimize assets
20ms emit
当我转到http://localhost:3000 时,我的页面加载如下。
package.json:
"name": "sevva-backend",
"version": "0.0.1",
"private": true,
"main": "server.js",
"scripts":
"build": "if-env NODE_ENV=production build:prod || build:dev",
"build:prod": "babel -d ./src ./public/bundle.js -s && webpack --config webpack.production.config.js",
"build:dev": "webpack",
"lint": "eslint src",
"start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
"start:dev": "webpack-dev-server --progress --profile --colors --inline --content-base public --history-api-fallback",
"start:prod": "webpack --config webpack.production.config.js && node server.js",
"test": "NODE_ENV=test mocha --recursive test",
"test:coverage": "nyc npm test",
"test:unit": "mocha --recursive test/middleware test/models test/routes",
"test:integration": "mocha --recursive test/integration"
,
"dependencies":
"babel": "^6.5.2",
"babel-cli": "^6.18.0",
"babel-core": "^6.18.2",
"babel-eslint": "^7.1.0",
"babel-loader": "^6.2.7",
"babel-plugin-css-modules-transform": "^1.1.0",
"babel-plugin-transform-class-properties": "^6.18.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-es2015-modules-commonjs": "^6.18.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"babel-register": "^6.18.0",
"babel-runtime": "^6.18.0",
"body-parser": "^1.13.3",
"compression": "^1.6.2",
"cookie-parser": "^1.3.3",
"css-loader": "^0.25.0",
"eslint": "^3.9.1",
"express": "^4.14.0",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"firebase": "^3.5.3",
"glob": "^6.0.4",
"html-webpack-plugin": "^2.24.1",
"if-env": "^1.0.0",
"ignore-styles": "^5.0.1",
"jade": "^1.11.0",
"method-override": "^2.3.0",
"morgan": "^1.6.1",
"node-sass": "^3.11.2",
"path": "^0.12.7",
"postcss-loader": "^1.1.0",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-hot-loader": "^3.0.0-beta.6",
"react-router": "^3.0.0",
"react-tools": "^0.13.3",
"react-transform": "0.0.3",
"sass-loader": "^4.0.2",
"serve-favicon": "^2.3.0",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"webpack": "^1.13.3",
"webpack-cleanup-plugin": "^0.4.1",
"webpack-dev-middleware": "^1.8.4",
"webpack-dev-server": "^1.16.2",
"webpack-hot-middleware": "^2.13.1"
,
"devDependencies":
"babel-cli": "^6.18.0",
"babel-eslint": "^7.1.0",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"chai": "^3.5.0",
"debug": "^2.2.0",
"eslint": "^3.9.1",
"eslint-plugin-react": "^6.6.0",
"mocha": "^3.0.2",
"nyc": "^8.1.0",
"request": "^2.60.0",
"supertest": "^2.0.0",
"time-grunt": "^1.2.1"
,
"engines":
"node": "6.6.0"
请注意上面的许多不必要的依赖项。我很好奇为什么 webpack-dev-server 可以完美运行,但不能与 node server.js 一起使用,如上面的文件所示。
现在,我一直在摸索好几个小时试图弄明白这个问题。首先,我非常清楚 ES6 import 语句似乎不适用于 node 命令。
所以,我所做的是尝试使用 babel-node 代替。但是,我也无法让它按预期工作,它返回以下错误。
Nicholass-MacBook-Pro:sevva-backend nicholaslie$ babel-node server.js
/Users/nicholaslie/Documents/Sevva/sevva-backend/node_modules/bootstrap/dist/css/bootstrap.min.css:6
*//*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */htmlfont-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%bodymargin:0article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summarydisplay:blockaudio,canvas,progress,videodisplay:inline-blockaudio:not([controls])display:none;height:0progressvertical-align:baseline[hidden],templatedisplay:noneabackground-color:transparent;-webkit-text-decoration-skip:objectsa:active,a:hoveroutline-width:0abbr[title]border-bottom:none;text-decoration:underline;text-decoration:underline dottedb,strongfont-weight:inheritb,strongfont-weight:bolderdfnfont-style:italich1font-size:2em;margin:.67em 0markbackground-color:#ff0;color:#000smallfont-size:80%sub,supfont-size:75%;line-height:0;position:relative;vertical-align:baselinesubbottom:-.25emsuptop:-.5emim
SyntaxError: Unexpected token
at Object.exports.runInThisContext (vm.js:76:16)
at Module._compile (module.js:545:28)
at Module._extensions..js (module.js:582:10)
at Object.require.extensions.(anonymous function) [as .js] (/Users/nicholaslie/.nvm/versions/node/v7.0.0/lib/node_modules/babel-cli/node_modules/babel-register/lib/node.js:152:7)
at Module.load (module.js:490:32)
at tryModuleLoad (module.js:449:12)
at Function.Module._load (module.js:441:3)
at Module.require (module.js:500:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/Users/nicholaslie/Documents/Sevva/sevva-backend/src/app.jsx:1:1)
不知何故,babel-node 也无法按预期工作,因为它在转换 CSS 文件时失败。我的 app.jsx 文件如下:
import 'bootstrap/dist/css/bootstrap.min.css'
import styles from './stylesheets/index.scss'
import navlinkStyles from './stylesheets/components/_navlink.scss'
import React from 'react'
import IndexLink from 'react-router'
import NavLink from './components/NavLink'
import Home from './components/Home'
export default class App extends React.Component
render()
return (
<div>
this.props.children || <Home />
<h1>It Works!</h1>
<p>This React project just works including <span className=styles.blueBg>module</span> local styles.</p>
<p>Global bootstrap css import works too as you can see on the following button.</p>
<p><a className="btn btn-primary btn-lg">Enjoy!</a></p>
<ul role="nav">
<li><IndexLink to="/" activeClassName=navlinkStyles.navlinkActive>Home</IndexLink></li>
<li><NavLink to="/about">About</NavLink></li>
<li><NavLink to="/repos">Repos</NavLink></li>
</ul>
/* add this */
this.props.children
</div>
)
附带说明,我知道 babel-node 不应该用于生产。正如docs中所说:
不适用于生产用途 您不应该在生产中使用 babel-node。这是不必要的 重,由于缓存存储在内存中,内存使用率很高。 您还将始终遇到启动性能损失,因为 整个应用程序需要即时编译。
我的 webpack.config.js 文件:
"use strict";
var webpack = require('webpack');
var path = require('path');
var loaders = require('./webpack.loaders');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const HOST = process.env.HOST || "127.0.0.1";
const PORT = process.env.PORT || "3000";
module.exports =
entry: [
'react-hot-loader/patch',
'./src/index.jsx' // your app's entry point
],
externals: React: 'react',
devtool: process.env.WEBPACK_DEVTOOL || 'cheap-module-source-map',
output:
path: 'public',
filename: 'bundle.js',
publicPath: '/'
,
resolve:
extensions: ['', '.js', '.jsx']
,
module:
loaders: [
// global css
test: /\.css$/,
exclude: /[\/\\]src[\/\\]/,
loaders: [
'style?sourceMap',
'css'
]
,
// local scss modules
test: /\.scss$/,
exclude: /[\/\\](node_modules|bower_components|public)[\/\\]/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'postcss',
'sass'
]
,
// local css modules
test: /\.css$/,
exclude: /[\/\\](node_modules|bower_components|public)[\/\\]/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]'
]
,
//JS/JSX files
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel?presets[]=es2015,presets[]=stage-0,presets[]=react,plugins[]=transform-runtime']
]
,
sassLoader:
includePaths: [path.resolve(__dirname, "./some-folder")]
,
devServer:
contentBase: "./public",
// do not print bundle build stats
noInfo: true,
// enable HMR
hot: true,
// embed the webpack-dev-server runtime into the bundle
inline: true,
// serve index.html in place of 404 responses to allow HTML5 history
historyApiFallback: true,
port: PORT,
host: HOST
,
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : [
new webpack.NoErrorsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin(
template: './src/index.html'
),
]
;
我的 webpack.production.config.js 文件:
var fs = require('fs')
var webpack = require('webpack');
var path = require('path');
var loaders = require('./webpack.loaders');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
module.exports =
entry: [
'./src/index.jsx'
],
// keep node_module paths out of the bundle
externals: fs.readdirSync(path.resolve(__dirname, 'node_modules')).concat([
'react-dom/server', 'react/addons',
]).reduce(function (ext, mod)
ext[mod] = 'commonjs ' + mod
return ext
, React: 'react' ),
output:
path: path.join(__dirname, 'public'),
filename: 'bundle.js'
,
resolve:
extensions: ['', '.js', '.jsx']
,
module:
loaders: [
//local css modules
test: /[\/\\]src[\/\\].*\.css/,
exclude: /(node_modules|bower_components|public)/,
loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]')
,
//local scss modules
test: /[\/\\]src[\/\\].*\.scss/,
exclude: /(node_modules|bower_components|public)/,
loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass')
,
//global css files
test: /[\/\\](node_modules|global)[\/\\].*\.css$/,
loader: ExtractTextPlugin.extract('style', 'css')
,
//JS/JSX files
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack', 'babel?presets[]=es2015,presets[]=stage-0,presets[]=react,plugins[]=transform-runtime']
]
,
node:
__filename: true,
__dirname: true
,
plugins: [
new WebpackCleanupPlugin(),
new webpack.DefinePlugin(
'process.env':
NODE_ENV: '"production"'
),
new webpack.optimize.UglifyJsPlugin(
compress:
warnings: false,
screw_ie8: true,
drop_console: true,
drop_debugger: true
),
new webpack.optimize.OccurenceOrderPlugin(),
new ExtractTextPlugin('[contenthash].css',
allChunks: true
),
new HtmlWebpackPlugin(
template: './src/index.html',
title: 'Webpack App'
),
new webpack.optimize.DedupePlugin()
]
;
我的目标:在生产中部署这个应用程序。在服务器上运行我的应用程序的正确命令是什么,需要进行哪些必要的更改?希望有人可以提供帮助:(
【问题讨论】:
为您发布尽可能多的信息干杯:)。这里的问题是你需要使用 babel 来编译你的后端模块来使用 commonjs。假设您使用的是 node6,它将支持类等,但还不支持模块。 Webpack 使它工作,因为它使用 babel 加载器为您处理编译。我没有回答作为答案,因为我真的不知道在 nodejs 后端上的最佳解决方案。我仍然需要自己学习一些东西。 @agmcleod,是的,起初,我认为Node.js本身需要更新,所以我尝试更新。但不,那是行不通的。大声笑。 您是否正在尝试创建同构反应应用程序? @Everettss,我不太了解这个术语(同构反应应用程序),但我想要做的实际上是准备一个以 Express 作为后端的 Web 应用程序,并在前端进行 React-结束(暂时)。我想 Webpack 将帮助我优化资产、压缩 js 文件等以捆绑 (CMIIW) 形式交付。现在,这是我目前的目标:) 看起来您正在尝试在服务器上运行函数renderToString
,因此它是同构应用程序。只需向我们展示您的server.js
。
【参考方案1】:
1.如果你想创建同构 react 应用
由于你使用JSX
、.css
loader 和其他花哨的 webpack 东西,你也必须使用 webpack 来捆绑服务器端代码。有关更多信息,请查看此帖子Webpack for back-end?
2。如果您只想在客户端做出反应
只需通过函数 renderToString
删除用于在服务器端呈现静态 html 的代码,并且只在客户端留下用于引导的元素挂钩。
【讨论】:
以上是关于Node.js - 在 Server.js 上执行 Node 命令(Express + React + Webpack)的主要内容,如果未能解决你的问题,请参考以下文章
NODE.JS 如何使用 node.js 显示位于名为 CSS 的文件夹内的我的 css 文件,其中我的 server.js 和 index.html 在文件夹外