Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundling support for Require.js #86

Open
HRasch opened this issue Nov 24, 2016 · 7 comments
Open

Bundling support for Require.js #86

HRasch opened this issue Nov 24, 2016 · 7 comments

Comments

@HRasch
Copy link

HRasch commented Nov 24, 2016

Hello,
we are currently developing an ecommerce application where requireJS.Net is included. No I try to bundle my solution, but I'm struggle with 3 problems:

  1. I can not use the autoBundle-Feature, because I have the following structure in my Project

-> app
--> assets
---> controllers
---> js
---> libs
The reason for this structure is because some included libs like bootstrap contain javascript, css, fonts, aso. I don't wanna split this external libs. But it's not possible to override the baseUrl for the autoBundle-functionality.

  1. The second and more import point is, that no bundle-config is passed to require.js. The autoBundle-functionality would build up some bundles, but require.js need the information what bundle to load if a module is required. If I understand it correctly, this is normally configured through the bundle-section in require.js. RequireJS.Net do not support this section.

  2. My last point is that it would be great to have an option to build an js-file with the config, because if it's getting complex, it could be cached on client-side and is not included in each page.

@aquamoth
Copy link
Collaborator

Its already been three months for this post, but in case it still matters to you:

  1. I believe the sample project RequireJSNet.Examples illustrates this situation in url /home/entrypoint. The required entrypoint is relocated to ~/App/. It is also bundled by the autobundler to /bundles/auto/entrypoint.js (which may be a bit hard to realize).

  2. When the compressor nuget package is installed it adds a build target in the project file which will bundle all dependencies according to RequireJS.json. It also creates RequireJS.overrides.json which contains all the information requirejs needs to use the bundles.

If the config option LoadOverrides = true is set in the Html.RenderRequireJsSetup` configuration, RequireJSDotNet will automatically include this information when requirejs loads. This makes it easy to debug without bundling and deploy to production with bundles.

  1. I'm interested in this myself. If you reaffirm your need for this I will see if I can make it happen anytime soon.

@HRasch
Copy link
Author

HRasch commented Feb 22, 2017 via email

@aquamoth
Copy link
Collaborator

aquamoth commented Feb 24, 2017 via email

@aquamoth
Copy link
Collaborator

I have created a working alpha regarding offlining the configuration into its own "file". The code is found under aquamoth/requirejsdotnet, branch httpmodule.

There is no documentation at the moment except the examples have been updated to use the new code.

There is a call in global.asax to register a new httproutehandler and the supported configurations. Then the setup call in the shared layout views are simplified a lot.

´/home/index´ illustrates how the new call is used while still inlining the config. ´/home/complex´ offlines the config using the httphandler while ´/home/entrypoint´ hasnt changed at all and still uses the original way of declaring the config in the view layout.

I'd really like any feedback on this before moving it into the main repo. Especially since there is one unfortunate breaking change; the call to determine locale now must get an HttpContext instead of an HtmlHelper...

Stefan; I want to talk to you about how we move this branch forward too.. Gitter-users anybody??

@HRasch
Copy link
Author

HRasch commented Feb 27, 2017

Ok, I reviewed your implementation a little bit and want you give some feedback.

Maybe we are loosing some focus on the sollution with this changes. We should remember that requirejs.net is a asp.net mvc wrapper around require.js to bring some very nice features:

  • Separation of JS / (Razor) Views
  • Localizable Resources
  • Bundling / Compression
  • Serializing Objects to the client (requireJsConfig)

what we don't like on the implementation:

  • Complex configuration directly rendered inside each page

Maybe I currently don't get the importance for the overrides, but if I would kick out Requirejs.Net and use require.js in it's native js-implementation, i would create two different configs, one including the bundles and the other without bundles for debugging. The compression-task would be done with r.

Require.js won't support localizable resources, passing the options or the detection, if a JS-File exists for my action.

On the other hand, the config file is a fixed ressource. No need for a distinct HttpHandler to resolve the configuration.

This is the reason, why I don't agree with this solution. Yes, it's easy to render the output of the configuration just to a httpHandler instead of the Page. But there are dependencies from the rendered page to this rendered content, like the requireJsConfig-options or ressources. Because of this, each page would have it's own handler-call, and the config cannot be read from the client-cache.

I think the configuration should be splitted to a clean require.config (and a second for overrides) and any page-dependent configuration should be rendered to the page (like the options, ressources..) or through a httphandler.

@HRasch HRasch closed this as completed Feb 27, 2017
@aquamoth
Copy link
Collaborator

I appreciate your input but maybe I dont fully grasp your critique;

Is an httphandler intrinsically wrong in your opinion, or is it foremost that it currently creates different urls for different pages?

I dont lightly break existing code, but what if we add a property "ignore-endpoint" that returns the same config-url for all pages with the same config?

Just to be clear; the httphandler supports caching with both last-modified header and etag so the config gets cached on the clients. After all that was the main goal...

I do agree the solution with an extra httphander adds a bit of complexity. Maybe we can compress to a file at compile time instead, if we get rid of the entrypoint requirement?

@aquamoth aquamoth reopened this Feb 27, 2017
@HRasch
Copy link
Author

HRasch commented Feb 27, 2017

In my opinion a HttpHandler should be used if non-static content that don't belong to the current (page) request should be transmitted to the client. There are some exceptions: The content has a different file-format than the main-request, uses a different infrastructure and is accessable in a restful kind of request, The same request should return the same response.

This in my mind, i wouldn't use an http handler for content that can be served in a static way. I think the "general" configuration is such a piece of static content. It can be saved in some javascript file like require.js does it natively.

So the question should not be "why not using an httphandler?", but "what are the benefits using an http-handler?".

Ok, our goal is to exclude the configuration part from the page. But what is about the data, that is page dependent? Is it really false to include it to the page? It's harder to pass some information, that belongs to one request to a second one, e.g. if u want to move the pageOptions to the httpHandler-Request.

I think a clean solution would introduce something like a proxy-call (to your http-handler) just for the configuration-settings. These configuration-settings should include the paths, shims, bundles, ... it has to return the bootstrapping-configuration for require.js. This makes sense, because we don't need a client-side part to read the configuration from json e.g. and bootstrap require.js.

All other content should stay in the page (options, locale, require for the endpoint) because it is page dependent content. Making an distinct request for page-dependent content is for me something like an anti-pattern.

@HRasch HRasch closed this as completed Feb 27, 2017
@HRasch HRasch reopened this Feb 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants