DelSkayn / rquickjs

High level bindings to the quickjs javascript engine
MIT License
503 stars 63 forks source link

Redeclaration of Modules? #344

Open Gentle opened 2 months ago

Gentle commented 2 months ago

I would like to be able to redeclare modules, but the observed behavior is that the first declaration is always taken

Example Code that doesn't do what I would have expected:

    #[test]
    fn test_redeclare() {
        let rt = rquickjs::Runtime::new().unwrap();
        let context = rquickjs::Context::full(&rt).unwrap();
        context.with(|ctx| {
            Module::evaluate(
                ctx.clone(),
                "a",
                r#"export default function() { return 42 }"#,
            )
            .catch(&ctx)
            .unwrap();
            while ctx.execute_pending_job() {}
            Module::evaluate(
                ctx.clone(),
                "a",
                r#"export default function() { return 10 }"#,
            )
            .catch(&ctx)
            .unwrap();
            while ctx.execute_pending_job() {}
            let (module, _) = Module::declare(
                ctx.clone(),
                "b",
                r#"
                import blah from 'a'
                export default function() { return blah() }
                "#,
            )
            .catch(&ctx)
            .unwrap()
            .eval()
            .catch(&ctx)
            .unwrap();
            while ctx.execute_pending_job() {}
            let func = module
                .namespace()
                .unwrap()
                .get::<_, Function>("default")
                .unwrap();
            let x: i32 = func.call(()).catch(&ctx).unwrap();
            assert_eq!(x, 10);
        });
    }
DelSkayn commented 2 months ago

This is the standard QuickJS behavior and I think rquickjs should stick to to how QuickJS does things.

DelSkayn commented 1 month ago

Too add I don't think there is a good way to support this without some extensive patching of QuickJS. So I don't think there is a way to do this.

Gentle commented 1 month ago

thanks for your response, I assumed as much

I'm trying to get some form of hot module reloading to work, I've now switched to declaring the modules and keeping the returned namespace in a registry, so that the registry can handle when a module has been replaced with a new version

If there's a better way I'm interested :)