Add Yarn support in new apps using --yarn option #26836

Merged
merged 4 commits into from Nov 29, 2016
@Liceth
Contributor
Liceth commented Oct 20, 2016 edited

This add a package.json and the settings needed to get npm nodules integrated in new apps when the --yarn option is used (e.g rails new blog --yarn).

The next changes should be done to finish this:

  • Add package.json in new apps when --yarn option is passed
  • Run yarn install after bundle install in new apps
  • Add rails-ujs dependency to package.json
  • Add node_modules folder to asset paths
  • Fix existing broken tests
  • Add new tests
  • Changelog
@rails-bot

Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @eileencodes (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

This repository is being automatically checked for code quality issues using Code Climate. You can see results for this analysis in the PR status below. Newly introduced issues should be fixed before a Pull Request is considered ready to review.

Please see the contribution instructions for more information.

@guilleiguaran guilleiguaran self-assigned this Oct 20, 2016
@guilleiguaran guilleiguaran changed the title from Add Npm support in new apps using option to [WIP] Add Npm support in new apps using option Oct 20, 2016
@guilleiguaran guilleiguaran changed the title from [WIP] Add Npm support in new apps using option to [WIP] Add npm support in new apps using --npm option Oct 20, 2016
@@ -404,6 +412,49 @@ def run_bundle
bundle_command("install") if bundle_install?
end
+ def npm_path
+ commands = ["npm"]
@guilleiguaran
guilleiguaran Oct 20, 2016 Member

I think we can add also to "yarn" command here (https://code.facebook.com/posts/1840075619545360)

- gems << GemfileEntry.version("#{options[:javascript]}-rails", nil,
- "Use #{options[:javascript]} as the JavaScript library")
+
+ packagejson_exist = File.exist?("package.json")
@guilleiguaran
guilleiguaran Oct 20, 2016 Member

We are using this line code in multiple parts of code so I think we can extract it to an package_json_exist? function

@@ -33,6 +33,9 @@ def self.add_shared_options_for(name)
class_option :javascript, type: :string, aliases: "-j", default: "jquery",
desc: "Preconfigure for selected JavaScript library"
+ class_option :npm, type: :boolean, default: false,
+ desc: "Preconfigure for NPM for assets management"
+
@guilleiguaran
guilleiguaran Oct 20, 2016 Member

"Preconfigure NPM for assets management"

+ "dependencies": {
+ "jquery": "~3.1.0",
+ "jquery-ujs": "~1.2.2"
+ }
@guilleiguaran
guilleiguaran Oct 20, 2016 Member

I think we will be able to remove jquery from here and change jquery-ujs to rails-ujs after of having #25208 finished

+
+ unless npm_path
+ puts %{Warning: npm option passed but npm executable was
+ not detected in the system. Download Node.js in https://nodejs.org/en/download/}
@guilleiguaran
guilleiguaran Oct 20, 2016 Member

Let's move this warning message to https://github.com/rails/rails/pull/26836/files#diff-248322211d56bb3b2ab59ac68a2839f5R212, right now it's being displayed everytime the npm_path function is called if command is not found

@rafaelfranca
Member

Can we change npm with yarn? I think only the npm install command that
needs to change
On Wed, 19 Oct 2016 at 21:58 Ruby on Rails Bot notifications@github.com
wrote:

Thanks for the pull request, and welcome! The Rails team is excited to
review your changes, and you should hear from @eileencodes
https://github.com/eileencodes (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra
commits. This ensures that the reviewer can see what has changed since they
last reviewed the code. Due to the way GitHub handles out-of-date commits,
this should also make it reasonably obvious what issues have or haven't
been addressed. Large or tricky changes may require several passes of
review and changes.

This repository is being automatically checked for code quality issues
using Code Climate https://codeclimate.com. You can see results for
this analysis in the PR status below. Newly introduced issues should be
fixed before a Pull Request is considered ready to review.

Please see the contribution instructions
http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html
for more information.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#26836 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAC66CqJBNFf1G3_6OUb7rSrr1YlfQVeks5q1rzGgaJpZM4KbnZu
.

@Liceth
Contributor
Liceth commented Oct 20, 2016

yes, we can add "yarn" as first option to supported commands list and it will be used instead of npm if installed

@rafaelfranca
Member

I'd not even bother to support npm, just jump straight to yarn.

On Wed, 19 Oct 2016 at 22:57 Liceth Ovalles Rodriguez <
notifications@github.com> wrote:

yes, we can add "yarn" as first option to supported commands list and it
will be used instead of npm if installed


You are receiving this because you commented.

Reply to this email directly, view it on GitHub
#26836 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAC66LVJhBn3WNYgCrQQT1xk7LRggIDcks5q1sqJgaJpZM4KbnZu
.

@guilleiguaran guilleiguaran added this to the 5.1.0 milestone Oct 20, 2016
@Liceth Liceth changed the title from [WIP] Add npm support in new apps using --npm option to Add npm support in new apps using --npm option Oct 22, 2016
@Liceth
Contributor
Liceth commented Oct 22, 2016 edited

@eileencodes @rafaelfranca @guilleiguaran This is ready for review and failures in TravisCI aren't related to my changes (mysql2 tests are failing since yesterday).

@guilleiguaran
Member

@Liceth I've fixed the mysql2 tests in f13ec72 and updated your branch

@@ -205,6 +209,9 @@ def create_root_files
build(:readme)
build(:rakefile)
build(:configru)
+ if options[:npm]
+ build(:packagejson)
+ end
@guilleiguaran
guilleiguaran Oct 24, 2016 edited Member

This if can be done in a single line:

build(:packagejson) if options[:npm]
@Liceth
Liceth Oct 24, 2016 Contributor

Thanks for the observation @guilleiguaran I already made the changes

@bouk
Member
bouk commented Oct 25, 2016

Please note that yarn is not a total drop-in replacement for npm, we can't try one or the other. A project that uses yarn gets a yarn.lock file (analogous to Gemfile.lock). NPM doesn't create a file like that and doesn't interpret it.

I fully support not even bothering with NPM and just using yarn, it's a lot more robust in my experience. Requiring people to install it separately might take away from the plug-and-play nature of Rails.

@eileencodes eileencodes removed their assignment Oct 25, 2016
@Liceth
Contributor
Liceth commented Oct 25, 2016 edited

I'm fine wherever you decide about yarn/npm, only let me know the final decision on it.

@connorshea
Contributor

Don't you install Yarn using npm? I 100% support using Yarn as the package manager, but it won't avoid npm entirely.

@@ -33,6 +33,9 @@ def self.add_shared_options_for(name)
class_option :javascript, type: :string, aliases: "-j", default: "jquery",
desc: "Preconfigure for selected JavaScript library"
+ class_option :npm, type: :boolean, default: false,
+ desc: "Preconfigure for NPM assets management"
@connorshea
connorshea Oct 26, 2016 Contributor

npm should be lowercase in all situations as far as I know.

+ npm_command("install")
+ else
+ say_status :warning, "npm option passed but npm executable was not detected in the system.", :yellow
+ say_status :warning, "Download Node.js in https://nodejs.org/en/download/.", :yellow
@connorshea
connorshea Oct 27, 2016 Contributor

Should be "Download Node.js at https://nodejs.org/en/download/"

@Liceth
Liceth Oct 27, 2016 Contributor

Hi @connorshea Thanks for you review

@@ -5,6 +5,9 @@ Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path
+<%- if options[:npm] -%>
+Rails.application.config.assets.paths << Rails.root.join('node_modules')
@connorshea
connorshea Oct 27, 2016 Contributor

Should this have a comment explaining what it does?

@bouk
Member
bouk commented Oct 28, 2016

For installing yarn there's options available for most common package managers (brew, apt, Chocolatey) https://yarnpkg.com/en/docs/install

@bouk
Member
bouk commented Oct 28, 2016

It might be handy to add updating of the JS packages to the bin/update and bin/setup templates

@guilleiguaran
Member

@Liceth we have decided to skip NPM and go directly with Yarn because of the improvements of this last. Can you update your pull request?

Also update the bin/update and bin/setup files as @bouk suggested.

Thank you very much for your work on this!!!

@Liceth
Contributor
Liceth commented Oct 31, 2016

Sure @guilleiguaran I wil do the changes in the pull request.
Thank you 👍

@Liceth Liceth changed the title from Add npm support in new apps using --npm option to Add Yarn support in new apps using --yarn option Oct 31, 2016
@Liceth
Contributor
Liceth commented Nov 18, 2016 edited

@rafaelfranca @guilleiguaran I'm finishing this but I have a quick question related to jQuery removal (#25208)

If the users pass the -j option when they're creating a new app do we need to add the library to the Gemfile (e.g jquery-rails) or to the package.json?

Also note that there are some libraries that haven't been published to npm since they haven't received updates in many years like prototype.js, prototype_ujs and mootools_ujs

@guilleiguaran
Member

Let's keep the actual behavior of -j option, if the users pass it let's add the gem instead of the npm dependency.

@guilleiguaran
Member

Also please rebase this and squash commits

@guilleiguaran
Member

This seems ready for me, I've assigned to @dhh for final review

@guilleiguaran
Member

One last thing, please add a CHANGELOG entry for this, please!!

@Liceth
Contributor
Liceth commented Nov 22, 2016

Ok I will do the change @guilleiguaran

@guilleiguaran
Member

Sorry, I was supposed to unassign myself only, not to @rafaelfranca, re-assigned to him also 😄

@dhh
Member
dhh commented Nov 23, 2016

What options do we have for relocating this config file somewhere else? IMO, it seems natural that this should either live in config/ or app/assets. But not in root.

@guilleiguaran
Member

AFAIK all the operations done with the yarn command are relative to the current folder (used as prefix), so it we want to move package.json to app/assets we need to move also node_modules and users will need to run yarn commands inside of app/assets folder.

@@ -33,6 +33,9 @@ def self.add_shared_options_for(name)
class_option :javascript, type: :string, aliases: "-j",
desc: "Preconfigure for selected JavaScript library"
+ class_option :yarn, type: :boolean, default: false,
@rafaelfranca
rafaelfranca Nov 23, 2016 Member

wrong indentation here.

+
+ yarn_path = commands.find do |cmd|
+ paths = ENV["PATH"].split(File::PATH_SEPARATOR)
+ path = paths.find do |p|
@rafaelfranca
rafaelfranca Nov 23, 2016 Member

blank line around this block

+ end
+ path && File.expand_path(cmd, path)
+ end
+ yarn_path
@rafaelfranca
rafaelfranca Nov 23, 2016 Member

blank line before this line

+
+ def yarn_command(command)
+ full_command = "#{yarn_path} #{command}"
+ if options[:quiet]
@rafaelfranca
rafaelfranca Nov 23, 2016 Member

blank line before this line

+ end
+ end
+
+ def run_yarn
@rafaelfranca
rafaelfranca Nov 23, 2016 Member

This method should be the first defined and the others be defined after this one.

def run_yean
def package_json_exist?
def yarn_path
def yarn_command
-<% unless options.skip_active_record -%>
+<% if options[:yarn] %>
+ system! 'yarn'
+<% end %>
@rafaelfranca
rafaelfranca Nov 23, 2016 Member

Should not the blank line be inside the conditional?

Liceth added some commits Nov 20, 2016
@Liceth @guilleiguaran Liceth Add package.json for Yarn if --yarn option is added 89822e8
@Liceth @guilleiguaran Liceth Add node_modules path to assets load paths when --yarn option is used e6730c7
@Liceth @guilleiguaran Liceth Run yarn on setup and update scripts.
9a95e13
@Liceth @guilleiguaran Liceth Add node_modules to default gitignore 732702b
@Liceth
Contributor
Liceth commented Nov 28, 2016

@rafaelfranca Changes are done

@rafaelfranca

Thank you so much.

Please add a CHANGELOG entry so @guilleiguaran can merge it.

@guilleiguaran guilleiguaran merged commit 43e42ad into rails:master Nov 29, 2016

2 checks passed

codeclimate Code Climate didn't find any new or fixed issues.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@guilleiguaran
Member

Looks like the CHANGELOG entry was missed with the last rebase but I still had it locally so I've pushed it in 3b0a09c

@Liceth
Contributor
Liceth commented Nov 29, 2016

Thank you!! 👍

@vipulnsward
Member

🚀 ❤️

@dhh
Member
dhh commented Nov 30, 2016

Thanks for working on this @Liceth! I've been adding Yarn to Basecamp 3 and made a few alterations to the setup merged here that I'd like to see in master, if you're interested in continuing to work on this:

  • Having node_modules in the root of the app doesn't feel quite right. I get that this is the standard for full-JS apps, but a Rails app is more like a cohabitation space. So I'd like for us to use vendor/yarn/node_modules (and vendor/yarn/package.json).
  • To use a custom placement for Yarn, we'll need to make sure Yarn is run from vendor/yarn. To that effect we can use a new bin/yarn binstub that sets the things right. I've been running with this binstub:
#!/bin/bash
app_root="$( cd "$(dirname "$0")/.."; pwd )"
( cd $app_root/vendor/yarn; yarn $@ )
  • We should have a vendor/yarn/.gitignore that has node_modules in it.
  • I think we should also have a vendor/assets/javascripts/yarn.js stub that suggests how to use //= require some/yarned/js/stuff to be compiled by the asset pipeline. We can then include this yarn dependency file from the default application.js setup.
  • I'd like to consider making Yarn the default when its installed on the system. So if yarn is available, we switch to Yarn-by-default and expose --skip-yarn instead.
@dhh
Member
dhh commented Nov 30, 2016

(BTW, I'm aware that the default node load path scheme is easier when you nest node_modules in a clear hierarchy. With vendor/yarn/node_modules AND app/assets/javascripts we'll need to set NODE_PATH or similar when configuring web pack. But I think that's fine.)

@keoghpe
keoghpe commented Nov 30, 2016

👍 Great job, I feel rails has been yarning for this for quite some time.

@bouk
Member
bouk commented Nov 30, 2016

@dhh I think your suggestion makes sense as a default for Rails, and apps can change their set up if needs arise

@dhh
Member
dhh commented Nov 30, 2016

On second thought, perhaps we don't even need the yarn directory. We could just go with vendor/node_modules, vendor/package.json, vendor/yarn.lock. That actually seems well enough.

@benlangfeld
benlangfeld commented Nov 30, 2016 edited

@dhh If package.json has to go in vendor/, then Gemfile logically would have to also.

I don't object to node_modules being hidden away, but package.json and yarn.lock are root level application concerns and should be exposed just like Gemfile, .travis.yml, etc. Are you open to reconsidering that?

@dhh
Member
dhh commented Nov 30, 2016
@dhh
Member
dhh commented Dec 1, 2016

Implemented my recommendations for using vendor in #27245.

@benlangfeld

@dhh I still don't understand the objection to leaving those project metadata files in the root directory where all the others like it live. What am I missing?

@dhh
Member
dhh commented Dec 1, 2016

@benlangfeld The root is enough of a mess as-is in many projects. To clean that up, we gotta start somewhere. This seems like a good place. package.json/yarn.lock and the node_modules directory are all clearly vendor concerns. So moving that stuff to vendor makes sense to me.

@dhh
Member
dhh commented Dec 1, 2016

I'd be happy in time to move Gemfile/Gemfile.lock there as well.

@benlangfeld

@dhh In cases where Rails engines are also npm modules for the purpose of delivering assets, the package.json they have is meta-data about the package being delivered in the same vain as the gemspec. In the event this change propagated to engines, would you support these files staying in the engine root alongside the gemspec?

I ask mostly because this is something I'm working through on our engine-based app, but also because I recall a traumatic incident as a child when I "tidied up" some messy DLLs from C:/ to C:/Windows and "bricked" the family computer. 😄

@dhh
Member
dhh commented Dec 1, 2016

Can you walk me through the workflow you have for engines where there is a package.json? Are you using that file to publish the JS parts of the engine to NPM? Or are you thinking that this is a way to integrate matters once we get to Webpack?

Because I get that package.json is basically both Gemfile and .gemspec in one. In Rails, your own app doesn't have a .gemspec, but your engine might. Here, we're using package.json as Gemfile, just to manage the vendored JS dependencies, not as .gemspec with the intention of publishing the app somewhere.

@benlangfeld
benlangfeld commented Dec 1, 2016 edited

@dhh We're following an internal workflow based on the ideas at http://cbra.info, the overall goal being rescuing a 200kloc, 600 model application from chaos.

This app also uses react_on_rails, which uses Webpack rather than the asset pipeline, and my current effort is on linking engine's assets into the app. This is what I'm actively working on as of today, so my thoughts are not yet well formed.

once we get to Webpack?

Is some core usage of Webpack already on the roadmap? Are there details available of what this will look like?

@dhh
Member
dhh commented Dec 1, 2016

Gotcha. Yeah, let's try to sort it all out.

I'm starting work on --webpack now. Should have a preliminary PR up soon. There's definitely a ton more work for us to get there compared to --yarn, but I'd like to target 5.1 with that option as well.

@dhh
Member
dhh commented Dec 1, 2016

Not a fan of using components to decompose the Majestic Monolith. But whatever floats your boat! We have a 300-model, 35kloc app in Basecamp 3. Shopify has, I believe, a 700-model 200kloc app. Both Majestic Monoliths, and happily so.

If you, for organizational reasons, want to split the Majestic Monolith, then I think going with completely separate apps is a better way to go.

@TheLarkInn

Feel free and reach out for webpack assistance :) our org would love to track the efforts to adding webpack as a replacement to sprockets etc and assist where valuable.

@dhh
Member
dhh commented Dec 2, 2016 edited

Thanks @TheLarkInn. I'm sure we can use the help! I'll ping you on the PR once it's ready.

The current thinking is to let the asset pipeline focus on JS sprinkles, css, images, etc. I know that web pack technically CAN manage those things, but I don't see a big benefit to doing so.

Where Webpack really shines is for application-level JS. So that's also a way for having the two systems coexist, especially for existing apps. For Basecamp, we're considering writing another calendaring feature, which is right in the sweet spot for client-side MVC. We can use Webpack for that feature, while we continue to use the asset pipeline for the JS sprinkles that add sparkle to pages with less demanding UI.

Anyway, I've been diving in over the last several days. Playing with everything within Basecamp. So thinking subject to change!

What's clear is that we want the core Rails principles of convention over configuration to carry over. Nobody should HAVE to configure their own webpack.config.js. It should surely be possible, but not required.

@TheLarkInn

Totalll, I think that's a great start/approach. I'm making a plugin that can potentially work with multipage MVC's multipage-webpack-plugin. It's an oss plugin inspired at work for the need for an easier script injection process for server routes MVC's (we use laravel), so if you find benefit to match this kind of rails arch, let.me know and we can work on it or i can implement additional feature. I'll keep an eye out for an email when you get a PR ready. 👏👏👏

@moonglum
moonglum commented Dec 2, 2016 edited

@dhh A different approach would be to offer integration to external asset pipelines, without choosing a specific one like Webpack. I've built a gem for that purpose and am using that in production with a (Webpack-based) Node.js asset pipeline. The idea is simple:

The external asset pipeline compiles the files. In addition, it creates so called manifest files that map artifact names (like application.js) to a path where the file can be found (like /javascripts/application-gjgkj3499292.js). The gem simply reads the manifest files so you can still keep using helpers like stylesheet_link_tag or image_tag without loosing the capability to use cache busting for those files. The manifest file is a simple JSON file.

If you're interested in that approach, I'm more than happy to contribute that to Rails.

@dhh
Member
dhh commented Dec 2, 2016

Lucas, that's an interesting idea. I'd like to start with Webpack first and see how things go. For starters, we're only going to use Webpack for app-style JS. Not images, css, fonts, etc. I think it's more important out the gate that we nail the experience for the pipelines we provide in the box (Rails' own and Webpack) than going full extendable. But those goals are not in opposition.

I'd be happy to see what an exploration looks like. I'd just temper expectations about what's on a likely path for Rails 5.1.

It'll probably be easier to see how this is going to fit together once we land the current plans for --webpack in master.

@FND
Contributor
FND commented Dec 2, 2016 edited

@dhh's approach seems reasonable - however, it might still be advisable to choose a compiler-agnostic name for the CLI option, to prevent API changes when the underlying infrastructure changes? (For straightforward webpack configurations, Rollup can be used as a drop-in replacement.)

@dhh
Member
dhh commented Dec 2, 2016

Don't think the CLI options matter that much, since even if we did go with a generic solution, we can still support that. So --webpack would trigger the Webpack variant of that. Then --other-pipe could trigger that. Or we could extend with --pipeline webpack. This CLI name is only relevant for the start of a new project anyway. So it's not like there'd be backwards incompatibility issues going forward.

But yeah, I think all this is up in the air. Let's get a real PR going, then it'll be easier to talk about specifics.

@mrreynolds
Contributor

+1 for --pipeline webpack.

@kayakyakr
Contributor

This triggered a long conversation in our Slack about the same and even with just 2 of us mostly talking, we came up with 4 different opinions on how it should be done... In general, I think we'd favor a combination of @moonglum and @dhh's approaches.

Dunno if anyone's had experience with https://github.com/thoughtbot/ember-cli-rails, but they've mostly hit the sweet spot as far as I'm concerned.

@dhh
Member
dhh commented Dec 2, 2016

@kayakyakr That's always been a big part of the value with Rails. There's an infinite number of ways things COULD be done, but there's an immense benefit to simply picking a path of running with it. That's the core promise behind Convention over Configuration.

@FND
Contributor
FND commented Dec 2, 2016

FWIW, without wanting to belabor this point, just a quick clarification: The benefits of Convention over Configuration are of course undisputed - the reason this issue seemed worth raising is because the JavaScript precompiler shouldn't surface to application developers, i.e. the respective source code should be unaffected by whatever is decided here.

@kayakyakr
Contributor

@FND that's not going to be the case if the implementation is to run sprockets and webpack side-by-side, though. Each pipeline wants its own assets path. Only taking the path of full pipeline replacement gets you the ability to be precompiler-agnostic.

@moonglum
moonglum commented Dec 2, 2016

In general, I think we'd favor a combination of @moonglum and @dhh's approaches.

I think that makes sense. If the ability to read manifest files as described above would be built-into Rails, then all the --webpack flag would need to do is create a webpack config that creates the according manifest files. Adding a --whatever-other-solution-you-need flag would then be simple.

This would offer the easy out of the box experience that @dhh described, but would still be flexible to use with other external asset pipelines.

@NekR
NekR commented Dec 4, 2016

I know that web pack technically CAN manage those things, but I don't see a big benefit to doing so.

It might be useful if someone would, say, use a ServiceWorker webpack plugin to generate it for static assets. I know there is ServiceWorker plugin for rails' itself, but still, that might be possible.

@steakknife

Looks good. Previously there was webpack-rails (more resources: Migrating from Rails’ asset pipeline to Node’s webpack, react-webpack-rails-tutorial), which might serve as an example to build upon configuration / conventions and integration behaviors.

@akabekobeko
akabekobeko commented Dec 5, 2016 edited

webpack is popular and multi-functional. However, it is mere module and it is not standard as Node and npm. As with yarn, these are optional as npm and npm-scripts as standard.

If jQuery dependence is to be stopped, it is better to be cautious about non-standard product dependence.

If future yarn and webpack are obsolete (...It may be impossible), npm and npm-scripts will remain.

@justin808
justin808 commented Dec 5, 2016 edited

@steakknife Thanks for the shout-out for the react-webpack-rails-tutorial. Its sibling package is react_on_rails.

@justin808

@dhh wrote:

Lucas, that's an interesting idea. I'd like to start with Webpack first and see how things go. For starters, we're only going to use Webpack for app-style JS. Not images, css, fonts, etc.

A huge advantage of Webpack is CSS-Modules. If you like tidy, you'll love CSS-Modules. See Sass, CSS Modules, and Twitter Bootstrap Integration.

Here's an example of it:

@josepjaume
Contributor
josepjaume commented Dec 5, 2016 edited

@dhh in my experience, the major pain points I've found integrating any sort of pre-compiling using Webpack and feeding it to Sprockets are asset fingerprinting. The way Sprockets works right now, it's nearly impossible to create, let's say, a react component that references a particular asset (an image, for example), without getting React to read Sprocket's manifest file, or Sprockets read Webpack's manifest file.

There's two approaches I believe might work:

  • The first one, just let Webpack handle asset fingerprinting, but you already said that's not desirable.

  • Another other option would be to let Sprockets fingerprint all the assets and rewrite the actual assets just at the end of the build process, instead of relying on the original code to write the right asset locations - something like what the Phoenix framework does with brunch. That'd would also decouple the contract between webpack (or any other build tool) and sprockets, allowing us to integrate with virtually any other build tool.

Maybe the guys on https://github.com/shakacode/react_on_rails/ (specially @justin808) could chime in on the matter, they seem to have given it a lot of thought.

@justin808

@josepjaume We have the problem solved in React on Rails, such that "it just works". The solution involves:

  1. Allow webpack to fingerprint assets.
  2. Publish the assets using the Rails asset pipeline, which creates double fingerprints.
  3. Create symlinks at deployment, using the manifest file, so that we have single-fingerprinted symlink names that point to the double fingerprinted files.

This way, the correct file names are available on deployment.

Any questions?

@jamby jamby referenced this pull request in browserify-rails/browserify-rails Dec 6, 2016
Closed

Browserify/babelify transforms not working #181

@dhh
Member
dhh commented Dec 7, 2016

For those interested, I've published the first work on --webpack here: #27288.

Re: cross-reading of manifests, @josepjaume, I think that's actually how we should make this work. Make it possible for each side to read the others manifest and construct what they need from there. The current strategy is to use Webpack exclusively for app-like JS, and nothing else. Asset pipeline for everything else (JS sprinkles, images, fonts, css, etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment