从流中动态导入Javascript模块

sha*_*haz 7 javascript firebase reactjs webpack react-loadable

目标:支持基于某些安全性或定义的用户角色要求的动态加载Javascript模块,这样,即使在开发工具中标识了模块名称,也无法通过控制台成功导入。

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

可以轻松地将JavaScript模块上载到Firebase(#AskFirebase)之类的云存储服务,并且可以firebase.functions().httpsCallable("ghost");基于自定义声明或类似测试的使用Firebase Cloud Function有条件地检索代码。

export const ghost = functions.https.onCall(async (data, context) => {
  if (! context.auth.token.restrictedAccess === true) {
    throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
  }

  const storage = new Storage();
  const bucketName = 'bucket-name.appspot.com';
  const srcFilename = 'RestrictedChunk.chunk.js';

  // Downloads the file
  const response = await storage
    .bucket(bucketName)
    .file(srcFilename).download();
  const code = String.fromCharCode.apply(String, response[0])

  return {source: code};

})
Run Code Online (Sandbox Code Playgroud)

最后,我想做的是...

...将一个Webpack的React组件放入云端,在服务器端进行安全检查后有条件地将其下载到客户端,然后将import()其下载到用户的客户端环境中并进行渲染。

将Javascript存储在云中并有条件地下载到客户端很容易。在客户端中有了webpack的代码后,就可以像Function(downloadedRestrictedComponent)将其使用时那样将其添加到用户环境中,import('./RestrictedComponent')但是我不知道是如何从组件中获取默认导出的,以便我可以实际渲染事情。

import(pathToComponent)返回加载的模块,据我所知,没有选项传递import()字符串或流,而只是传递模块的路径。并且Function(downloadedComponent)会将下载的代码添加到客户端环境中,但是我不知道如何访问模块的导出以呈现动态加载的React组件。

有什么方法可以从下载的流中动态导入Javascript模块吗?

编辑添加:感谢您的回复。不熟悉Blobs和URL.createObjectURL。知道为什么会找不到吗?

const ghost = firebase.functions().httpsCallable("ghost");

const LoadableRestricted = Loadable({
  //  loader: () => import(/* webpackChunkName: "Restricted" */ "./Restricted"),
  loader: async () => {
    const ghostContents = await ghost();
    console.log(ghostContents);
    const myBlob = new Blob([ghostContents.data.source], {
      type: "application/javascript"
    });
    console.log(myBlob);
    const myURL = URL.createObjectURL(myBlob);
    console.log(myURL);
    return import(myURL);
  },
  render(loaded, props) {
    console.log(loaded);
    let Component = loaded.Restricted;
    return <Component {...props} />;
  },
  loading: Loading,
  delay: 2000
});
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

Ran*_*urn 4

将模块文件/流的内容读入 BLOB。用于URL.createObjectURL()创建 BLOB 的动态 URL。import现在按照上面的建议使用:

import(myBlobURL).then(module=>{/*doSomethingWithModule*/});
Run Code Online (Sandbox Code Playgroud)