{"action":"created","issue":{"url":"https://api.github.com/repos/riganti/dotvvm/issues/271","repository_url":"https://api.github.com/repos/riganti/dotvvm","labels_url":"https://api.github.com/repos/riganti/dotvvm/issues/271/labels{/name}","comments_url":"https://api.github.com/repos/riganti/dotvvm/issues/271/comments","events_url":"https://api.github.com/repos/riganti/dotvvm/issues/271/events","html_url":"https://github.com/riganti/dotvvm/pull/271","id":191589357,"number":271,"title":"Refactored Resource Management","user":{"login":"exyi","id":7894687,"avatar_url":"https://avatars.githubusercontent.com/u/7894687?v=3","gravatar_id":"","url":"https://api.github.com/users/exyi","html_url":"https://github.com/exyi","followers_url":"https://api.github.com/users/exyi/followers","following_url":"https://api.github.com/users/exyi/following{/other_user}","gists_url":"https://api.github.com/users/exyi/gists{/gist_id}","starred_url":"https://api.github.com/users/exyi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/exyi/subscriptions","organizations_url":"https://api.github.com/users/exyi/orgs","repos_url":"https://api.github.com/users/exyi/repos","events_url":"https://api.github.com/users/exyi/events{/privacy}","received_events_url":"https://api.github.com/users/exyi/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-11-24T20:47:58Z","updated_at":"2016-11-29T11:28:32Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/riganti/dotvvm/pulls/271","html_url":"https://github.com/riganti/dotvvm/pull/271","diff_url":"https://github.com/riganti/dotvvm/pull/271.diff","patch_url":"https://github.com/riganti/dotvvm/pull/271.patch"},"body":"* Splitted resource type (script/style) and resource location type (local file, local embedded, remote url, local generated)\r\n* All local resources are served by one middleware and have nice & cache-friendly urls (`dotvvmResource/{hash}/{resourceName}`)\r\n* Supports loading fallback - when one location fails, then it can be loaded from another one\r\n* When url is remote and local location is also specified, `integrity` attribute is rendered ([see Subresource Integrity at MDN](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity))\r\n* Added few extensibility interfaces, so you can change the way how local resource are loaded - you can even automatically publish them to CDN or IPFS and load them from it ;)\r\n\r\n### Refactoring overview\r\n\r\nI have changed the resource hierarchy a bit:\r\n* `IResource` - just lighter interface than the old `ResourceBase` - has dependencies and Render method\r\n    - `ResourceBase` - abstract implementation of that interface\r\n* `ILinkResource : IResource` - adds GetLocations, used to obtain url or content from the resource\r\n    - `LinkResourceBase` - abstract implementation, has utility for rendering resource, integrity hashes\r\n* ScriptResource/StylesheetResource/NullResource - similar as before\r\n\r\nAnd added new class hierarchy for representing resource location:\r\n* `IResourceLocation` - GetUrl()\r\n* `ILocalResourceLocation : IResourceLocation` - LoadResource() - gets the content\r\n* `RemoteResourceLocation : IResourceLocation` - loaded from the url\r\n* `EmbededResourceLocation: ILocalResourceLocation` - loaded from assembly embeded resource\r\n* `LocalFileResourceLocation : ILocalResourceLocation` - loaded from file\r\n\r\n### Backwards compatibility\r\nThis is the main problem - the resource registration API is not compatible, but you only have to apply cosmetic changes to the code, no huge architecture refactoring is required on your side. Please let me know in comments how problematic would it be for you.\r\n\r\n### Content Security Policy?\r\nOriginally I wanted to add automatic CSP, but it is not that simple since resources can be loaded dynamically after postback. We could enforce that everything is loaded from our server and you can add your own locations on your own, but I'm not sure if it is good idea to enforce. Any ideas? @ridercz? Or another security guy?\r\n\r\n### Images?\r\nWe have nice cache-friendly content serving mechanism - what about to use it for images (video, audio and other content)? Maybe we could use special url that will point to the resource, like `resource://my-image` or `~~my-image` and it will be translated to resource's location.\r\n\r\nWe could also add virtual resources for entire image folder to avoid registration hell - could be used like `images:delete-icon.png`.\r\n\r\nDo you have any other use cases/ideas that the new resource system could support? Let me know until we release it :)\r\n\r\nEDIT:\r\nWe have currently a problem with source maps. They are looked up in relative path to the script file, so they will not be found in the /dotvvmResource/{hash} directory. Maybe we could turn off our resource middleware when run on debug."},"comment":{"url":"https://api.github.com/repos/riganti/dotvvm/issues/comments/263546497","html_url":"https://github.com/riganti/dotvvm/pull/271#issuecomment-263546497","issue_url":"https://api.github.com/repos/riganti/dotvvm/issues/271","id":263546497,"user":{"login":"djanosik","id":858180,"avatar_url":"https://avatars.githubusercontent.com/u/858180?v=3","gravatar_id":"","url":"https://api.github.com/users/djanosik","html_url":"https://github.com/djanosik","followers_url":"https://api.github.com/users/djanosik/followers","following_url":"https://api.github.com/users/djanosik/following{/other_user}","gists_url":"https://api.github.com/users/djanosik/gists{/gist_id}","starred_url":"https://api.github.com/users/djanosik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/djanosik/subscriptions","organizations_url":"https://api.github.com/users/djanosik/orgs","repos_url":"https://api.github.com/users/djanosik/repos","events_url":"https://api.github.com/users/djanosik/events{/privacy}","received_events_url":"https://api.github.com/users/djanosik/received_events","type":"User","site_admin":false},"created_at":"2016-11-29T11:28:32Z","updated_at":"2016-11-29T11:28:32Z","body":"I don't use DotVVM Resource Management anywhere, but I've tried to review the PR. Just a few notes:\r\n\r\n- I would prefer to have shortcuts for registering resources. Like `.RegisterLocalFileStylesheet(...)`. But we can surely leave this to users to implement whatever extensions they want.\r\n- I think it isn't a good idea to auto-generate the CSP header. There is an [NWebsec](https://github.com/NWebsec/NWebsec) middleware that makes it easy enough. It reminds me that DotVVM is not CSP compliant. I will file an issue.\r\n- I have no idea how to handle source maps. But I think you can't disable RM middleware in debug mode, because you still need it to load embedded resources.\r\n    - Can we accept that source maps will not work with embedded resources?\r\n    - Can we disable RM middleware just for local file resources?\r\n- I would like to see OOB solution for minification and bundling. It can live in other project.\r\n    - It should not handle precompilation of `less`, `TypeScript`, etc.\r\n    - It should bundle all resources into one file. Maybe we can skip this on HTTP/2.\r\n    - It should minify all not-yet-minified resources.\r\n    - It should not do anything in debug mode.\r\n\r\n"}}
{"actor":{"display_login":"djanosik"}}