Reactjs babel loader、webpack、ES2015模块:;元素类型无效";
Github回购协议,包括以下内容: 更新12/18:问题的很大一部分是用于运行项目的npm命令。我注意到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('
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=布局;
它对我有用