前言
使用react的朋友对jsx的语法相当熟悉,JavaScript和html混合开发,灵活快速,DOM结构一目了然,经过babel处理在渲染到页面上,下面我们来看一下
react如何处理jsx文件
下面看个demo,观察jsx的处理逻辑
先安装插件
yarn add webpack webpack-cli
yarn add babel-loader
yarn add @babel/plugin-transform-react-jsx
yarn add @babel/preset-react @babel/preset-env
简单配置一个webpack.config.js 解析 jsx
var path = require("path");
module.exports = {
mode: "development",
entry: "./demo1.jsx",
devtool: "source-map",
output: {
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /.jsx$/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
plugins: ["@babel/plugin-transform-react-jsx"]
}
}
}
]
}
};
再来一段demo1.jsx
const name = "world";
<h1 title='title' ref='title'>
hello, {name}
</h1>;
我们来看一下 webpack打包之后的文件内容
/***/ (function(module, exports) {
var name = "world";
/*#__PURE__*/
React.createElement("h1", {
title: "title",
ref: "title"
}, "hello, ", name);
/***/ })
可以看到babel 解析成了React.createElement,官网上React.createElement的说明
React.createElement( type, [props], [...children]):根据指定的第一个参数创建一个React元素
第一个参数是必填,传入的是HTML标签名称,eg: ul, li
第二个参数是选填,表示的是属性,eg: className
第三个参数是选填, 子节点,eg: 要显示的文本内容,
React.createElement源码地址
const hasOwnProperty = Object.prototype.hasOwnProperty;
const RESERVED_PROPS = {
key: true,
ref: true,
__self: true,
__source: true,
};
可以看到定义的属性ref,key会直接挂在生成元素上,而其他属性挂在props上,子元素可以是一个或者多个,都会被挂在props.children上,demo1的编译生成的"hello, ", name就是多个文本节点,最终生成的虚拟dom是这样子的
jsx 组件大小写问题
组件名首字母一定要大写,如果bable转化时 发现当前标签的首字母为大写 则表示当前的标签是一个函数名称 否则当前标签为一个字符串 看个例子
const Comp = () => <h1>hello, world</h1>;
const App = () => {
return <Comp />;
};
最终babel解析成
/*!*******************!*\
!*** ./demo2.jsx ***!
*******************/
/*! no static exports found */
/***/ (function(module, exports) {
var Comp = function Comp() {
/*#__PURE__*/
return React.createElement("h1", null, "hello, world");
};
/*#__PURE__*/
var App = function App() {
//返回React组件类型元素
return React.createElement(Comp, null);
};
/***/ })
/******/ });
若使用小写则会编译成
/*!*******************!*\
!*** ./demo2.jsx ***!
*******************/
/*! no static exports found */
/***/ (function(module, exports) {
/*#__PURE__*/
var comp = function comp() {
return React.createElement("h1", null, "hello, world");
};
var App = function App() {
//返回字符串元素
/*#__PURE__*/
return React.createElement("comp", null);
};
/***/ })
html 无法正常渲染
jsx文件不支持在花括号{}写表达式,原因大家大概知道为什么了吧
例如 { var a = 1; },babel会把var a=1;解析成子元素,肯定不对了,所以我们写jsx的时候要注意符合子元素定义