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

Ready for Vue #107

Merged
merged 9 commits into from
Feb 24, 2017
Merged

Ready for Vue #107

merged 9 commits into from
Feb 24, 2017

Conversation

ytbryan
Copy link
Contributor

@ytbryan ytbryan commented Feb 23, 2017

This PR ships with Vue, its supported libraries & configuration which I reference partially from chrisvfritz's repo (https://github.com/chrisvfritz/rails-javascript-integrations/tree/vue-webpack)

It includes the classic <%= javascript_pack_tag 'hello_vue' %> and another <%= javascript_pack_tag 'vue_todo' %> example that demonstrates other capabilities of Vue found in chrisvfritz's vue-webpack branch.

@dleavitt
Copy link
Contributor

Nice! I am a big fan of vue so excited to have progress on this. And gj putting all that error messaging in the generator, future generations will thank you!

I think what's done here is quite excessive for a generator though - it installs an entire Todo app into your Rails app.

  • it modifies the database, adding a model. unless the user wants a Todo model with that schema, it means they'll have to rollback or undo that migration before proceeding. It also adds an implicit dependency on active record. A vue scaffold should not be messing with the db.
  • adds routes and an api endpoint, also things users will have to delete after running the generator. Doesn't add a route to actually test the vue app though, as far as I can tell
  • uses url-loader. file-loader is a better default, and I think using url-loader without file-loader may cause problems for assets too big to be base64'd (try setting a low size limit on url-loader and see what happens)
  • puts all assets under app/javascript/packs. Everything but the entry points should be under app/javascript.
  • puts a png of the vue logo into a gem that's going to be downloaded by everyone who uses rails. Best practices mandate using an image of Guy Fieri instead.

Suggestion:
Make this more like the react and angular generators - just enough to demo the core functionality in a way that's easy to build upon. IMO this would be more like the hello_vue.js entrypoint included here, with the addition of a single .vue file (or a small app that doesn't require server-side interaction.)

Additional functionality beyond the above should be removed and made into a separate app template or a demo app.

@ytbryan
Copy link
Contributor Author

ytbryan commented Feb 24, 2017

Thanks, appreciate the feedback. Will move the todo example to a separate app template.

This edited PR is ready for merging. It now renders a simple "Hello Vue!" with app.vue and hello_vue.js

I also set vue to latest stable version (2.1.10) because the latest (2.2.0.beta1) did not compile well.

Update: Try ./bin/yarn upgrade vue to fix the compilation issue. At the meantime, a PR is scheduled to fix this

Tried to replace url-loader with file-loader but image placed in .vue don't render. So url-loader was left default for now.

@guilleiguaran guilleiguaran merged commit 652afad into rails:master Feb 24, 2017
config = File.read(config_path)

# Module resolution https://webpack.js.org/concepts/module-resolution/
if config.include?("'vue$':'vue/dist/vue.common.js'")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this won't be necessary anymore with Vue v2.2.x https://github.com/vuejs/vue/releases/tag/v2.2.0

Copy link
Contributor Author

@ytbryan ytbryan Feb 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zigomir thanks for informing me. I guess it needs to be updated to 'vue$': 'vue/dist/vue.esm.js' Update: #150

Will send in a PR after I read through the entire vue 2.2.x release. Thanks!

@ankitsinghaniyaz
Copy link

@ytbryan Will this disable my normal views and erb helpers?

@ytbryan
Copy link
Contributor Author

ytbryan commented Mar 8, 2017

@ankitsinghaniyaz can you elaborate and if possible, show with some code?

I don't get what is "this"

@ankitsinghaniyaz
Copy link

ankitsinghaniyaz commented Mar 8, 2017

@ytbryan I mean if I use webpack and vue configuration. Will I still be able to use .html.erb files?

Is there a sample app created using this?

@ytbryan
Copy link
Contributor Author

ytbryan commented Mar 8, 2017

@ankitsinghaniyaz Yes, webpack configuration should not affect your existing erb view files.

@ankitsinghaniyaz try rails new app --webpack=vue

@ankitsinghaniyaz
Copy link

@ytbryan I created a new app, but it will be awesome if I have some guidelines how to structure the code and how to mix it with normal rails templating.

@aalvrz
Copy link

aalvrz commented Mar 10, 2017

Hi @ytbryan great work.

I am having trouble setting this up with a fresh Rails 5.0.2 application.

After creating the application, I add webpacker gem and then bundle:

gem 'webpacker', github: 'rails/webpacker'

Then I run rails webpacker:install and get this:

      create  app/javascript
      create  app/javascript/packs/application.js
       exist  bin
      create  bin/webpack-dev-server
      create  bin/webpack-watcher
      create  bin/webpack
      create  bin/yarn
      create  config/webpack
      create  config/webpack/development.js
      create  config/webpack/production.js
      create  config/webpack/shared.js
      append  .gitignore
         run  ./bin/yarn add webpack webpack-merge path-complete-extname babel-loader babel-core babel-preset-env coffee-loader coffee-script compression-webpack-plugin rails-erb-loader glob from "."
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
         run  ./bin/yarn add --dev webpack-dev-server from "."
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install

At this point it seems that there is something wrong. For some reason this Yarn is not in the system. Anyway, I proceeded to install Vue with rails webpacker:install:vue which results in:

Copying the Vue example to app/javascript/packs/vue
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install

The Vue examples are actually copied to app/javascripts/packs:

app/javascript/packs/
├── app.vue
├── application.js
└── hello_vue.js

0 directories, 3 files

I proceeded to add <%= javascript_pack_tag 'hello_vue' %> to my application.html.erb layout. I get the following errors in the Rails server:

ActionController::RoutingError (No route matches [GET] "/packs/hello_vue.js"):
  
actionpack (5.0.2) lib/action_dispatch/middleware/debug_exceptions.rb:53:in `call'
web-console (3.4.0) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.4.0) lib/web_console/middleware.rb:20:in `block in call'
web-console (3.4.0) lib/web_console/middleware.rb:18:in `catch'
web-console (3.4.0) lib/web_console/middleware.rb:18:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.0.2) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.0.2) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.0.2) lib/active_support/tagged_logging.rb:69:in `block in tagged'
activesupport (5.0.2) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.0.2) lib/active_support/tagged_logging.rb:69:in `tagged'
railties (5.0.2) lib/rails/rack/logger.rb:24:in `call'
sprockets-rails (3.2.0) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/request_id.rb:24:in `call'
rack (2.0.1) lib/rack/method_override.rb:22:in `call'
rack (2.0.1) lib/rack/runtime.rb:22:in `call'
activesupport (5.0.2) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/static.rb:136:in `call'
rack (2.0.1) lib/rack/sendfile.rb:111:in `call'
railties (5.0.2) lib/rails/engine.rb:522:in `call'
puma (3.8.0) lib/puma/configuration.rb:224:in `call'
puma (3.8.0) lib/puma/server.rb:590:in `handle_request'
puma (3.8.0) lib/puma/server.rb:425:in `process_client'
puma (3.8.0) lib/puma/server.rb:289:in `block in run'
puma (3.8.0) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
  Rendering /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb within rescues/layout
  Rendering /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.3ms)
  Rendered collection of /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/routes/_route.html.erb [1 times] (1.6ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/routes/_table.html.erb (16.9ms)
  Rendering /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.5ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb within rescues/layout (68.0ms)

It seems javascript_pack_tag is not pointing to the correct location? Am I missing something here? I am new to webpack/webpacker.

@ytbryan
Copy link
Contributor Author

ytbryan commented Mar 10, 2017

Thanks @BigChief45. You forgot about the ./bin/webpack-dev-server that will serve your assets.

For production, you can also compile assets using rails webpacker:compile

From the readme:

In development, you'll need to run ./bin/webpack-watcher in a separate terminal from ./bin/rails server to have your app/javascript/packs/*.js files compiled as you make changes. If you'd rather not have to run the two processes separately by hand, you can use Foreman.

Alternatively, you can run ./bin/webpack-dev-server. This will launch a Webpack Dev Server listening on http://localhost:8080/ serving your pack files. It will recompile your files as you make changes. You also need to set config.x.webpacker[:dev_server_host] in your config/environments/development.rb to tell Webpacker to load your packs from the Webpack Dev Server. This setup allows you to leverage advanced Webpack features, such as Hot Module Replacement.

Let me know if it works. Also, you can read Gaurav's article on getting started https://medium.com/statuscode/introducing-webpacker-7136d66cddfb#.kyrso4uuc (Especially Step 4 which you are missing)

@aalvrz
Copy link

aalvrz commented Mar 16, 2017

@ytbryan Thanks for your reply.

Figured out a few things. I installed Yarn, updated Node, ran bin/yarn to update some dependencies, and then re-ran the webpacker and webpacker:vue install commands from before. Everything seems to be alright at this point.

In development.rb I set the following configuration:

config.x.webpacker[:dev_server_host] = '0.0.0.0'

Then I run bin/webpacker-dev-server:

Project is running at http://localhost:8080/
webpack output is served from /
Content not from webpack is served from /home/ubuntu/workspace/sample/public/packs
(node:2552) DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see https://github.com/webpack/loader-utils/issues/56
parseQuery() will be replaced with getOptions() in the next major version of loader-utils.
Hash: 817ffe00862acdaea322
Version: webpack 2.2.1
Time: 5466ms
             Asset    Size  Chunks                    Chunk Names
      hello_vue.js  654 kB       0  [emitted]  [big]  hello_vue
    application.js  337 kB       1  [emitted]  [big]  application
  hello_vue.js.map  764 kB       0  [emitted]         hello_vue
application.js.map  375 kB       1  [emitted]         application
chunk    {0} hello_vue.js, hello_vue.js.map (hello_vue) 614 kB [entry] [rendered]
   [34] (webpack)-dev-server/client?http://localhost:8080 5.44 kB {0} {1} [built]
   [50] ./~/sockjs-client/lib/entry.js 244 bytes {0} {1} [built]
   [76] ./~/strip-ansi/index.js 161 bytes {0} {1} [built]
   [78] ./~/url/url.js 23.3 kB {0} {1} [built]
   [79] ./~/url/util.js 314 bytes {0} {1} [built]
   [80] (webpack)-dev-server/client/overlay.js 3.6 kB {0} {1} [built]
   [81] (webpack)-dev-server/client/socket.js 856 bytes {0} {1} [built]
   [83] (webpack)/hot/emitter.js 77 bytes {0} {1} [built]
   [85] ./app/javascript/packs/hello_vue.js 551 bytes {0} [built]
   [86] ./~/babel-loader/lib!./~/vue-loader/lib/selector.js?type=script&index=0!./app/javascript/packs/app.vue 114 bytes {0} [built]
   [93] ./app/javascript/packs/app.vue 1.57 kB {0} [built]
   [94] ./~/vue-loader/lib/component-normalizer.js 1.15 kB {0} [built]
   [96] ./~/vue-style-loader!./~/css-loader?sourceMap!./~/vue-loader/lib/style-rewriter.js?{"id":"data-v-55a08a3f","scoped":true,"hasInlineConfig":false}!./~/vue-loader/lib/selector.js?type=styles&index=0!./app/javascript/packs/app.vue 1.57 kB {0} [built]
   [99] ./~/vue/dist/vue.esm.js 244 kB {0} [built]
  [101] multi (webpack)-dev-server/client?http://localhost:8080 ./app/javascript/packs/hello_vue.js 40 bytes {0} [built]
     + 85 hidden modules
chunk    {1} application.js, application.js.map (application) 301 kB [entry] [rendered]
   [34] (webpack)-dev-server/client?http://localhost:8080 5.44 kB {0} {1} [built]
   [35] ./~/ansi-html/index.js 4.26 kB {0} {1} [built]
   [38] ./~/events/events.js 8.33 kB {0} {1} [built]
   [39] ./~/html-entities/index.js 231 bytes {0} {1} [built]
   [44] ./~/punycode/punycode.js 14.7 kB {0} {1} [built]
   [47] ./~/querystring-es3/index.js 127 bytes {0} {1} [built]
   [50] ./~/sockjs-client/lib/entry.js 244 bytes {0} {1} [built]
   [76] ./~/strip-ansi/index.js 161 bytes {0} {1} [built]
   [78] ./~/url/url.js 23.3 kB {0} {1} [built]
   [79] ./~/url/util.js 314 bytes {0} {1} [built]
   [80] (webpack)-dev-server/client/overlay.js 3.6 kB {0} {1} [built]
   [81] (webpack)-dev-server/client/socket.js 856 bytes {0} {1} [built]
   [83] (webpack)/hot/emitter.js 77 bytes {0} {1} [built]
   [84] ./app/javascript/packs/application.js 515 bytes {1} [built]
  [100] multi (webpack)-dev-server/client?http://localhost:8080 ./app/javascript/packs/application.js 40 bytes {1} [built]
     + 71 hidden modules

WARNING in EnvironmentPlugin - NVM_CD_FLAGS environment variable is undefined.

You can pass an object with default values to suppress this warning.
See https://webpack.js.org/plugins/environment-plugin for example.

Then in a separate terminal, I run the Rails server on port 8081. When I open in the browser I still get a similar error to before, but this time there is a different path in the error message:

Started GET "/javascripts/0.0.0.0/hello_vue.js" for 10.240.0.5 at 2017-03-16 08:38:41 +0000
Cannot render console from 10.240.0.5! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
  
ActionController::RoutingError (No route matches [GET] "/javascripts/0.0.0.0/hello_vue.js"):
  
actionpack (5.0.2) lib/action_dispatch/middleware/debug_exceptions.rb:53:in `call'
web-console (3.4.0) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.4.0) lib/web_console/middleware.rb:20:in `block in call'
web-console (3.4.0) lib/web_console/middleware.rb:18:in `catch'
web-console (3.4.0) lib/web_console/middleware.rb:18:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.0.2) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.0.2) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.0.2) lib/active_support/tagged_logging.rb:69:in `block in tagged'
activesupport (5.0.2) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.0.2) lib/active_support/tagged_logging.rb:69:in `tagged'
railties (5.0.2) lib/rails/rack/logger.rb:24:in `call'
sprockets-rails (3.2.0) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/request_id.rb:24:in `call'
rack (2.0.1) lib/rack/method_override.rb:22:in `call'
rack (2.0.1) lib/rack/runtime.rb:22:in `call'
activesupport (5.0.2) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.0.2) lib/action_dispatch/middleware/static.rb:136:in `call'
rack (2.0.1) lib/rack/sendfile.rb:111:in `call'
railties (5.0.2) lib/rails/engine.rb:522:in `call'
puma (3.8.0) lib/puma/configuration.rb:224:in `call'
puma (3.8.0) lib/puma/server.rb:590:in `handle_request'
puma (3.8.0) lib/puma/server.rb:425:in `process_client'
puma (3.8.0) lib/puma/server.rb:289:in `block in run'
puma (3.8.0) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
  Rendering /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb within rescues/layout
  Rendering /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (7.9ms)
  Rendered collection of /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/routes/_route.html.erb [1 times] (1.6ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/routes/_table.html.erb (1.8ms)
  Rendering /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (8.1ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0@global/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb within rescues/layout (71.5ms)

I feel I'm closer this time, but not sure what else I'm missing here.

@renchap
Copy link
Contributor

renchap commented Mar 16, 2017

This is not correct: config.x.webpacker[:dev_server_host] = '0.0.0.0'

Try with config.x.webpacker[:dev_server_host] = 'http://localhost:8080'

@aalvrz
Copy link

aalvrz commented Mar 17, 2017

@renchap Thanks for chiming in. I tried using that configuration, and while I don't get errors anymore, the Vue component is not displaying the "hello" message.

I am working on a cloud based development environment so I think the localhost configuration might not work. Any chance on running both Rails and Webpack server in 0.0.0.0 under different ports? I tried checking app/config/webpack/development.js for some port option but I can't find any.

Edit

Tried running the webpack dev server with ./bin/webpack-dev-server --host 0.0.0.0 --port 8080.

Then changed the development.rb configuration to:

config.x.webpacker[:dev_server_host] = 'http://0.0.0.0:8080'

Then started Rails in 0.0.0.0 and port 8081. No errors but still can't get Vue to show anything.

@ytbryan
Copy link
Contributor Author

ytbryan commented Mar 17, 2017

@BigChief45 Can you open an issue instead? do you have the repo on github somewhere? Which cloud-based dev environment? Heroku? 😅 Because config.x.webpacker[:dev_server_host] = 'http://localhost:8080' should work on heroku.

Anyway let's take this off this PR request thread. You can open an issue and we can fix it there.

For future issues regarding vue (or react or angular), please open an issue instead. Thank you!

@renchap
Copy link
Contributor

renchap commented Mar 17, 2017

@BigChief45 you can configure the host when launching ./bin/webpack-dev-server :

./bin/webpack-dev-server --host 0.0.0.0

Then you need to change config.x.webpacker[:dev_server_host] to use your cloud based environment IP or hostname (the same you use to connect to rails). 0.0.0.0 is a special IP meaning "listen on every IP on this computer", you can not use it to connect to it.

If you connect to your Rails app using for example http://1.2.3.4:3000, then you need to use http://1.2.3.4:8080 for config.x.webpacker[:dev_server_host]

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

Successfully merging this pull request may close these issues.

7 participants