Reactjs babel loader、webpack、ES2015模块:;元素类型无效";

Reactjs babel loader、webpack、ES2015模块:;元素类型无效";,reactjs,ecmascript-6,webpack,babeljs,Reactjs,Ecmascript 6,Webpack,Babeljs,Github回购协议,包括以下内容: 更新12/18:问题的很大一部分是用于运行项目的npm命令。我注意到npm构建没有成功,但是npm启动报告构建正常。下面的完整答案说明了为什么这样做没有达到预期效果。这个问题的其余部分留给子孙后代 我的第一个网页项目的基本设置有问题。我正在使用React和Babel,以及以下webpack.config.js: var path = require('path'); module.exports = { entry: [ path.resolve('

Github回购协议,包括以下内容:

更新12/18:问题的很大一部分是用于运行项目的npm命令。我注意到
npm构建
没有成功,但是
npm启动
报告构建正常。下面的完整答案说明了为什么这样做没有达到预期效果。这个问题的其余部分留给子孙后代


我的第一个网页项目的基本设置有问题。我正在使用React和Babel,以及以下
webpack.config.js

var path = require('path');

module.exports = {
  entry: [ path.resolve('./js/app.js'),
           'webpack-dev-server/client?http://localhost:8080' ],
  output: {
    path: path.resolve('./js/build'),
    filename: 'app.min.js'
  },
  module: {
    loaders: [
      { test: /\.jsx?$/,
        loader: 'babel',
        query: {
          presets: ['react', 'stage-1', 'es2015']
        },
        include: path.resolve('js/') } ]
  },
  devtool: 'source-map'
};
js/app.js

import Lifecycle from './components/lifecycle';
import React from 'react';
import {render} from 'react-dom';

var shell = document.createElement('div');
shell.className = 'app-shell';
document.body.appendChild(shell);
render(<Lifecycle />, shell);
import React from 'react';

class Lifecycle extends React.Component {
  render() {
    return (
      <div>Hello, world</div>
    );
  }
}

export default Lifecycle;
上面的构建没有错误,但不会呈现“Hello,world”。我在浏览器控制台中得到错误:“不变冲突:元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。”

我可以追踪到一些生成的babel代码,这些代码试图检查我的模块
生命周期
是否是ES6模块(babel可以识别它),并希望它在内部模块对象上有一个属性
默认值
(它没有)。下面是生成的代码:

/* 0 */
/***/ function(module, exports, __webpack_require__) {

  'use strict';

  var _lifecycle = __webpack_require__(1);

  var _lifecycle2 = _interopRequireDefault(_lifecycle);

  var _react = __webpack_require__(2);

  var _react2 = _interopRequireDefault(_react);

  var _reactDom = __webpack_require__(159);

  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

  (0, _reactDom.render)(_react2.default.createElement(_lifecycle2.default, null), document.body);

/***/ }

最后一点注意:我为安装引用了好几次,我可以将该示例repo克隆并构建到一个正常工作的应用程序中。我意识到我一定错过了回购协议中发生的一些重要部分,但我看不到它。

是否有理由在
app.js
中动态创建应用程序的容器div,而不仅仅是将其放入
index.html
?我克隆了您的回购协议,并通过以下更改获得了要构建的应用程序:

index.html:

<body>
   <div id="app-shell"></div>
   <script type="application/javascript" src="js/build/app.min.js"></script>
</body>
import React from 'react';
import Layout from './Layout';
import {render} from 'react-dom';

if (typeof document !== 'undefined') {
  render(<Layout />, document.getElementById('app'));
}

module.exports = Layout;

app.js

import React from 'react';
import {render} from 'react-dom';
import Lifecycle from './components/lifecycle';

render(<Lifecycle />, document.getElementById('app-shell'));
export default class Layout extends Component {
  constructor(props) {
   super(props);
  }

  render() {
    return (
      <div className="Layout">

      </div>
    )
  }
};
从“React”导入React;
从'react dom'导入{render};
从“./components/Lifecycle”导入生命周期;
render(,document.getElementById('app-shell');
我认为
“元素类型无效”
错误是一个转移视线的错误。在此之前,我看到:

警告:React.createElement:类型不应为null,未定义, 布尔值,或数字。它应该是字符串(对于DOM元素)或 ReactClass(用于复合组件)。警告@ app.min.js:2233createElement@app.min.js:19531(匿名函数)@ app.min.js:61__网页_require__@app.min.js:20(匿名函数)@ app.min.js:40(匿名函数)@app.min.js:43 app.min.js:2233 警告:render():将组件直接呈现到document.body中是 不鼓励,因为它的孩子经常被第三方操纵 脚本和浏览器扩展。这可能导致微妙的和解 问题。尝试渲染到为应用程序创建的容器元素中

这可能是由于您在
app.js

中创建shell元素的方式对我很有效

git clone https://github.com/b-paul/react-lifecycle.git
cd react-lifecycle.git
npm install
npm run build
npm run start
# go to http://localhost:8090/index.html    

这个问题应该被称为“为什么我的NPM脚本不能更新我的包?”

在开发初期的某个时候,我成功地将代码与webpack捆绑在一起。该捆绑包以
js/build/app.min.js
的形式存在于磁盘上。在那之后,我认为我是在使用
package.json
中的NPM脚本来用每次更改重新构建应用程序,但在浏览器中,我仍然得到了旧的行为(来自原始捆绑包)。我遗漏了两个事实:

事实1:是一个公认的NPM命令,但它不会从
package.json
调用
scripts.build
。在@zhongjie wu中,我需要执行
npm运行构建
<另一方面,code>npm start确实调用了
脚本。start
,它成功地与
webpack dev server
构建了一个捆绑包


事实2:
网页包开发服务器
在为重建包提供服务时,无法将网页包配置文件中的
输出.path
识别为路由的一部分。因此,考虑到我使用的配置,
webpack
构建到
/js/build/app.min.js
,但是
webpack dev server
从内存中作为
/app.min.js
提供该捆绑包。因为我的HTML引用了原始版本,所以我没有看到dev服务器包。

Layout.js

import React from 'react';
import {render} from 'react-dom';
import Lifecycle from './components/lifecycle';

render(<Lifecycle />, document.getElementById('app-shell'));
export default class Layout extends Component {
  constructor(props) {
   super(props);
  }

  render() {
    return (
      <div className="Layout">

      </div>
    )
  }
};
和条目文件需要执行ES5导出:

<body>
   <div id="app-shell"></div>
   <script type="application/javascript" src="js/build/app.min.js"></script>
</body>
import React from 'react';
import Layout from './Layout';
import {render} from 'react-dom';

if (typeof document !== 'undefined') {
  render(<Layout />, document.getElementById('app'));
}

module.exports = Layout;
从“React”导入React;
从“./Layout”导入布局;
从'react dom'导入{render};
如果(文档类型!==“未定义”){
render(,document.getElementById('app'));
}
module.exports=布局;
它对我有用