在我的webpack入口文件中,我有这个:
import ReactDOM from 'react-dom';
import Layout from './components/Layout';
// ...
dialog = document.createElement("dialog");
ReactDOM.render(<Layout dialog={dialog} />, dialog);
这将编译为React.createElement(o,{dialog:u})
然后我的脚本抱怨React
没有定义,因为我还没有导入它
同时,如果我在文件顶部添加import React from 'react';
,Webpack的行就会变成i.a.createElement(o,{dialog:u})
。
在我不手动导入React的情况下,它究竟为什么要使用React.createElement
?
我的Webpack配置是:
const path = require('path');
const os = require('os');
const PLUGINDIR = `${os.homedir()}/Library/Application Support/Adobe/Adobe XD CC/develop/ea44acd5/`;
module.exports = {
entry: './src/main.js',
mode: 'production',
output: {
path: path.resolve(PLUGINDIR),
filename: 'main.js',
libraryTarget: "commonjs2"
},
module: {
rules: [{
test: /.jsx?$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
plugins: [
"transform-react-jsx"
]
}
}, {
test: /.css$/,
use: ["style-loader", "css-loader"]
}]
}
};
Webpack没有插入"React.createElement"。Babel这样做是为了转换JSX(例如<Layout .../>
)。我怀疑在第一种情况下,webpack不知道React是什么,所以它不会缩小对它的引用。在第二种情况下webpack确实知道它是什么,因此它可以更智能地处理它,并适当地缩小它。
这是因为react
是react-dom
的对等依赖项;你可以在react-dom
的package.json
中看到这一点。换句话说,react-dom
在内部使用react代码,并希望您使用与package.json
中的版本兼容的react
版本,它不会自己安装react
版本。
这和webpack有什么关系?好吧,webpack将使用~/node_modules/react-dom/cjs/react-dom.development.js
或~/node_modules/react-dom/cjs/react-dom.production.min.js
,这取决于您是处于开发模式还是生产模式。这两个文件中的代码,即使使用了react,也不会理解react语法,因为它们是使用~/node_modules/react-dom/package.json
生成的,并且react
在该文件中被列为对等依赖项。
如果react
不是react-dom
的对等依赖项,而是正常依赖项,则可以跳过import React from 'react'
,但如果使用不同版本的react
有其他依赖项,就会遇到问题。
最后,您在webpack生成的捆绑文件中看到的内容在很大程度上取决于您使用的webpack版本。本质上,webpack创建依赖项的对象(或数组,具体取决于webpack版本)。在您的情况下,i
将是包含所有依赖项的对象,而a
将是指向反应的关键。您可以在本指南中找到有关webpack内部的更多详细信息。