好家伙!果然报错了。这里的报错告诉我们,在 = 后面不能使用 “小于号”,但是在正常的 JSX 语法中,这个其实是 HTML 标签的 “尖括号”,因为没有 JSX 语法的编译过程,所以 JavaScript 默认就会认为这个就是 “小于号”。
所以我们要怎么做让我们的 webpack 编译过程支持 JSX 语法呢?这里其实就是还需要我们加入一个最关键的一个包,而这个包名非常的长,叫做 @babel/plugin-transform-react-jsx。好那么我们就执行一段命令来安装一下这个包:
npm install --save-dev @babel/plugin-transform-react-jsx
安装好之后,我们还需要在 webpack 配置中给他加入进去。我们需要在 module 里面的 rules 里面的 use 里面加入一个 plugins 的配置中加入 ['@babel/plugin-transform-react-jsx']。
然后最终我们的 webpack 配置文件就是这样的:
module.exports = { entry: 'https://www.jb51.net/article/main.js', mode: 'development', module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: ['@babel/plugin-transform-react-jsx'], }, }, }, ], }, };
配置好之后,我们再去执行一下 webpack。这时候我们发现没有再报错了。这样也就证明我们的代码现在是支持使用 JSX 语法编写了。
最后我们来围观一下,最后编程的效果是怎么样的。
我们会发现,在 eval 里面我们加入的 <div/> 被翻译成一个 React.createElement("div", null) 的函数调用了。
所有接下来我们就一起来看一下,我们应该怎么实现这个 React.createElement,以及我们能否把这个换成我们自己的函数名字。
JSX 基本用法首先我们来尝试理解 JSX,JSX 其实它相当于一个纯粹在代码语法上的一种快捷方式。在上一部分的结尾我们看到,JSX语法在被编译后会出现一个 React.createElement 的一个调用。
JSX 基础原理那么这里我们就先修改在 webpack 中的 JSX 插件,给它一个自定义的创建元素函数名。我们打开 webpack.config.js,在 plugins 的位置,我们把它修改一下。
module.exports = { entry: 'https://www.jb51.net/article/main.js', mode: 'development', module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: [ [ '@babel/plugin-transform-react-jsx', { pragma: 'createElement' } ] ], }, }, }, ], }, };
上面我们只是把原来的 ['@babel/plugin-transform-react-jsx'] 参数改为了 [['@babel/plugin-transform-react-jsx', {pragma: 'createElement'}]]。加入了这个 pragma 参数,我们就可以自定义我们创建元素的函数名。
这么一改,我们的 JSX 就与 React 的框架没有任何联系了。我们执行一下 webpack 看一下最终生成的效果,就会发现里面的 React.createElement 就会变成 createElement。
接下来我们加入一个 HTML 文件来执行我们的 main.js 试试。首先在根目录创建一个 main.html,然后输入一下代码:
<script src="https://www.jb51.net/article/main.js"></script>
然后我们执行在浏览器打开这个 HTML 文件。
这个时候我们控制台会给我们抛出一个错误,我们的 createElement 未定义。确实我们在 main.js 里面还没有定义这个函数,所以说它找不到。
所以我们就需要自己编写一个 createElement 这个函数。我们直接打开根目录下的 main.js 并且把之前的 for 循环给删除了,然后加上以下代码:
function createElement() { return; } let a = <div />;
这里我们就直接返回空,先让这个函数可以被调用即可。我们用 webpack 重新编译一次,然后刷新我们的 main.html 页面。这个时候我们就会发现报错没有了,可以正常运行。
实现 createElement 函数在我们的编译后的代码中,我们可以看到 JSX 的元素在调用 createElement 的时候是传了两个参数的。第一个参数是 div, 第二个是一个 null。