This issue comes from a meeting @coorasse, @spaghetticode and I had to discuss the feasibility of supporting Webpacker into Solidus. These are the notes of the meeting. We want to use them to start a conversation and taste the general feelings around this.
Webpacker is the default JavaScript compiler in Rails 6.
Right now we totally rely on Sprockets for JavaScript compilation. Do we want to make any effort to support Webpacker as well? Of cource it would be optional, so we don't break existing store and leave users the possibility to chose what they prefer to use.
From https://github.com/rails/webpacker:
It coexists with the asset pipeline, as the primary purpose for webpack is app-like JavaScript, not images, CSS, or even JavaScript Sprinkles (that all continues to live in app/assets).
It's the JavaScript compiler, not images, CSS, fonts one. We'd still need Sprockets for the other things.
Although some solution is started to be presented, in this issue on Webpacker there is still a lot of confusion, and there's no a clear path on how to use Webpacker in combination with JavaScript files served by a Rails engine.
Also, this guide has been published but it's not super clear how it would work with Solidus (and its extensions).
We think that since we would still need Sprockets for other assets, there could not be a lot of value supporting support Webpacker here.
If we want, we could start preparing things by removing all js.erb files that would be an issue with Webpacker, and generally, are probably not a good practice. Still not sure how it works with js views.
Solidus frontend is meant to be replaced.
That said, every store can already easily install Webpacker on their frontends and take care of the rest without too much constraint from Solidus.
Given for granted that we are ok leaving Sprockets on the backend, we'll only talk about frontend related stuff here.
This is complicated. We have extensions that inject JavaScript code into the frontend application.js manifest. This is done in the extensions' install script.
If Webpacker is being used on the frontend this is useless, if not dangerous. We should find a way to don't copy those files if Webpacker is used.
An initial idea could be adding a Spree::Config.webpacker.frontend_enabled? in solidus_core that let us understand from the extension if Webpacker is being used and if we need to append the require in the manifest.
At that point, JavaScript files should be manually copied into the application frontend and being included into the Webpacker folder structure. This is far from an ideal solution but we can't see any other way to work around this.
Everyone feedback welcome!
This issue can't go ahead without the community. Do someone else have experience or thoughts about this?
Usually webpack is used together with JS frameworks such as Vue, React and Angular.
These frameworks are created to make SPA pages that use XMLHTTPREQUEST asynchronous calls using the api fetch or the old AJAX.
But how do you get a front end that consumes a solidus API if solidus only allows you to use the API if you have an administrator user token?
@CharlyJazz While I do understand your concerns, we try to keep issues apart from each other unless they're closely related, and I don't think that's the case here.
It鈥檚 worth nothing that whilst it appears we have a choice right now, Webpack will be the default for compiling JS in Rails 6 - https://github.com/rails/rails/pull/33079
I dont think we should swim up the stream here. Lets just go webpack and call it a day. Or lets just drop the spree_frontend altogether! I have a working graphql imple already!
I'd also like to voice my support for this. Without webpack, working on the solidus frontends, the admin panel or the storefront, is an unfamiliar experience for many JS devs. Webpack is the standard right now and adopting it will help Solidus get more frontend focused contributors. Additionally, it can open the door for other javascript frameworks such as React and Vue.
Greetings!
Webpacker does a stand up job at incorporating CSS and images, so I would suggest that future ideas try and reach for a solution that uses Webpacker for everything.
I propose that in order to keep Solidus backwards compatible, that we extract all the JS elements into node as the 2nd part in a 2 part install ( the first being bundle). And the Sprocket based JS could be ignored.
Admittedly I am not very well versed in Solidus yet, so do let me know if you see any unforeseeable icebergs, and if the Solidus team wouldn't mind seeing this as a viable PR..
Webpacker/Webpack is great for application code and should not be used by gems because of complicated developer experience unless you are publishing it to NPM but in that case rollup would be much better to publish JS packages: https://github.com/rails/rails/pull/32721.
For gem level frontend code, I think it's good to stick with Sprockets since everything just works.
It's a difficult one but given the complexity of using tools like Webpack at gem level it makes sense to go with something simple that works for everyone. In the end, no one will use the exact storefront implementation as in demo.
@gauravtiwari thanks for your insights here. I agree and our company started working on a new way to handle the storefronts: several super basic implementations a new store can install by copying files into their own application instead of using a gem. The first version is here: https://github.com/nebulab/solidus_starter_frontend/ and it's a remake of the current frontend that should work with sprockets as well. We are also starting to work on a new starter kit with Webpack, React with Next.js consuming with the new GraphQL API.
Thanks @kennyadsl
The starter kit looks great and the approach makes sense 馃憤 regarding components inside Rails, perhaps: https://github.com/github/view_component would be much better instead of using plain .erb partials.
ViewComponent is supported natively in Rails 6.1, and compatible with Rails 5.0+ via an included monkey patch.
See: https://github.com/github/view_component#sidecar-assets
Yes, there's already an issue to refactor using view components. Thanks!
I don't know if this can be useful here but for an Active Admin plugin I'm adding Webpacker support in this way: webpacker support.
package.json in the gem with the NPM metadata;index.js to require the JS/SCSS resources;Then for the installation the users will have to:
yarn add pointing directly to the GH repo (in this way I avoid maintaining the NPM package 馃槄);@blocknotes having both a gem and an NPM package (to always keep in sync) is a possible approach to support Webpcker in Solidus. Anyway, taking this route we'd break all existing extensions that are still relying on Sprockets to inject code in the host application.
@blocknotes having both a gem and an NPM package (to always keep in sync) is a possible approach to support Webpcker in Solidus. Anyway, taking this route we'd break all existing extensions that are still relying on Sprockets to inject code in the host application.
Why should they break?
My plugin is using Sprockets as default but it can be also included using Webpacker.
I think that they'll break if they use some internal namespace/functions released as NPM package by Solidus (e.g. the Spree.routes object) and tried to be accessed in the Sprockets context by the extensions code.
Most helpful comment
I dont think we should swim up the stream here. Lets just go webpack and call it a day. Or lets just drop the spree_frontend altogether! I have a working graphql imple already!