react框架中无构建模式直接使用es6组件

文章讲述了在React18.1.0版本中官方未提供ES6模块支持的情况下,如何通过将React和相关库如ReactDOM封装为ES6模块,以及如何处理依赖于window.React的第三方组件,以便在浏览器中使用ES6原生开发方式。作者提倡简洁开发,避免过多工具层次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

react框架,看到的总是使用es5,通过webpack编译构建。react官方,直到现在的v18.1.0版本中,只有cjs和umd版本,都没有esm(es6)版本,看起来是对es6的不认可?

但是,大家写react组件都是按es6语法在写,最后搞了一大堆webpack/babel来转成es5运行,啰里啰嗦的,特别是搞出了import加载css,import加载图片的语法,不好理解。为何不直接使用es6原生模式直接运行呢?

我比较喜欢“浏览器原生开发”,不想如俄罗套娃一样,一层层套下去,搞了很多半生不熟的工具(react-app在node_modules下搞出的921个组件,是很唬人的),最后出问题了还不知道哪里找。

相比较而言,vue 3.3.4版本就有cjs和esm版本,使用vue的框架就可以使用es6。

那是否react框架真的没有办法使用es6运行呢?那倒不是,只是麻烦些,方法如下。

(1)react和react-dom封装成es6

有些第三方组件,引用react是隐式从window.React来,有的是显示import。

import React from 'react';

class YJFoilTopLeft extends React.Component {

不太可能去要求人家全部改掉。只能把react封装成一个esm版本的组件:

react@foil.mjs

/**
 * react v18.1.0,官方没有提供es6版本,这里把es5版本包装成es6版本。
 */
let React = window.yjRequire('react@raw');
let { Children, Component, Fragment, Profiler, PureComponent, StrictMode,
  Suspense, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, cloneElement,
  createContext, createElement, createFactory, createRef, forwardRef,
  isValidElement, lazy, memo, startTransition, unstable_act, useCallback,
  useContext, useDebugValue, useDeferredValue, useEffect, useId, useImperativeHandle,
  useInsertionEffect, useLayoutEffect, useMemo, useReducer, useRef, useState,
  useSyncExternalStore, useTransition, version } = React;
export {
  Children, Component, Fragment, Profiler, PureComponent, StrictMode,
  Suspense, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, cloneElement,
  createContext, createElement, createFactory, createRef, forwardRef,
  isValidElement, lazy, memo, startTransition, unstable_act, useCallback,
  useContext, useDebugValue, useDeferredValue, useEffect, useId, useImperativeHandle,
  useInsertionEffect, useLayoutEffect, useMemo, useReducer, useRef, useState,
  useSyncExternalStore, useTransition, version
}
export default React;

如果你是用<script src='/react/umd/react.development.js'>加载React到window上的,那上面的let React = window.yjRequire('react@raw');可以改为:let React = window.React;

react-dom也类似:

react-dom@foil.mjs

/**
 * react-dom v18.1.0,官方没有提供es6版本,这里把es5版本包装成es6版本。
 */
let ReactDOM = window.yjRequire('react-dom@raw');
let { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, createPortal, createRoot,
  findDOMNode, flushSync, hydrate, hydrateRoot, render, unmountComponentAtNode,
  unstable_batchedUpdates, unstable_renderSubtreeIntoContainer, version } = ReactDOM;
export {
  __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, createPortal, createRoot,
  findDOMNode, flushSync, hydrate, hydrateRoot, render, unmountComponentAtNode,
  unstable_batchedUpdates, unstable_renderSubtreeIntoContainer, version
}
export default ReactDOM;

浏览器中的importMap这样写:

{
  'react@raw':"/react/umd/react.development.js",
  'react-dom@raw':"/react-dom/umd/react-dom.development.js",
         
  'react':'/spa/react/root/src/wrapper/react@foil.mjs',
  'react-dom':'/spa/react/root/src/wrapper/react-dom@foil.mjs'
}

(2)遇到其它没有esm版本的第三方组件,如法炮制。

如:devextreme-react用到的prop-types,也是没有esm版本:

prop-types@foil.mjs

/**
 * prop-types v15.8.1,官方没有提供es6版本,这里把es5版本包装成es6版本。
 */
let PropTypes = window.yjRequire('prop-types@raw');
let { array, bigint, bool, func, number, object, string, symbol,
  any, arrayOf, element, elementType, instanceOf, node, objectOf,
  oneOf, oneOfType, shape, exact, checkPropTypes, resetWarningCache} = PropTypes;
export {
  array, bigint, bool, func, number, object, string, symbol,
  any, arrayOf, element, elementType, instanceOf, node, objectOf,
  oneOf, oneOfType, shape, exact, checkPropTypes, resetWarningCache, PropTypes
}
export default PropTypes;

在浏览器importMap中加上映射:

{
  "prop-types@raw":"/devextreme-react/node_modules/prop-types/prop-types.js",
  "prop-types":"/spa/react/root/src/wrapper/prop-types@foil.mjs",
}

rc-easyui 1.2.9版本也没有esm版本,你自己封装试试吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火星牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值