You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Svein-Erik Løken <sv...@jacilla.no> on 2017/11/24 13:13:55 UTC

Contribute requirejs.config.paths to ModuleManager

Trying to use TypeScript and React with Tapestry:

In TypeScript I need to use:  import * as React from "react";

I would like to load react: react.min, so I have to set paths: {...}

The configuration should be set at startup, but I cannot figure how to do it. I can set requirejs.config.shim, but not paths.

I tried to load it with @Contribute(ModuleManager.class), but could not figure out how.

PSEUDO CODE
@Contribute(ModuleManager.class)
public static void setupMyBaseModules(MappedConfiguration<String, Object> configuration) {
    JSONObject pathsConfig = new JSONObject(
            "react", "react.min",
            "react-dom", "react-dom.min"
    );
    AMDResourceConfiguration paths = new AMDResourceConfiguration("paths", pathsConfig);
    configuration.add(null, new JavaScriptModuleConfiguration(paths));
}


Tried to load it this way:


@Startup
public void registerToClearPlasticProxyFactoryOnInvalidation(JavaScriptSupport javaScriptSupport) {
    ModuleConfigurationCallback callback = new
            ModuleConfigurationCallback() {
                @Override
                public JSONObject configure(JSONObject configuration) {
                    configuration.put("paths",
                            new JSONObject(
                                    "react", "react.min",
                                    "react-dom", "react-dom.min"
                            ));
                    return configuration;
                }
            };
    javaScriptSupport.addModuleConfigurationCallback(callback);
}

[ERROR] ioc.Registry org.apache.tapestry5.ioc.util.UnknownValueException: No object of type org.apache.tapestry5.services.javascript.JavaScriptSupport is available from the Environment.






Now I am loading the configuration in @SetupRender, but it should be loaded globally.


@Inject
JavaScriptSupport javaScriptSupport;

private static final ModuleConfigurationCallback CALLBACK = new
        ModuleConfigurationCallback() {
            @Override
            public JSONObject configure(JSONObject configuration) {
                configuration.put("paths",
                        new JSONObject(
                                "react", "react.min",
                                "react-dom", "react-dom.min"
                                ));
                return configuration;
            }
        };

@SetupRender
public void configureRequireJS() {
    javaScriptSupport.addModuleConfigurationCallback(CALLBACK);
}

Can this be configuration be contribute to the ModuleManager.class? I think this should be supported in Tapestry.

S-E




RE: Contribute requirejs.config.paths to ModuleManager

Posted by Svein-Erik Løken <sv...@jacilla.no>.
I tried to fight it too, but had to capitulate. 

After some debugging my @Contribute(JavaScriptStackSource.class) was not set:

public class ModuleManagerImpl implements ModuleManager
{
private Resource resolveModuleNameToResource(String moduleName)
    {
        Resource resource = shimModuleNameToResource.get(moduleName);

        if (resource != null)
        {
            return resource;
        }

        // Tack on a fake extension; otherwise modules whose name includes a '.' get mangled
        // by Resource.withExtension().
        String baseName = String.format("/META-INF/modules/%s.EXT", moduleName);

        Resource baseResource = classpathRoot.forFile(baseName);

        for (String extension : extensions)
        {
            resource = baseResource.withExtension(extension);

            if (resource.exists())
            {
                return resource;
            }
        }

        // Return placeholder for null:
        return classpathRoot;
    }

My module is not listed in shimModuleNameToResource, and does not exist in /META-INF/modules/%s.EXT. The result is an empty classpathRoot.


I think I don't fully understand JavaScriptStack. I think a method is missing: Map<String, JavaScriptModuleConfiguration> getJavaScriptModules(). I would like to have a example of how to include a AMD/UMD module. What about support for CommonJS?




In the debugging process I found that @Contribute(ModuleManager.class) was the perfect choice for me.

    @Contribute(ModuleManager.class)
    public static void setupMyBaseModules(MappedConfiguration<String, Object> configuration, @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode) {
        String[] reactModules = {"react", "react-dom"};
        String ext = productionMode ? ".min.js" : ".js";
        for (String m : reactModules) {
            configuration.add(m, new JavaScriptModuleConfiguration(new ClasspathResource(String.format("META-INF/assets/js/%s%s", m, ext))));
        }
    }

I think I was fooled by:

The documentation for ModuleManager.class say:
"...This is primarily used to wrap non-AMD compliant libraries for use with RequireJS"

The internal variable Map<String, Resource> shimModuleNameToResource in ModuleManagerImpl. The shim prefix...

S-E




From: Chris Poulsen [via Apache Tapestry Mailing List Archives] [mailto:ml+s1045711n5733731h42@n5.nabble.com] 
Sent: tirsdag 28. november 2017 08:34
To: Svein-Erik Løken <sv...@jacilla.no>
Subject: Re: Contribute requirejs.config.paths to ModuleManager

Hi, 

It has been a while since I last fought the module system, but in some 
cases I've used a request filter to map between module and asset paths 
(triggering on known module paths and then returning permanent redirects to 
the actual asset urls in the filter) - This was necessary in order to get 
stuff like CK editor to load properly as a module and still allowing it to 
dynamically require its plugins IIRC. 

-- 
Chris 




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org

Re: Contribute requirejs.config.paths to ModuleManager

Posted by Chris Poulsen <ma...@nesluop.dk>.
Hi,

It has been a while since I last fought the module system, but in some
cases I've used a request filter to map between module and asset paths
(triggering on known module paths and then returning permanent redirects to
the actual asset urls in the filter) - This was necessary in order to get
stuff like CK editor to load properly as a module and still allowing it to
dynamically require its plugins IIRC.

-- 
Chris


On Mon, Nov 27, 2017 at 2:14 PM, Svein-Erik Løken <sv...@jacilla.no> wrote:

> Got this error message (very informative):
>
> org.apache.tapestry5.ioc.util.UnknownValueException
> Unable to create a client URL for classpath resource
> META-INF/modules/react/react.min.js: The resource path was not within an
> aliased path.
> availableValues
> Aliased paths:
> • META-INF/assets
> • META-INF/assets/core
> • META-INF/assets/democore
> • com/demo/core
> • com/demo/module1
> • com/demo/module1
> • org/apache/tapestry5
> • org/apache/tapestry5
>
>
>
> Tried other locations:
>
> public class ReactStack implements JavaScriptStack {
>     private final AssetSource assetSource;
>
>     public ReactStack(final AssetSource assetSource) {
>         this.assetSource = assetSource;
>     }
>
>     public List<Asset> getJavaScriptLibraries() {
>         List<Asset> ret = new ArrayList<>();
> //        ret.add(assetSource.getClasspathAsset("/META-INF/
> modules/react/react.min.js"));
> //        ret.add(assetSource.getClasspathAsset("/META-INF/
> assets/react/react.min.js"));
> //        ret.add(assetSource.getClasspathAsset("/META-INF/
> assets/react/react.js"));
> //        ret.add(assetSource.getClasspathAsset("/META-INF/
> assets/react.min.js"));
>         ret.add(assetSource.getClasspathAsset("/META-INF/
> assets/react.js"));
>         return ret;
>     }
>
>
> Still getting:
> Loading 1 libraries
> Loading library /assets/meta/z94ea83c9/react.js
> Executing 3 inits
> Loaded module bootstrap/collapse
> GET http://localhost:9876/modules.gz/react.js 404 (No module for path
> 'react.js'.)
>
> Very strange that the virtual link does not work!
>
> S-E
>
>
> From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List
> Archives] [mailto:ml+s1045711n5733729h80@n5.nabble.com]
> Sent: mandag 27. november 2017 13:32
> To: Svein-Erik Løken <sv...@jacilla.no>
> Subject: Re: Contribute requirejs.config.paths to ModuleManager
>
> On Sun, Nov 26, 2017 at 10:40 AM, Svein-Erik Løken
> </user/SendEmail.jtp?type=node&node=5733729&i=0> wrote:
>
> > Source code:
> >
>
> > @Contribute(JavaScriptStackSource.class)
> > public static void addMyStack(MappedConfiguration<String,
> > JavaScriptStack> configuration) {
> >     configuration.addInstance("react", ReactStack.class);
> > }
> >
> > @Contribute(JavaScriptStack.class)
> > @Core
> > public static void addAppModules(OrderedConfiguration<StackExtension>
> > configuration) {
> >     configuration.add("react", StackExtension.module("react"));
> > }
> >
>
> These look correct. ^^^
>
> > public class ReactStack implements JavaScriptStack {
> >     private final AssetSource assetSource;
> >
> >     public ReactStack(final AssetSource assetSource) {
> >         this.assetSource = assetSource;
> >     }
> >
> >     public List<Asset> getJavaScriptLibraries() {
> >         List<Asset> ret = new ArrayList<>();
> >         ret.add(assetSource.getClasspathAsset("/META-INF/
> > assets/react.min.js"));
> >         return ret;
> >     }
> >
> >     @Override
> >     public List<String> getModules() {
> >         List<String> ret = new ArrayList<>();
> >         ret.add("react");
> >         return ret;
> >     }
> >
>
> I believe your error was having the getModules() method above return a list
> with 'react'. According to its JavaDoc, getModules() must return the
> modules on which this stack depends. It doesn't actually depend on the
> 'react' module. Please try having that method return an empty List and tell
> us what happens.
>
> You may also need to move react.min.js to
> /META-INF/modules/react/react.min.js.
>
> ________________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/Contribute-requirejs-config-paths-to-ModuleManager-
> tp5733721p5733729.html
> To unsubscribe from mailto:users@tapestry.apache.org Mailing List
> Archives, http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=
> 2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4.
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%
> 21nabble%3Aemail.naml&base=nabble.naml.namespaces.
> BasicNamespace-nabble.view.web.template.NabbleNamespace-
> nabble.view.web.template.NodeNamespace&breadcrumbs=
> notify_subscribers%21nabble%3Aemail.naml-instant_emails%
> 21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml
>

RE: Contribute requirejs.config.paths to ModuleManager

Posted by Svein-Erik Løken <sv...@jacilla.no>.
Got this error message (very informative):

org.apache.tapestry5.ioc.util.UnknownValueException
Unable to create a client URL for classpath resource META-INF/modules/react/react.min.js: The resource path was not within an aliased path.
availableValues
Aliased paths:
• META-INF/assets
• META-INF/assets/core
• META-INF/assets/democore
• com/demo/core
• com/demo/module1
• com/demo/module1
• org/apache/tapestry5
• org/apache/tapestry5



Tried other locations:

public class ReactStack implements JavaScriptStack {
    private final AssetSource assetSource;

    public ReactStack(final AssetSource assetSource) {
        this.assetSource = assetSource;
    }

    public List<Asset> getJavaScriptLibraries() {
        List<Asset> ret = new ArrayList<>();
//        ret.add(assetSource.getClasspathAsset("/META-INF/modules/react/react.min.js"));
//        ret.add(assetSource.getClasspathAsset("/META-INF/assets/react/react.min.js"));
//        ret.add(assetSource.getClasspathAsset("/META-INF/assets/react/react.js"));
//        ret.add(assetSource.getClasspathAsset("/META-INF/assets/react.min.js"));
        ret.add(assetSource.getClasspathAsset("/META-INF/assets/react.js"));
        return ret;
    }


Still getting:
Loading 1 libraries
Loading library /assets/meta/z94ea83c9/react.js
Executing 3 inits
Loaded module bootstrap/collapse
GET http://localhost:9876/modules.gz/react.js 404 (No module for path 'react.js'.)

Very strange that the virtual link does not work! 

S-E
 

From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List Archives] [mailto:ml+s1045711n5733729h80@n5.nabble.com] 
Sent: mandag 27. november 2017 13:32
To: Svein-Erik Løken <sv...@jacilla.no>
Subject: Re: Contribute requirejs.config.paths to ModuleManager

On Sun, Nov 26, 2017 at 10:40 AM, Svein-Erik Løken </user/SendEmail.jtp?type=node&node=5733729&i=0> wrote: 

> Source code: 
> 

> @Contribute(JavaScriptStackSource.class) 
> public static void addMyStack(MappedConfiguration<String, 
> JavaScriptStack> configuration) { 
>     configuration.addInstance("react", ReactStack.class); 
> } 
> 
> @Contribute(JavaScriptStack.class) 
> @Core 
> public static void addAppModules(OrderedConfiguration<StackExtension> 
> configuration) { 
>     configuration.add("react", StackExtension.module("react")); 
> } 
> 

These look correct. ^^^ 

> public class ReactStack implements JavaScriptStack { 
>     private final AssetSource assetSource; 
> 
>     public ReactStack(final AssetSource assetSource) { 
>         this.assetSource = assetSource; 
>     } 
> 
>     public List<Asset> getJavaScriptLibraries() { 
>         List<Asset> ret = new ArrayList<>(); 
>         ret.add(assetSource.getClasspathAsset("/META-INF/ 
> assets/react.min.js")); 
>         return ret; 
>     } 
> 
>     @Override 
>     public List<String> getModules() { 
>         List<String> ret = new ArrayList<>(); 
>         ret.add("react"); 
>         return ret; 
>     } 
> 

I believe your error was having the getModules() method above return a list 
with 'react'. According to its JavaDoc, getModules() must return the 
modules on which this stack depends. It doesn't actually depend on the 
'react' module. Please try having that method return an empty List and tell 
us what happens. 

You may also need to move react.min.js to 
/META-INF/modules/react/react.min.js. 

________________________________________
If you reply to this email, your message will be added to the discussion below:
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Contribute-requirejs-config-paths-to-ModuleManager-tp5733721p5733729.html 
To unsubscribe from mailto:users@tapestry.apache.org Mailing List Archives, http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4.
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml 

Re: Contribute requirejs.config.paths to ModuleManager

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Sun, Nov 26, 2017 at 10:40 AM, Svein-Erik Løken <sv...@jacilla.no> wrote:

> Source code:
>

> @Contribute(JavaScriptStackSource.class)
> public static void addMyStack(MappedConfiguration<String,
> JavaScriptStack> configuration) {
>     configuration.addInstance("react", ReactStack.class);
> }
>
> @Contribute(JavaScriptStack.class)
> @Core
> public static void addAppModules(OrderedConfiguration<StackExtension>
> configuration) {
>     configuration.add("react", StackExtension.module("react"));
> }
>

These look correct. ^^^


> public class ReactStack implements JavaScriptStack {
>     private final AssetSource assetSource;
>
>     public ReactStack(final AssetSource assetSource) {
>         this.assetSource = assetSource;
>     }
>
>     public List<Asset> getJavaScriptLibraries() {
>         List<Asset> ret = new ArrayList<>();
>         ret.add(assetSource.getClasspathAsset("/META-INF/
> assets/react.min.js"));
>         return ret;
>     }
>
>     @Override
>     public List<String> getModules() {
>         List<String> ret = new ArrayList<>();
>         ret.add("react");
>         return ret;
>     }
>

I believe your error was having the getModules() method above return a list
with 'react'. According to its JavaDoc, getModules() must return the
modules on which this stack depends. It doesn't actually depend on the
'react' module. Please try having that method return an empty List and tell
us what happens.

You may also need to move react.min.js to
/META-INF/modules/react/react.min.js.

RE: Contribute requirejs.config.paths to ModuleManager

Posted by Svein-Erik Løken <sv...@jacilla.no>.
I think the JavaScriptStack is the correct way!



I cannot make it work! I thought my code would create a link from module "react" to /assets/meta/z94ea83c9/react.min.js.



JS: define(["react"], function (react) {

and/or

@AfterRender
void testReactModuleLoading() {
    javaScriptSupport.require("react");
}

Log:

Loading 1 libraries

Loading library /assets/meta/z94ea83c9/react.min.js

Executing 3 inits

Loaded module bootstrap/collapse

GET http://localhost:9876/modules.gz/react.js 404 (No module for path 'react.js'.)



Source code:

@Contribute(JavaScriptStackSource.class)
public static void addMyStack(MappedConfiguration<String, JavaScriptStack> configuration) {
    configuration.addInstance("react", ReactStack.class);
}

@Contribute(JavaScriptStack.class)
@Core
public static void addAppModules(OrderedConfiguration<StackExtension> configuration) {
    configuration.add("react", StackExtension.module("react"));
}



public class ReactStack implements JavaScriptStack {
    private final AssetSource assetSource;

    public ReactStack(final AssetSource assetSource) {
        this.assetSource = assetSource;
    }

    public List<Asset> getJavaScriptLibraries() {
        List<Asset> ret = new ArrayList<>();
        ret.add(assetSource.getClasspathAsset("/META-INF/assets/react.min.js"));
        return ret;
    }

    @Override
    public List<String> getModules() {
        List<String> ret = new ArrayList<>();
        ret.add("react");
        return ret;
    }







From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List Archives] [mailto:ml+s1045711n5733724h25@n5.nabble.com]
Sent: fredag 24. november 2017 22:03
To: Svein-Erik Løken <sv...@jacilla.no>
Subject: Re: Contribute requirejs.config.paths to ModuleManager

I'm wondering here whether the best approach is the one you've chosen here,
usually used when you're dealing with non-AMD-module-compliant JavaScript
libraries, while React is compliant. I believe you should create a
JavaScriptStack with the React .js files, contribute it to the
JavaScriptStackSource service, then add your module to the core one (i.e.
the one included in all pages). See
https://tapestry.apache.org/javascript-modules.html, section Aggregating
Modules:

Because Tapestry is open, it is possible to contribute modules even into
the *core* JavaScript stack.  This is done using your application's module:
@Contribute(JavaScriptStack.class)
@Core
public static void addAppModules(OrderedConfiguration<StackExtension>
configuration) {
    configuration.add("tree-viewer", StackExtension.module("tree-viewer"));
    configuration.add("app-utils", StackExtension.module("app-utils"));
}
So yes, Tapestry already supports what you want. :)


On Fri, Nov 24, 2017 at 3:20 PM, Svein-Erik Løken <[hidden email]</user/SendEmail.jtp?type=node&node=5733724&i=0>> wrote:

> React can in theory be used in all pages (globally). It will be like a
> core library for me, like jquery, underscore, bootstrap, etc. In TypeScript
> I am using
> "compilerOptions": {
>     "module": "amd".
>
> I have written a service:
> @Override
> public void appendToModulePath(JSONObject cfg) {
>     javaScriptSupport.addModuleConfigurationCallback(configuration -> {
>         if (!configuration.has("paths")) {
>             configuration.put("paths", cfg);
>         } else {
>             configuration.getJSONObject("paths").putAll(cfg.toMap());
>         }
>         return configuration;
>     });
> }
>
> I am now calling this in my global <html t:type="layout", and adding paths
> like “leaflet”:”leaflet-src” on pages with a map.
>
> Setting requirejs.config.paths globally should not load anything until
> loaded by require.
> E.g: JS from a transpiled TypeScript with React: define(["require",
> "exports", "react", "react-dom"], function (require, exports, React,
> ReactDOM) {
>
> I can try the Mixin technique, but still think Tapestry should have a way
> of contribute requirejs.config.paths.  You have a nice way contribute
> requirejs.config.shim which maybe could be modified to also accept paths.
> To support modern JS frameworks I think setting requirejs.config.paths in a
> nice way globally should be implemented.
>
> S-E
>
> From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List
> Archives] [mailto:[hidden email]</user/SendEmail.jtp?type=node&node=5733724&i=1>]
> Sent: fredag 24. november 2017 17.02
> To: Svein-Erik Løken <[hidden email]</user/SendEmail.jtp?type=node&node=5733724&i=2>>
> Subject: Re: Contribute requirejs.config.paths to ModuleManager
>
> On Fri, Nov 24, 2017 at 11:13 AM, Svein-Erik Løken <[hidden
> email]</user/SendEmail.jtp?type=node&node=5733722&i=0>> wrote:
>
> Hello!
>
> Trying to use TypeScript and React with Tapestry:
> >
> > In TypeScript I need to use:  import * as React from "react";
> >
> > I would like to load react: react.min, so I have to set paths: {...}
> >
> > The configuration should be set at startup, but I cannot figure how to do
> > it. I can set requirejs.config.shim, but not paths.
> >
>
> Are you using React in all pages or just some of them?
>
> >
> > I tried to load it with @Contribute(ModuleManager.class), but could not
> > figure out how.
> >
> > PSEUDO CODE
> > @Contribute(ModuleManager.class)
> > public static void setupMyBaseModules(MappedConfiguration<String,
> Object>
> > configuration) {
> >     JSONObject pathsConfig = new JSONObject(
> >             "react", "react.min",
> >             "react-dom", "react-dom.min"
> >     );
> >     AMDResourceConfiguration paths = new AMDResourceConfiguration("
> paths",
> > pathsConfig);
> >     configuration.add(null, new JavaScriptModuleConfiguration(paths));
> > }
> >
>
> MappedConfiguration, as far as I can remember, doesn't accept null as the
> contribution id. Even if it does, it's a bad idea.
>
> > Tried to load it this way:
> > @Startup
> > public void registerToClearPlasticProxyFactoryOnInvalidation(
> JavaScriptSupport
> > javaScriptSupport) {
> >     ModuleConfigurationCallback callback = new
> >             ModuleConfigurationCallback() {
> >                 @Override
> >                 public JSONObject configure(JSONObject configuration) {
> >                     configuration.put("paths",
> >                             new JSONObject(
> >                                     "react", "react.min",
> >                                     "react-dom", "react-dom.min"
> >                             ));
> >                     return configuration;
> >                 }
> >             };
> >     javaScriptSupport.addModuleConfigurationCallback(callback);
> > }
>
>
>
> > [ERROR] ioc.Registry org.apache.tapestry5.ioc.util.
> UnknownValueException:
> > No object of type org.apache.tapestry5.services.
> javascript.JavaScriptSupport
> > is available from the Environment.
>
>
> I'm afraid this isn't the correct way of using
> JavaScriptSupport.addModuleConfigurationCallback(). It should be used
> while
> rendering a page or handling an event. The way you did it above, you're
> trying to add JavaScript at application startup. You need to do this in
> page or component classes.
>
>
> > Now I am loading the configuration in @SetupRender, but it should be
> > loaded globally.
> >
>
> Define "globally", please. All pages, including error ones? Most pages? The
> better way of doing this is moving this code to a mixin and apply it to the
> pages where you need React. If you want it in all pages, you can contribute
> a ComponentClassTransformWorker2 to the service with the same name which
> applies the mixin to all pages. See
> MutableComponentModel.addMixinClassName().
>
> --
> Thiago
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/Contribute-requirejs-config-paths-to-ModuleManager-
> tp5733721p5733722.html
> To unsubscribe from [hidden email]</user/SendEmail.jtp?type=node&node=5733724&i=3><mailto:
> [hidden email]</user/SendEmail.jtp?type=node&node=5733724&i=4>> Mailing List Archives, click here<
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=
> 2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4>.
> NAML<http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%
> 21nabble%3Aemail.naml&base=nabble.naml.namespaces.
> BasicNamespace-nabble.view.web.template.NabbleNamespace-
> nabble.view.web.template.NodeNamespace&breadcrumbs=
> notify_subscribers%21nabble%3Aemail.naml-instant_emails%
> 21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>



--
Thiago

________________________________
If you reply to this email, your message will be added to the discussion below:
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Contribute-requirejs-config-paths-to-ModuleManager-tp5733721p5733724.html
To unsubscribe from users@tapestry.apache.org<ma...@tapestry.apache.org> Mailing List Archives, click here<http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4>.
NAML<http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>

Re: Contribute requirejs.config.paths to ModuleManager

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
I'm wondering here whether the best approach is the one you've chosen here,
usually used when you're dealing with non-AMD-module-compliant JavaScript
libraries, while React is compliant. I believe you should create a
JavaScriptStack with the React .js files, contribute it to the
JavaScriptStackSource service, then add your module to the core one (i.e.
the one included in all pages). See
https://tapestry.apache.org/javascript-modules.html, section Aggregating
Modules:

Because Tapestry is open, it is possible to contribute modules even into
the *core* JavaScript stack.  This is done using your application's module:
@Contribute(JavaScriptStack.class)
@Core
public static void addAppModules(OrderedConfiguration<StackExtension>
configuration) {
    configuration.add("tree-viewer", StackExtension.module("tree-viewer"));
    configuration.add("app-utils", StackExtension.module("app-utils"));
}
So yes, Tapestry already supports what you want. :)


On Fri, Nov 24, 2017 at 3:20 PM, Svein-Erik Løken <sv...@jacilla.no> wrote:

> React can in theory be used in all pages (globally). It will be like a
> core library for me, like jquery, underscore, bootstrap, etc. In TypeScript
> I am using
> "compilerOptions": {
>     "module": "amd".
>
> I have written a service:
> @Override
> public void appendToModulePath(JSONObject cfg) {
>     javaScriptSupport.addModuleConfigurationCallback(configuration -> {
>         if (!configuration.has("paths")) {
>             configuration.put("paths", cfg);
>         } else {
>             configuration.getJSONObject("paths").putAll(cfg.toMap());
>         }
>         return configuration;
>     });
> }
>
> I am now calling this in my global <html t:type="layout", and adding paths
> like “leaflet”:”leaflet-src” on pages with a map.
>
> Setting requirejs.config.paths globally should not load anything until
> loaded by require.
> E.g: JS from a transpiled TypeScript with React: define(["require",
> "exports", "react", "react-dom"], function (require, exports, React,
> ReactDOM) {
>
> I can try the Mixin technique, but still think Tapestry should have a way
> of contribute requirejs.config.paths.  You have a nice way contribute
> requirejs.config.shim which maybe could be modified to also accept paths.
> To support modern JS frameworks I think setting requirejs.config.paths in a
> nice way globally should be implemented.
>
> S-E
>
> From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List
> Archives] [mailto:ml+s1045711n5733722h63@n5.nabble.com]
> Sent: fredag 24. november 2017 17.02
> To: Svein-Erik Løken <sv...@jacilla.no>
> Subject: Re: Contribute requirejs.config.paths to ModuleManager
>
> On Fri, Nov 24, 2017 at 11:13 AM, Svein-Erik Løken <[hidden
> email]</user/SendEmail.jtp?type=node&node=5733722&i=0>> wrote:
>
> Hello!
>
> Trying to use TypeScript and React with Tapestry:
> >
> > In TypeScript I need to use:  import * as React from "react";
> >
> > I would like to load react: react.min, so I have to set paths: {...}
> >
> > The configuration should be set at startup, but I cannot figure how to do
> > it. I can set requirejs.config.shim, but not paths.
> >
>
> Are you using React in all pages or just some of them?
>
> >
> > I tried to load it with @Contribute(ModuleManager.class), but could not
> > figure out how.
> >
> > PSEUDO CODE
> > @Contribute(ModuleManager.class)
> > public static void setupMyBaseModules(MappedConfiguration<String,
> Object>
> > configuration) {
> >     JSONObject pathsConfig = new JSONObject(
> >             "react", "react.min",
> >             "react-dom", "react-dom.min"
> >     );
> >     AMDResourceConfiguration paths = new AMDResourceConfiguration("
> paths",
> > pathsConfig);
> >     configuration.add(null, new JavaScriptModuleConfiguration(paths));
> > }
> >
>
> MappedConfiguration, as far as I can remember, doesn't accept null as the
> contribution id. Even if it does, it's a bad idea.
>
> > Tried to load it this way:
> > @Startup
> > public void registerToClearPlasticProxyFactoryOnInvalidation(
> JavaScriptSupport
> > javaScriptSupport) {
> >     ModuleConfigurationCallback callback = new
> >             ModuleConfigurationCallback() {
> >                 @Override
> >                 public JSONObject configure(JSONObject configuration) {
> >                     configuration.put("paths",
> >                             new JSONObject(
> >                                     "react", "react.min",
> >                                     "react-dom", "react-dom.min"
> >                             ));
> >                     return configuration;
> >                 }
> >             };
> >     javaScriptSupport.addModuleConfigurationCallback(callback);
> > }
>
>
>
> > [ERROR] ioc.Registry org.apache.tapestry5.ioc.util.
> UnknownValueException:
> > No object of type org.apache.tapestry5.services.
> javascript.JavaScriptSupport
> > is available from the Environment.
>
>
> I'm afraid this isn't the correct way of using
> JavaScriptSupport.addModuleConfigurationCallback(). It should be used
> while
> rendering a page or handling an event. The way you did it above, you're
> trying to add JavaScript at application startup. You need to do this in
> page or component classes.
>
>
> > Now I am loading the configuration in @SetupRender, but it should be
> > loaded globally.
> >
>
> Define "globally", please. All pages, including error ones? Most pages? The
> better way of doing this is moving this code to a mixin and apply it to the
> pages where you need React. If you want it in all pages, you can contribute
> a ComponentClassTransformWorker2 to the service with the same name which
> applies the mixin to all pages. See
> MutableComponentModel.addMixinClassName().
>
> --
> Thiago
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/Contribute-requirejs-config-paths-to-ModuleManager-
> tp5733721p5733722.html
> To unsubscribe from users@tapestry.apache.org<mailto:
> users@tapestry.apache.org> Mailing List Archives, click here<
> http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=
> 2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4>.
> NAML<http://apache-tapestry-mailing-list-archives.1045711.
> n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%
> 21nabble%3Aemail.naml&base=nabble.naml.namespaces.
> BasicNamespace-nabble.view.web.template.NabbleNamespace-
> nabble.view.web.template.NodeNamespace&breadcrumbs=
> notify_subscribers%21nabble%3Aemail.naml-instant_emails%
> 21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>



-- 
Thiago

RE: Contribute requirejs.config.paths to ModuleManager

Posted by Svein-Erik Løken <sv...@jacilla.no>.
React can in theory be used in all pages (globally). It will be like a core library for me, like jquery, underscore, bootstrap, etc. In TypeScript I am using
"compilerOptions": {
    "module": "amd".

I have written a service:
@Override
public void appendToModulePath(JSONObject cfg) {
    javaScriptSupport.addModuleConfigurationCallback(configuration -> {
        if (!configuration.has("paths")) {
            configuration.put("paths", cfg);
        } else {
            configuration.getJSONObject("paths").putAll(cfg.toMap());
        }
        return configuration;
    });
}

I am now calling this in my global <html t:type="layout", and adding paths like “leaflet”:”leaflet-src” on pages with a map.

Setting requirejs.config.paths globally should not load anything until loaded by require.
E.g: JS from a transpiled TypeScript with React: define(["require", "exports", "react", "react-dom"], function (require, exports, React, ReactDOM) {

I can try the Mixin technique, but still think Tapestry should have a way of contribute requirejs.config.paths.  You have a nice way contribute requirejs.config.shim which maybe could be modified to also accept paths. To support modern JS frameworks I think setting requirejs.config.paths in a nice way globally should be implemented.

S-E

From: Thiago H de Paula Figueiredo [via Apache Tapestry Mailing List Archives] [mailto:ml+s1045711n5733722h63@n5.nabble.com]
Sent: fredag 24. november 2017 17.02
To: Svein-Erik Løken <sv...@jacilla.no>
Subject: Re: Contribute requirejs.config.paths to ModuleManager

On Fri, Nov 24, 2017 at 11:13 AM, Svein-Erik Løken <[hidden email]</user/SendEmail.jtp?type=node&node=5733722&i=0>> wrote:

Hello!

Trying to use TypeScript and React with Tapestry:
>
> In TypeScript I need to use:  import * as React from "react";
>
> I would like to load react: react.min, so I have to set paths: {...}
>
> The configuration should be set at startup, but I cannot figure how to do
> it. I can set requirejs.config.shim, but not paths.
>

Are you using React in all pages or just some of them?

>
> I tried to load it with @Contribute(ModuleManager.class), but could not
> figure out how.
>
> PSEUDO CODE
> @Contribute(ModuleManager.class)
> public static void setupMyBaseModules(MappedConfiguration<String, Object>
> configuration) {
>     JSONObject pathsConfig = new JSONObject(
>             "react", "react.min",
>             "react-dom", "react-dom.min"
>     );
>     AMDResourceConfiguration paths = new AMDResourceConfiguration("paths",
> pathsConfig);
>     configuration.add(null, new JavaScriptModuleConfiguration(paths));
> }
>

MappedConfiguration, as far as I can remember, doesn't accept null as the
contribution id. Even if it does, it's a bad idea.

> Tried to load it this way:
> @Startup
> public void registerToClearPlasticProxyFactoryOnInvalidation(JavaScriptSupport
> javaScriptSupport) {
>     ModuleConfigurationCallback callback = new
>             ModuleConfigurationCallback() {
>                 @Override
>                 public JSONObject configure(JSONObject configuration) {
>                     configuration.put("paths",
>                             new JSONObject(
>                                     "react", "react.min",
>                                     "react-dom", "react-dom.min"
>                             ));
>                     return configuration;
>                 }
>             };
>     javaScriptSupport.addModuleConfigurationCallback(callback);
> }



> [ERROR] ioc.Registry org.apache.tapestry5.ioc.util.UnknownValueException:
> No object of type org.apache.tapestry5.services.javascript.JavaScriptSupport
> is available from the Environment.


I'm afraid this isn't the correct way of using
JavaScriptSupport.addModuleConfigurationCallback(). It should be used while
rendering a page or handling an event. The way you did it above, you're
trying to add JavaScript at application startup. You need to do this in
page or component classes.


> Now I am loading the configuration in @SetupRender, but it should be
> loaded globally.
>

Define "globally", please. All pages, including error ones? Most pages? The
better way of doing this is moving this code to a mixin and apply it to the
pages where you need React. If you want it in all pages, you can contribute
a ComponentClassTransformWorker2 to the service with the same name which
applies the mixin to all pages. See
MutableComponentModel.addMixinClassName().

--
Thiago

________________________________
If you reply to this email, your message will be added to the discussion below:
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Contribute-requirejs-config-paths-to-ModuleManager-tp5733721p5733722.html
To unsubscribe from users@tapestry.apache.org<ma...@tapestry.apache.org> Mailing List Archives, click here<http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=2375125&code=c3ZlaW5AamFjaWxsYS5ub3wyMzc1MTI1fC0xNTM4NzY2ODg4>.
NAML<http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>

Re: Contribute requirejs.config.paths to ModuleManager

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Fri, Nov 24, 2017 at 11:13 AM, Svein-Erik Løken <sv...@jacilla.no> wrote:

Hello!

Trying to use TypeScript and React with Tapestry:
>
> In TypeScript I need to use:  import * as React from "react";
>
> I would like to load react: react.min, so I have to set paths: {...}
>
> The configuration should be set at startup, but I cannot figure how to do
> it. I can set requirejs.config.shim, but not paths.
>

Are you using React in all pages or just some of them?


>
> I tried to load it with @Contribute(ModuleManager.class), but could not
> figure out how.
>
> PSEUDO CODE
> @Contribute(ModuleManager.class)
> public static void setupMyBaseModules(MappedConfiguration<String, Object>
> configuration) {
>     JSONObject pathsConfig = new JSONObject(
>             "react", "react.min",
>             "react-dom", "react-dom.min"
>     );
>     AMDResourceConfiguration paths = new AMDResourceConfiguration("paths",
> pathsConfig);
>     configuration.add(null, new JavaScriptModuleConfiguration(paths));
> }
>

MappedConfiguration, as far as I can remember, doesn't accept null as the
contribution id. Even if it does, it's a bad idea.


> Tried to load it this way:
> @Startup
> public void registerToClearPlasticProxyFactoryOnInvalidation(JavaScriptSupport
> javaScriptSupport) {
>     ModuleConfigurationCallback callback = new
>             ModuleConfigurationCallback() {
>                 @Override
>                 public JSONObject configure(JSONObject configuration) {
>                     configuration.put("paths",
>                             new JSONObject(
>                                     "react", "react.min",
>                                     "react-dom", "react-dom.min"
>                             ));
>                     return configuration;
>                 }
>             };
>     javaScriptSupport.addModuleConfigurationCallback(callback);
> }



> [ERROR] ioc.Registry org.apache.tapestry5.ioc.util.UnknownValueException:
> No object of type org.apache.tapestry5.services.javascript.JavaScriptSupport
> is available from the Environment.


I'm afraid this isn't the correct way of using
JavaScriptSupport.addModuleConfigurationCallback(). It should be used while
rendering a page or handling an event. The way you did it above, you're
trying to add JavaScript at application startup. You need to do this in
page or component classes.


> Now I am loading the configuration in @SetupRender, but it should be
> loaded globally.
>

Define "globally", please. All pages, including error ones? Most pages? The
better way of doing this is moving this code to a mixin and apply it to the
pages where you need React. If you want it in all pages, you can contribute
a ComponentClassTransformWorker2 to the service with the same name which
applies the mixin to all pages. See
MutableComponentModel.addMixinClassName().

-- 
Thiago