我可以从客户端动态加载JS模块吗?

时间:2019-10-01 05:20:06

标签: javascript

在我的Web应用程序中,我希望使用户能够编写自己的模块以在应用程序中使用。理想情况下,这些是在客户端用JS编写的。

但是,我无法让应用程序访问在客户端创建的类。最初,我需要某种类型的模块导入,但是动态导入仍然需要一个路径,出于安全原因,浏览器无法访问该路径。将JS直接导入到脚本标签中会污染全局名称空间,这也不理想。

有一些明智的方法吗?理想情况下,我想导入该类,例如

// MyClass.js, on the client side
export default class MyClass {
    myPrint() {
        console.log('ya blew it');
    }
}

然后在App.js中:

import(somehow_get_this_path).then((MyClass) => { etc});

这条路有可能吗?当前的命名空间污染方法使用选择文件对话框,但不允许我告诉导入它具有的路径。您得到的只是一个斑点。我对这些东西还很陌生,所以如果这个问题很愚蠢,我深表歉意。

编辑:我尝试使用CreateObjectURL来获取对象URL,这会导致错误:

Error: Cannot find module 'blob:null/d651a896-d568-437f-86d0-72ebcee7bc56'

2 个答案:

答案 0 :(得分:0)

如果您将webpack用作捆绑程序,则可以使用magic comments来延迟加载组件。

否则您可以使用动态导入。

 import('path_to_my_class').then(MyClass => {
    // Do something with MyClass
 });

编辑1:-

您可以使用此代码获取上载js文件的有效本地URL。尝试使用此

const path = (window.URL || window.webkitURL).createObjectURL(file);
console.log('path', path);

编辑2:-

或者,您可以在全局级别创建自己的对象,并使用匿名函数(创建闭包)包装文件,以免污染全局命名空间。

// you can add other methods to it according to your use case.
window.MyPlugins =  {
  plugins: [],
  registerPlugin: function (plugin){
    this.plugins.push(plugin);
  }
}
// MyFirstPlugin.js

// you can inject this code via creating a script tag.

(function(w){ //closure
  function MyFirstPlugin() {
    this.myPrint = function (){
       console.log('ya blew it');
    }
  }
  w.MyPlugins.registerPlugin(new MyFirstPlugin());
})(window)
// get the reference to the plugin in some other file
 window.MyPlugins.plugins

答案 1 :(得分:0)

读取文件并使用eval

 <script>
 function importJS(event) {
   var input = event.target;
   var reader = new FileReader();
   reader.onload = function(){
      eval(reader.result);
      input.value='';
   };
   reader.readAsText(input.files[0]);
 };
</script>

Select a *.js file and execute
<br>
<br>
<input type="file" onchange="importJS(event);">