2

问题描述

项目需要用到的第三方库sigma.js没有提供import引入的module形式,只提供了min.js文件,而且这个第三方库比较大,需要在项目中进行按需加载,按需加载是通过import()实现的,而这个第三方库提供的min.js文件不能直接import吧(我的理解是这样)

这是用这个第三方库举例子,不代表只是解决这个库就可以了,项目用到了很多老的库,这些库不知道怎么引用

问题出现的环境背景及自己尝试过哪些方法

当前的解决方案是后端处理的,后端判断访问的页面需要使用这个库的时候写入html文件中,从而使得react项目可以以全局变量的实行获取到这个库

2019-07-14 提问
2 个回答
1

已采纳

之前做过一个类似场景,比如要使用百度地图JS SDK,但又不想在html写死,我们的做法是在需要的时候再按需用script去加载, 比如

const headElement = document.head || document.getElementsByTagName('head')[0]
const _importedScript: { [src: string]: true } = {}
/**
 * load dependency by script tag
 */
export function importScript(src: string): Promise<void> {
  return new Promise((resolve, reject) => {
    if (src in _importedScript) {
      resolve()
      return
    }
    const script = document.createElement('script')
    script.type = 'text/javascript'
    script.onerror = err => {
      headElement.removeChild(script)
      reject(new URIError(`The Script ${src} is no accessible.`))
    }
    script.onload = () => {
      _importedScript[src] = true
      resolve()
    }
    headElement.appendChild(script)
    script.src = src
  })
}

按照上面的方式,这些库一般只能使用全局变量去操作,也没有必要经过webpack中转,像以前的JQuery一样用不就行了。

Ok, 下一步怎么和React组件配合呢?因为你必须加载了这个依赖才能安全地进行下级的渲染,这里可以使用Suspend和lazy来实现:

export function loadScript<T extends ComponentType<any>>(
  src: string,
  factory: () => Promise<{ default: T }>,
  Fallback?: React.ComponentType
) {
  const Comp = lazy(() => importScript(src).then(factory));

  return props => {
    return (
      <Suspense fallback={Fallback ? <Fallback /> : null}>
        <Comp {...props} />
      </Suspense>
    );
  };
}

假设我们的下级组件是这样的:

export default function UseJQ() {
  useEffect(() => {
    // 这里需要安全地访问jQuery
    console.log($);
  }, []);
  return <div>hello jQuery</div>;
}

怎么使用?我们这里尽量靠近React的lazy接口使用方式:

const src = "https://unpkg.com/jquery@3.4.1/dist/jquery.js";
const UseJQ = loadScript(src, () => import("./UseJQ"));

function App() {
  return (
    <div className="App">
      <UseJQ />
    </div>
  );
}

点击这里查看CodeSandbox实例

最后,欢迎关注我和我交流。

0

min.js为什么不能直接import?不管是同步还是异步都可以,webpack会自动为你处理成模块化

撰写答案

推广链接