{"action":"created","issue":{"url":"https://api.github.com/repos/rails/webpacker/issues/153","repository_url":"https://api.github.com/repos/rails/webpacker","labels_url":"https://api.github.com/repos/rails/webpacker/issues/153/labels{/name}","comments_url":"https://api.github.com/repos/rails/webpacker/issues/153/comments","events_url":"https://api.github.com/repos/rails/webpacker/issues/153/events","html_url":"https://github.com/rails/webpacker/pull/153","id":211458122,"number":153,"title":"Add static assets support","user":{"login":"gauravtiwari","id":771039,"avatar_url":"https://avatars1.githubusercontent.com/u/771039?v=3","gravatar_id":"","url":"https://api.github.com/users/gauravtiwari","html_url":"https://github.com/gauravtiwari","followers_url":"https://api.github.com/users/gauravtiwari/followers","following_url":"https://api.github.com/users/gauravtiwari/following{/other_user}","gists_url":"https://api.github.com/users/gauravtiwari/gists{/gist_id}","starred_url":"https://api.github.com/users/gauravtiwari/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gauravtiwari/subscriptions","organizations_url":"https://api.github.com/users/gauravtiwari/orgs","repos_url":"https://api.github.com/users/gauravtiwari/repos","events_url":"https://api.github.com/users/gauravtiwari/events{/privacy}","received_events_url":"https://api.github.com/users/gauravtiwari/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":25,"created_at":"2017-03-02T17:15:42Z","updated_at":"2017-03-13T01:23:46Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rails/webpacker/pulls/153","html_url":"https://github.com/rails/webpacker/pull/153","diff_url":"https://github.com/rails/webpacker/pull/153.diff","patch_url":"https://github.com/rails/webpacker/pull/153.patch"},"body":"### Major Changes\r\n- [x] Use package.json to pass configuration options to rails and webpack. It seems like this is the best option, because both ruby and javascript has great support for JSON. Removed all configurations from Rails environment file. \r\n![screen shot 2017-03-05 at 13 16 01](https://cloud.githubusercontent.com/assets/771039/23587512/ef08a29e-01a5-11e7-9219-6af3dbb496da.png)\r\n\r\nThere is also an extra `ENV[\"DEV_SERVER_ENABLED\"]` to enable and disable dev server mode.\r\n\r\n```js\r\n// In webpack configs\r\nconst { webpacker } = require('../../package.json')\r\n\r\nconst distDir = webpacker.distDir\r\nconst distPath = webpacker.distPath\r\nconst srcDir = webpacker.srcDir\r\nconst nodeModulesDir = webpacker.nodeModulesDir\r\nconst digestFile = webpacker.digestFile\r\n```\r\n\r\n```rb\r\n# In ruby\r\n  def parse\r\n    if File.exist?(path)\r\n      package_json = JSON.parse(File.read(path))\r\n      HashWithIndifferentAccess.new(package_json)\r\n    else\r\n      raise PackageJsonError, \"Didn't find any package.json file at #{path}. \" \\\r\n      \"You must first install webpacker via rails webpacker:install\"\r\n    end\r\n  end\r\n```\r\n\r\n- [x]  Added a new task `webpacker:install:assets` to install static assets loaders on-demand. The webpack configuration is much more dry and makes sense. Static asset configuration lives in a separate file and it's installed and loaded when asked,\r\n\r\n```js\r\nconst { webpacker } = require('../../package.json')\r\nif (webpacker.assets) {\r\n  const assetsConfig = require('./assets.js')\r\n  sharedConfig.config = merge(sharedConfig.config, assetsConfig)\r\n}\r\n```\r\n\r\n```js\r\nimport React from 'react'\r\nimport ReactDOM from 'react-dom'\r\nimport clockIcon from '../counter/images/clock.png';\r\nimport './hello-react.sass'\r\n\r\nconst Hello = props => (\r\n  <div className=\"hello-react\">\r\n    <img src={clockIcon} alt=\"clock\" />\r\n    <p>Hello {props.name}!</p>\r\n  </div>\r\n)\r\n```\r\n\r\n- [x]  Use manifest plugin to generate digests and cleanup webpacker:compile task. \r\n\r\n```js\r\nnew ManifestPlugin({\r\n    fileName: manifestFileName,\r\n    publicPath: `/${distDir}/`\r\n})\r\n```\r\n\r\n```json\r\n{\r\n  \"application.js\": \"/packs/application-61c89ec4d430372bfdbf.js\",\r\n  \"clock.png\": \"/packs/clock-fc31531de5cc3518c7c658d5b83faa72.png\",\r\n  \"counter.css\": \"/packs/counter-3b38e8aeca5758f7f296.css\",\r\n  \"counter.js\": \"/packs/counter-0bd141f6d9360cf4a7f5.js\",\r\n  \"hello_react.css\": \"/packs/hello_react-3b38e8aeca5758f7f296.css\",\r\n  \"hello_react.js\": \"/packs/hello_react-447e04580529cf7a332b.js\",\r\n  \"lacuna-webfont.eot\": \"/packs/lacuna-webfont-54c0d12c6ab265792f0d8cfd81e481e4.eot\",\r\n  \"lacuna-webfont.svg\": \"/packs/lacuna-webfont-4291fc75d6240959b4abe83809c90350.svg\",\r\n  \"lacuna-webfont.ttf\": \"/packs/lacuna-webfont-1acb63487c4a72f7fd2e545d2e0090e2.ttf\",\r\n  \"lacuna-webfont.woff\": \"/packs/lacuna-webfont-0eb6add367ef5fc69c4569894525bd52.woff\"\r\n}\r\n```\r\n\r\n```json\r\n{\r\n  \"application.js\": \"/packs/application.js\",\r\n  \"application.js.map\": \"/packs/application.js.map\",\r\n  \"clock.png\": \"/packs/clock.png\",\r\n  \"counter.css\": \"/packs/counter.css\",\r\n  \"counter.css.map\": \"/packs/counter.css.map\",\r\n  \"counter.js\": \"/packs/counter.js\",\r\n  \"counter.js.map\": \"/packs/counter.js.map\",\r\n  \"hello_react.css\": \"/packs/hello_react.css\",\r\n  \"hello_react.css.map\": \"/packs/hello_react.css.map\",\r\n  \"hello_react.js\": \"/packs/hello_react.js\",\r\n  \"hello_react.js.map\": \"/packs/hello_react.js.map\",\r\n  \"lacuna-webfont.eot\": \"/packs/lacuna-webfont.eot\",\r\n  \"lacuna-webfont.svg\": \"/packs/lacuna-webfont.svg\",\r\n  \"lacuna-webfont.ttf\": \"/packs/lacuna-webfont.ttf\",\r\n  \"lacuna-webfont.woff\": \"/packs/lacuna-webfont.woff\"\r\n}\r\n```\r\n\r\n- [x]  Add a new stylesheet pack tag helper tag to helper.rb\r\n\r\n```rb\r\n def stylesheet_pack_tag(name, **options)\r\n    webpacker_config = Webpacker::Configuration.webpacker\r\n    unless webpacker_config[:assets]\r\n      raise StandardError, \"Stylesheet support isn't enabled. Install using - webpacker:install:assets\"\r\n    end\r\n\r\n    stylesheet_link_tag(Webpacker::Source.new(\"#{File.basename(name, '.css')}.css\").path, **options)\r\nend\r\n```\r\n\r\n```rb\r\n<%= stylesheet_pack_tag 'hello_react' %>\r\n```\r\n\r\n- [x]  Adjust source lookup class so it works with both stylesheet and javascript. Use manifest to lookup files in all environments, except with webpack dev server is enabled,\r\n\r\n\r\n```ruby\r\n  def path\r\n    if Rails.env.development? && dev_server_enabled?\r\n      \"http://#{dev_server[:host]}:#{dev_server[:port]}/#{filename}\"\r\n    else\r\n      Webpacker::Manifest.lookup(filename)\r\n    end\r\n  end\r\n```\r\n\r\n### Minor updates\r\n- [x]  Update Readme with new changes\r\n- [x]  Add rubocop from rails repo and lint everything [as per rails setup]\r\n- [x]  Add rubocop to travis\r\n- [x] Filter undefined env variables\r\n- [x] Add a separate version file\r\n\r\nDemo: [https://webpacker-example-app.herokuapp.com/](https://webpacker-example-app.herokuapp.com/)\r\n\r\nUsing package.json as a common configuration file makes the setup simple and configurable. I  initially thought to use a separate file  for webpacker config, but since package.json is there it would make sense to just use that.  Initially, I did some hack to read `dev_server_host` from development.rb, but it was very brittle. As discussed in #109, there is no out-of-box integration for styles etc. with webpacker but it's available using a separate task (`bundle exec rails webpacker:install:assets`) like we have react and such. The rest of the setup is mostly same as before, just more configurable. \r\n\r\nI made some out-of-scope changes like linting. Since, this involved touching a lot of files, I thought it would make sense to do it now. Sorry :)\r\n\r\n@dhh @dleavitt @guilleiguaran Please review when you get a chance ❤️ . Obviously, there might be some things that I have missed and sorry if I trespassed 😄 \r\n\r\n----\r\n\r\n### To try this out locally,\r\n\r\n```bash\r\nrails new webpacker-app\r\n```\r\nOpen up the gemfile and add \r\n\r\n```ruby\r\ngem 'webpacker', github: 'gauravtiwari/webpacker', branch: 'feature/static-assets'\r\n```\r\n\r\nrun `bundle install` then,\r\n\r\n```bash\r\nbundle exec rails webpacker:install\r\n\r\n# All or one (optional)\r\nbundle exec rails webpacker:install:react\r\nbundle exec rails webpacker:install:angular\r\nbundle exec rails webpacker:install:vue\r\n\r\n# To add static assets support\r\nbundle exec rails webpacker:install:assets\r\nbundle exec rails g controller pages index\r\n```\r\n\r\nIn `config/routes.rb`\r\n\r\n```ruby\r\nroot to: 'pages#index'\r\n```\r\n\r\nOpen up view pages/index.html.erb\r\n```erb\r\n<h1>Pages#index</h1>\r\n<p>Find me in app/views/pages/index.html.erb</p>\r\n<%= javascript_pack_tag 'application' %>\r\n<%= javascript_pack_tag 'hello_react' %>\r\n<hello-angular>Loading...</hello-angular>\r\n<%= javascript_pack_tag 'hello_angular' %>\r\n<%= javascript_pack_tag 'hello_vue' %>\r\n<%= stylesheet_pack_tag 'hello_react' %>\r\n```\r\n\r\nFinally, run webpack-watcher in one terminal window,\r\n\r\n```bash\r\n./bin/webpack-watcher \r\n```\r\n\r\nand in other,\r\n\r\n```bash\r\nbundle exec rails s\r\n```\r\n\r\nGo to [http://localhost:3000](http://localhost:3000]) to see all example apps running. Now, to test out styles,\r\n\r\nin app/javascript/packs, create a file called hello_react.sass\r\n\r\n```sass\r\n.hello-react\r\n  max-width: 500px\r\n  margin: 0 auto\r\n``` \r\n\r\nadd a className to react example,\r\n\r\n```js\r\nconst Hello = props => (\r\n  <div className=\"hello-react\">Hello {props.name}!</div>\r\n)\r\n```\r\n\r\nand finally, add `<%= stylesheet_pack_tag 'hello_react' %>` to pages/index.html.erb\r\n\r\nReload the browser and Voila!\r\n\r\n-----\r\n\r\n### Deploy it to heroku\r\n\r\nReplace `sqlite` gem with `pg`\r\n\r\n```bash\r\n# From terminal in order\r\nbundle install\r\ngit init && git add . && git commit -am \"Webpacker demo\"\r\nheroku create \r\nheroku buildpacks:add --index 1 heroku/nodejs\r\nheroku buildpacks:add --index 2 heroku/ruby\r\nheroku addons:create heroku-postgresql:hobby-dev\r\ngit push heroku master\r\n```\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/rails/webpacker/issues/comments/285995059","html_url":"https://github.com/rails/webpacker/pull/153#issuecomment-285995059","issue_url":"https://api.github.com/repos/rails/webpacker/issues/153","id":285995059,"user":{"login":"justin808","id":1118459,"avatar_url":"https://avatars1.githubusercontent.com/u/1118459?v=3","gravatar_id":"","url":"https://api.github.com/users/justin808","html_url":"https://github.com/justin808","followers_url":"https://api.github.com/users/justin808/followers","following_url":"https://api.github.com/users/justin808/following{/other_user}","gists_url":"https://api.github.com/users/justin808/gists{/gist_id}","starred_url":"https://api.github.com/users/justin808/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justin808/subscriptions","organizations_url":"https://api.github.com/users/justin808/orgs","repos_url":"https://api.github.com/users/justin808/repos","events_url":"https://api.github.com/users/justin808/events{/privacy}","received_events_url":"https://api.github.com/users/justin808/received_events","type":"User","site_admin":false},"created_at":"2017-03-13T01:23:45Z","updated_at":"2017-03-13T01:23:45Z","body":"> That means once people move on to Rails 5.1 and start to use webpacker then a breaking change like this will have to wait for Rails 6.x unless I'm missing something.\r\n\r\n@nickpith  Good reason to set the config now, either json or yml, and not JavaScript or Ruby or ENV."}}
{"actor":{"display_login":"justin808"}}