RequireJS load string

后端 未结 3 1397
隐瞒了意图╮
隐瞒了意图╮ 2021-02-10 01:47

In my app there are dynamic parts that are loaded from database as string that looks like:

\"define([\'dependency1\', \'dependency2\'], function(){\"+
\"   // fu         


        
相关标签:
3条回答
  • 2021-02-10 02:03

    To answer the question a little more directly, create a plugin like so:

    define("load-string",[], function(){
        var strings=[],
            re_package_name = /^string_module_(\d+)$/;
        return {
            normalize: function(name, _){
                if(re_package_name.test(name)){
                    return name
                }
                var nml = "string_module_" + (strings.push(name)-1);
                return nml;
            },
            load: function(name, _, onLoad, config){
                if(re_package_name.test(name)){
                    onLoad.fromText(strings[name.match(re_package_name)[1]]);
                }else{
                    onLoad.error("Invalid package name: ",name);
                }
            }  
        }
    });
    

    and use it like so:

    var world_module = "define([],function(){return 'world!'})";
    
    require(["load-string!" + world_module],
        function(x){
            console.log("Hello "+x);
        })
    
    0 讨论(0)
  • 2021-02-10 02:17

    You should be able to do :

    require(["jquery"], function($){        
        $(document).ready(function(){
            // logic to load specific script from database
            var scriptString = functionToLoadTheStringAbove();
    
            var olddefine = define; // require js define 
            var runme; // capture function 
            define = function (args,func){
                 runme = func; 
            }
            eval(scriptString);
            runme(); // run the function in current scope
            define = olddefine; // restore requirejs function 
    
            // dependency1, dependency2 are loaded        
        });
    });
    
    0 讨论(0)
  • 2021-02-10 02:22

    This is quite late, but I just post my solution here in case anyone needs.

    So I ended up asking in requireJS forum and examining the source of text! plugin and json! plugin. The cleanest way to load module from String in RequireJS is by making your own plugin to load the String, and then use onLoad.fromText() that will eval your String and resolve all dependencies.

    Example of my plugin (let's call it db! plugin):

    define([], function(){
        var db = new Database(); // string is loaded from LocalStorage
        return {
            load: function(name, req, onLoad, reqConfig){
                db.get(name, function(err, scriptString){
                    if (err) onLoad(err);
                    else onLoad.fromText(scriptString);
                });  
             }
        }
    });
    

    You can then use the plugin like:

    require(["jquery", "db!myScript"], function($, myScript){        
        // jQuery, myScript and its dependencies are loaded from database
    });
    

    Note:

    1. There's no way to require() from String without eval. This is what onLoad.fromText() does internally. Since eval is evil, you should only use it if you know what String you're going to eval(). If you're using it in browser extension, you might want to relax the CSP policy.
    2. To name your String module, you can use explicit naming syntax. This way, your module will always have the same absolute name.
    0 讨论(0)
提交回复
热议问题