-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Add option to have css/images managed through webpack #109
Comments
Happy to see a PR explore option #2 👍
…On Thu, Feb 23, 2017 at 8:30 PM, Daniel Leavitt ***@***.***> wrote:
I think it would be useful to have an additional generator that supports
*all* FE assets being managed through Webpack. I'd love to gauge interest
and get feedback before I start on a PR.
Background:
As far as I know there, are two basic options for managing images/css/etc
in a webpack + rails app.
*Option 1:* Manage Javascript through Webpack and everything else through
Sprockets.
This is only option currently supported out of the box.
- *Advantages:* Easy to set up, legacy app friendly, easy to reference
images, etc. from erb.
- *Disadvantages:* Still clunky (as noted in README). Still no good
system for managing vendor CSS dependencies. Doesn't make CSS a first class
citizen of the front end app, which means no loading css from node_modules
and no support for modular CSS approaches (used by Vue, Material Design,
etc.)
*Option 2:* Manage *all* assets through Webpack, remove Sprockets.
This involves adding some loaders to webpacker (probably file-loader and
sass/css/style loaders) as well as a manifest generator that Rails can use
to get properly fingerprinted paths in erb and such.
- *Advantages:*
- Allows easy use of Vue, CSS modules, and lots of other things
that frontend developers dig.
- More broadly, this is the way most frontend apps are structured
nowadays. Tutorials and example apps will work out-of-the-box with Rails.
- Removes Sprockets entirely for apps that don't need it, no more
need for two separate asset pipelines. No need to mess with bower or
https://rails-assets.org.
- Fixes a bunch of things in one stroke, eg #91
<#91>, #79
<#79>, etc.
- *Disadvantages:*
- Ultimately need to modify or duplicate all existing asset helpers
to work with the webpack-generated manifest.
- Additional webpack complexity around manifest generation and CSS
extraction and other things we want production-ready defaults for.
Potentially more moving pieces on the webpack side.
I'd be interested in creating a generator to support option 2 (either as
an alternative to webpacker:install or as an additional generator that
can be run after it.) Option 1 would be left as the default.
I think this feature could also provide the first step on a gradual path
to moving Sprockets out of
core. I think the technical risk of relying on Webpack (or another
successor library) is less than than the risk of relying on Sprockets.
Sprockets is a very complex library (and I suspect a maintenance pain
point.) It was a major step forward for its time but is showing its age;
most of its functionality is better provided by Webpack, which will soon be
part of Rails.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#109>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAKtQh2y4TBAwTXj89f05iU8lWtKSAZks5rfd5KgaJpZM4MKZTk>
.
|
Great, I'll get started! |
❤️❤️❤️
…On Thu, Feb 23, 2017 at 8:46 PM, Daniel Leavitt ***@***.***> wrote:
Great, I'll get started!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#109 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAKtVg8MW81p1pt1JLgLKuxzksJCbOiks5rfeIQgaJpZM4MKZTk>
.
|
@dleavitt @dhh Made an example app that uses webpacker + some additional changes that could be incorporated into Webpacker to make it work with static assets like css, images and fonts for app like javascripts. Javascript app codehttps://github.com/gauravtiwari/webpacker-example-app/tree/master/app/javascript/counter Some minor patches to source lookup classhttps://github.com/gauravtiwari/webpacker-example-app/blob/master/app/lib/webpack/source.rb Now using webpack manifest plugin, which maps all assets by default like this in production, {
"clock.png": "/packs/clock-fc31531de5cc3518c7c658d5b83faa72.png",
"counter.css": "/packs/counter-c38deda30895059837cf.css",
"counter.js": "/packs/counter-300631c4f0e0f9c865bc.js",
"lacuna-webfont.eot": "/packs/lacuna-webfont-54c0d12c6ab265792f0d8cfd81e481e4.eot",
"lacuna-webfont.svg": "/packs/lacuna-webfont-58e9f0ae5f3dec1ea00ef1a1ad099e8c.svg",
"lacuna-webfont.ttf": "/packs/lacuna-webfont-1acb63487c4a72f7fd2e545d2e0090e2.ttf",
"lacuna-webfont.woff": "/packs/lacuna-webfont-0eb6add367ef5fc69c4569894525bd52.woff"
} and in development, {
"clock.png": "/packs/clock.png",
"counter.css": "/packs/counter.css",
"counter.css.map": "/packs/counter.css.map",
"counter.js": "/packs/counter.js",
"lacuna-webfont.eot": "/packs/lacuna-webfont.eot",
"lacuna-webfont.svg": "/packs/lacuna-webfont.svg",
"lacuna-webfont.ttf": "/packs/lacuna-webfont.ttf",
"lacuna-webfont.woff": "/packs/lacuna-webfont.woff"
} it solves problem around linking multiple asset types with same name as we are using proper extensions in this manifest. Asset helperAn asset helper that generates appropriate HTML tags based on a given asset - View integrationWebpack configsUpdated webpack configs to incorporate fonts, styles and images Demohttps://webpacker-example-app.herokuapp.com/ Thought it would be good idea to visually look at this in action in a Rails app and then make a PR with the required changes. Also, on another note it seems we should remove react, angular and vue integrations out of this Gem. Perhaps, it's best we leave those integrations to community using a separate gems that depends on Webpacker because there are just tons of frameworks and they all work differently. Webpacker can be used to integrate webpack and yarn into a Rails app, instead of sprockets (in future). Will create an issue to discuss this further. |
This looks like a nice start! I am not fond of having non-JS code in @dhh, do you have an opinion on assets should be handled "long-term"? Should it be only Webpacker or Sprockets (for non-JS assets), or have support for Sprockets+Webpacker at the same time? As for your last comment, I agree. For React, we could easily move the |
@renchap Yeah, I agree. This is just to get an overview so, we can look at the options. I moved the static assets to If we are moving to webpack eventually, one asset helper tag would be enough because we can use the webpack manifest file to lookup and map generated assets. I guess this will make server rendering easy too. Yes, perhaps something like omniauth with it's many adapters. |
Wow, that was fast! Nice work! ✋ 👈 that is a high five. High five! I have some thoughts:
Anyway, this basically looks great and I think you or somebody should prepare some PRs. I'm thinking:
@renchap remember that this is intended (for now) to be a non-default alternative to using sprockets + webpack. People who are using webpack to manage their CSS and images are generally going to want them in the same paths as their Javascript.citation needed A very popular way to do it nowadays is to organize your app by components, and have all JS, assets, views, and CSS for a component live together in the same directory (or same file in Vue's case.) That said it's at some point worth discussing a number of larger issues around this, including whether javascript is the right name for the folder, what the various rails generators should do, etc. |
There's no reason to keep CSS separate from JavaScript with CSS modules. Here is an example: https://github.com/css-modules/webpack-demo/blob/master/src/components/1-ScopedSelectors/ScopedSelectors.js |
@dleavitt ✋ Okay so you wrote a ton of things 😄 so, let me read it and then we can work on it together. I saw @justin808 also opened an issue (#130) around directory organisation. This is good thing that everyone is coming together and contributing so, I suggest lets use this opportunity to discuss around these issues and then work on it through PR's otherwise we might have to face a lot of PR conflicts and duplicates. |
@gauravtiwari I took a look at gauravtiwari/webpacker-example-app@c617c1c. To me, this clearly shows that we should keep the old Rails assets that are loaded from the older Rails asset helpers into ERB files totally separate. I think it's critical that non-JS assets can be loaded the webpack way, which is to use |
@dleavitt Regarding
Maybe we could have a global default that OTOH, I like what @gauravtiwari did by creating just one helper I would probably just go with @gauravtiwari and replace the "javascript_pack_tag" with the "asset_pack_tag". |
@dleavitt Some notes for you on the points you commented earlier :),
Yes, it's seems reasonable to use the options you suggested and don't think it's complicated. All the options could be passed via the binstubs provided. We can set env variables during runtime and then the config will have access to it. On other note, about commenting the dev server config, I feel perhaps we shouldn't comment anything out that we feel is the standard practice for that environment, to give the developers the best experience and integrated setup.
As for this one, I feel it's best we don't mess up with asset pipeline helper at this point and rather spend our time to create something that works with Webpacker. Probably, this will confuse folks so, I guess it's best if we develop a set of tools around this Gem that works really well and integrated with Rails framework, not particularly asset pipeline or sprockets. Those systems are already well evolved as of now and works. Did you checked this helper tag? https://github.com/gauravtiwari/webpacker-example-app/blob/master/app/helpers/application_helper.rb#L4 How does it feels like? (Given we ignore asset pipeline for now completely)
I agree. As @justin808 pointed out couple of ideas in this (#130) comment regarding directory structure. Perhaps, we can take all that together and discuss this in that thread, however this looks nice though.
Absolutely, that was basically a quick setup to see how things might work. Although, as you mentioned there are a couple of gotchas that will come in the way. We will see.
Yes, that's what manifest plugin does, we have digests.json generated all the time, whenever the webpack server or watcher is re-run. See this comment, #109 (comment) SummarySo, overall it feels that for this particularly issue we need following, considering we don't bother about asset pipeline for now and assuming, this setup is purely for developing client side app's in javascript and not sprinkles,
Obviously, we can just use CSS modules as @justin808 suggested, however I am not sure if this works for everyone. Perhaps, we can provide both options.
@renchap and @justin808 can share some thoughts on server rendering and if any special setup is required for third party integration that we should have in this Gem ? I guess having a manifest of all assets will make this very transparent as we can lookup bundles and use it during server rendering. For other issues like folder names, lets discuss and track them in separate threads. |
@gauravtiwari awesome, thanks so much for the thoughtful reply!
I just suggested this for consistency with
I'm actually just suggesting we do what sprockets does; override
I think his ideas are interesting (and probably based on a lot of experience.) However they're pretty radical, and I don't think they should be part of this PR for now. I was more concerned with the structure within
Right, but the manifest is not actually used unless digesting is on. I suspect we'll eventually need to use it for non-digesting requests as well, but again, let's cross that bridge when we get to it. Your checklist looks great to me! A few notes:
I don't think we should have
If we can get the rest of the stuff done without this it might be a good idea to do this as a separate PR. Naming things is always controversial 🙂
I like what you've got right now. Just make sure
I think if we do this right it will make it easy to use CSS modules or any other setup folks might want to use. We can be agnostic about this.
Again, I think this should be on the roadmap but maybe not addressed here. Baby steps 👶 |
@dleavitt Great 😄 Oh yes, sorry I meant in terms of directory and naming in general (since that's been discussed), not technically and I agree about preserving So, I think once #111 is merged I can start making a PR on this and we can work together on that to finish up the feature. TODO
Yep, that totally makes sense 👍 |
Awesome! yeah I think it's best not to add any new dependencies in this PR. We just want to make using file-loader possible, not actually install it. |
All we need is a controller helper to get a specific file compiled asset file by name, and at production time, the fingerprinted one is loaded. Server rendering is running a JavaScript snippet with some library loaded (webpack bundle) and returning a string of HTML that is put on the rails view. |
👍 for grabbing |
@swrobel @gauravtiwari FWIW, we've given up on the hot reloading for our biggest application and we are instead relying on the Webpack DLL to speed up build times. I tend to create different Procfiles to either run static asset creation or hot reloading. This stuff is changing all the time. Sometimes, hot reloading is working. Sometimes it's not. |
A few quick thoughts:
Haven't had a chance to look at the code here yet, though. So that's just the preliminary thoughts. Awesome to see this progress so quickly! Thanks to everyone working on it and chiming in. ❤️ |
Thanks to you too ❤️ I am working on this one along similar lines. Will make a PR once ready. |
@dhh I think webpacker can use the same view helpers in a way that's sprockets-agnostic, right? Currently if you have sprockets (but not Webpacker) and use a view helper, the following happens:
With the addition of webpacker we just add one more step:
This means we only have to patch Let me know if I'm off-base here, but this seems like a much more elegant long-term solution. And I think it's pretty easy to implement. |
FWIW, as a user of webpacker, I would like a way to do exactly that - load css from I saw this in the Rails 5.1.0beta1 release blog post:
"Everything" had me hoping that I could reference this node package's CSS, but I think this means only JS dependencies can be referenced in the asset pipeline. |
@sealocal I've already started an effort to provide what you want in a gem complimentary to Webpacker, so that all the functionality of full webpack support for non-JavaScript is full supported, as it's done right now for React on Rails. |
@sealocal Not sure if I understood correctly, but I think you can do that with I am working on this so, hopefully will have PR soon for you to review. Is that what you meant? |
@justin808 Is there a name for this other complimentary gem? I will take a look when its published. @gauravtiwari Basically, I want to add to my component a syntax I've seen elsewhere: import css from 'file.css' I'm not so familiar with Webpack - I'm heavily leaning on webpacker. It seems that loading assets this way are popular - 3M download in last month, yarnpkg.com gives it a 🔥 . I say this is supportive evidence for webpacker making it a sensible default. webpack/shared.js
components/my_component.jsx.erb
The only downside is that this approach seems to slow down the Looking forward to learning from the PR on this! |
@sealocal the point of `import css from './MySuperComponent.css' is to have small bits of CSS right next to the components. If you want a global set of styles, just set it in the header and be done with it. |
@sealocal Great 👍 I think we are on the same page then 😉 Right, I see. Btw, you don't need to do .erb there, just relatively link the node_module as you would link any node_module. For ex - Please do checkout this in the meantime - Most of the work is on this repo and for guide just use this comment - #109 (comment) |
This is awesome! And great to see how to get into the innards of how to integrate with Rails. |
@justin808 I really don't care if it's global or local. I just want the stylesheet to always be available for any page or component that renders @guilleiguaran I get it! I don't know why you use |
@sealocal Ohh, it's because we don't need to assign that import. The assignment is only used if we want to do anything further with that variable. Essentially import css from 'file.css' It's ok like this if you are using Sorry, if I confused you earlier :) |
import css from './MyCompnent.css'; is for CSS modules where the class names in MyComponent.css are made into unique hashes so that your class names in your JS code are clean and simple, yet the browser has a totally unique class name that will not conflict. |
Yes, I'd love to see this as well. This way we can use Our current solution to integrate Webpack (and other tools) is this: |
I think it would be useful to have an additional generator that supports all FE assets being managed through Webpack. I'd love to gauge interest and get feedback before I start on a PR.
Background:
As far as I know there, are two basic options for managing images/css/etc in a webpack + rails app.
Option 1: Manage Javascript through Webpack and everything else through Sprockets.
This is only option currently supported out of the box.
Option 2: Manage all assets through Webpack, remove Sprockets.
This involves adding some loaders to webpacker (probably file-loader and sass/css/style loaders) as well as a manifest generator that Rails can use to get properly fingerprinted paths in erb and such.
I'd be interested in creating a generator to support option 2 (either as an alternative to
webpacker:install
or as an additional generator that can be run after it.) Option 1 would be left as the default.I think this feature could also provide the first step on a gradual path to moving Sprockets out of
core. I think the technical risk of relying on Webpack (or another successor library) is less than than the risk of relying on Sprockets. Sprockets is a very complex library (and I suspect a maintenance pain point.) It was a major step forward for its time but is showing its age; most of its functionality is better provided by Webpack, which will soon be part of Rails.
The text was updated successfully, but these errors were encountered: