-
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 static assets support #153
Changes from 3 commits
4625a6a
769cd06
5772382
443eef4
90b2462
bd5c74f
3a7fb6d
64e05e2
57b568a
573baa0
2d9d2de
dca884b
47031e4
539f448
bc12929
524c746
d73ca35
77b1cf5
64e34c0
63ae3cd
e4736d1
bb37152
596e77d
ef48e6f
2b0d4ed
ec86811
101c4f6
5842c70
d7278d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
AllCops: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use the same as rails/rails using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should follow https://github.com/github/rubocop-github and create a gem There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
TargetRubyVersion: 2.2 | ||
# RuboCop has a bunch of cops enabled by default. This setting tells RuboCop | ||
# to ignore them, so only the ones explicitly set in this file are enabled. | ||
DisabledByDefault: true | ||
Exclude: | ||
- 'lib/install/templates/**' | ||
- 'vendor/**/*' | ||
- 'node_modules/**/*' | ||
|
||
# Prefer &&/|| over and/or. | ||
Style/AndOr: | ||
Enabled: true | ||
|
||
# Do not use braces for hash literals when they are the last argument of a | ||
# method call. | ||
Style/BracesAroundHashParameters: | ||
Enabled: true | ||
|
||
# Align `when` with `case`. | ||
Style/CaseIndentation: | ||
Enabled: true | ||
|
||
# Align comments with method definitions. | ||
Style/CommentIndentation: | ||
Enabled: true | ||
|
||
# No extra empty lines. | ||
Style/EmptyLines: | ||
Enabled: true | ||
|
||
# In a regular class definition, no empty lines around the body. | ||
Style/EmptyLinesAroundClassBody: | ||
Enabled: true | ||
|
||
# In a regular method definition, no empty lines around the body. | ||
Style/EmptyLinesAroundMethodBody: | ||
Enabled: true | ||
|
||
# In a regular module definition, no empty lines around the body. | ||
Style/EmptyLinesAroundModuleBody: | ||
Enabled: true | ||
|
||
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }. | ||
Style/HashSyntax: | ||
Enabled: true | ||
|
||
# Method definitions after `private` or `protected` isolated calls need one | ||
# extra level of indentation. | ||
Style/IndentationConsistency: | ||
Enabled: true | ||
EnforcedStyle: rails | ||
|
||
# Two spaces, no tabs (for indentation). | ||
Style/IndentationWidth: | ||
Enabled: true | ||
|
||
Style/SpaceAfterColon: | ||
Enabled: true | ||
|
||
Style/SpaceAfterComma: | ||
Enabled: true | ||
|
||
Style/SpaceAroundEqualsInParameterDefault: | ||
Enabled: true | ||
|
||
Style/SpaceAroundKeyword: | ||
Enabled: true | ||
|
||
Style/SpaceAroundOperators: | ||
Enabled: true | ||
|
||
Style/SpaceBeforeFirstArg: | ||
Enabled: true | ||
|
||
# Defining a method with parameters needs parentheses. | ||
Style/MethodDefParentheses: | ||
Enabled: true | ||
|
||
# Use `foo {}` not `foo{}`. | ||
Style/SpaceBeforeBlockBraces: | ||
Enabled: true | ||
|
||
# Use `foo { bar }` not `foo {bar}`. | ||
Style/SpaceInsideBlockBraces: | ||
Enabled: true | ||
|
||
# Use `{ a: 1 }` not `{a:1}`. | ||
Style/SpaceInsideHashLiteralBraces: | ||
Enabled: true | ||
|
||
Style/SpaceInsideParens: | ||
Enabled: true | ||
|
||
# Check quotes usage according to lint rule below. | ||
Style/StringLiterals: | ||
Enabled: true | ||
EnforcedStyle: double_quotes | ||
|
||
# Detect hard tabs, no hard tabs. | ||
Style/Tab: | ||
Enabled: true | ||
|
||
# Blank lines should not have any spaces. | ||
Style/TrailingBlankLines: | ||
Enabled: true | ||
|
||
# No trailing whitespace. | ||
Style/TrailingWhitespace: | ||
Enabled: true | ||
|
||
# Use quotes for string literals when they are enough. | ||
Style/UnneededPercentQ: | ||
Enabled: true | ||
|
||
# Align `end` with the matching keyword or starting expression except for | ||
# assignments, where it should be aligned with the LHS. | ||
Lint/EndAlignment: | ||
Enabled: true | ||
EnforcedStyleAlignWith: variable | ||
|
||
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg. | ||
Lint/RequireParentheses: | ||
Enabled: true |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,10 +13,12 @@ cache: | |
yarn: true | ||
|
||
install: | ||
- gem install rubocop | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't this get handled by the gemfile? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @justin808 hmm, may be but don't like dependencies. Also, it seems rubocop is more kinda of standalone program now, like yarn and npm There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it should be in the Gemfile. If it is a development dependency, it should be there. |
||
- nvm install node | ||
- node -v | ||
- npm i -g yarn | ||
- yarn | ||
|
||
script: | ||
- yarn lint | ||
- rubocop |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
source 'https://rubygems.org' | ||
source "https://rubygems.org" | ||
|
||
gemspec |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,14 +15,16 @@ Webpacker is currently compatible with Rails 4.2+, but there's no guarantee it w | |
in the future. | ||
|
||
You can either make use of Webpacker during setup of a new application with `--webpack` | ||
or you can add the gem and run `bin/rails webpacker:install` in an existing application. | ||
or you can add the gem and run `./bin/rails webpacker:install` in an existing application. | ||
|
||
As the rubygems version isn't promised to be kept up to date until the release of Rails 5.1, you may want to include the gem directly from GitHub: | ||
|
||
```ruby | ||
gem 'webpacker', github: 'rails/webpacker' | ||
``` | ||
|
||
You can also see a list of available commands by running `./bin/rails webpacker` | ||
|
||
## Binstubs | ||
|
||
Webpacker ships with three binstubs: `./bin/webpack`, `./bin/webpack-watcher` and `./bin/webpack-dev-server`. | ||
|
@@ -78,13 +80,62 @@ app/javascript/calendar/models/month.js | |
But it could also look a million other ways. The only convention that Webpacker enforces is the | ||
one where entry points are automatically configured by the files in `app/javascript/packs`. | ||
|
||
## Advanced Configuration | ||
|
||
By default, webpacker provides simple conventions for where the webpack configs, javascript app files and compiled webpack bundles will go in your rails app, but all these are configurable from package.json that comes with webpacker. You can also configure webpack-dev-server host and port in your development environment | ||
|
||
```json | ||
{ | ||
"config": { | ||
"_comment": "Configure webpacker internals (do not remove)", | ||
"webpacker": { | ||
"srcPath": "app/javascript", | ||
"configPath": "config/webpack", | ||
"nodeModulesPath": "node_modules", | ||
"distDir": "packs", | ||
"distPath": "public/packs", | ||
"manifestFileName": "manifest.json" | ||
}, | ||
"_comment": "Configure webpack-dev-server", | ||
"devServer": { | ||
"enabled": true, | ||
"host": "localhost", | ||
"port": "8080", | ||
"compress": true | ||
} | ||
} | ||
} | ||
``` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When would these configurations differ in the different environments? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It wouldn't actually, but I added just to follow the convention in other files (database.yml) and in case someone gets fancy to change per/env basis. You suggested in another comment to split this in 2 files - perhaps just do this without env and in two files? |
||
|
||
**For ex:** if you rename `packs` directory inside `app/javascript` from `packs` to `bundles`, make sure you also update your `distDir` and `distPath`. | ||
|
||
```json | ||
"webpacker": { | ||
"distDir": "bundles", | ||
"distPath": "public/bundles", | ||
} | ||
``` | ||
|
||
**Note:** Do not delete this config otherwise your app will break, unless you really know what you're doing. | ||
|
||
## Deployment | ||
|
||
To compile all the packs during deployment, you can use the `rails webpacker:compile` command. This | ||
will invoke the production configuration, which includes digesting. The `javascript_pack_tag` helper | ||
method will automatically insert the correct digest when run in production mode. Just like the asset | ||
pipeline does it. | ||
Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`. The `javascript_pack_tag` and `stylesheet_pack_tag` helper method will automatically insert the correct HTML tag for compiled pack. Just like the asset pipeline does it. By default the output will look like this in different environments, | ||
|
||
```html | ||
<!-- In development mode with webpack-dev-server --> | ||
<script src="http://localhost:8080/calendar.js"></script> | ||
<link rel="stylesheet" media="screen" href="http://localhost:8080/calendar.css"> | ||
<!-- In development mode --> | ||
<script src="/packs/calendar.js"></script> | ||
<link rel="stylesheet" media="screen" href="/packs/calendar.css"> | ||
<!-- In production mode --> | ||
<script src="/packs/calendar-0bd141f6d9360cf4a7f5.js"></script> | ||
<link rel="stylesheet" media="screen" href="/packs/calendar-dc02976b5f94b507e3b6.css"> | ||
``` | ||
|
||
**Note:** *`stylesheet_pack_tag` helper is not available out-of-the-box. | ||
Check [statics assets](#ready-for-static-assets) support section for more details.* | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add the |
||
## Linking to sprockets assets | ||
|
||
|
@@ -100,27 +151,54 @@ var railsImagePath = "<%= helpers.image_path('rails.png') %>"; | |
|
||
This is enabled by the `rails-erb-loader` loader rule in `config/webpack/shared.js`. | ||
|
||
## Ready for Static Assets | ||
|
||
Static assets support isn't enabled out-of-the-box. To enable static assets support in your javascript app you will need to run `rails webpacker:install:assets` after you have installed webpacker. Once installed, you can | ||
link static files like images and styles directly into your javascript app code and | ||
have them properly compiled automatically. | ||
|
||
```js | ||
// React component example | ||
// app/javascripts/packs/hello_react.jsx | ||
import React from 'react' | ||
import ReactDOM from 'react-dom' | ||
import clockIcon from '../counter/images/clock.png' | ||
import './hello-react.sass' | ||
|
||
const Hello = props => ( | ||
<div className="hello-react"> | ||
<img src={clockIcon} alt="clock" /> | ||
<p>Hello {props.name}!</p> | ||
</div> | ||
) | ||
``` | ||
|
||
and then within your view, include the `stylesheet_pack_tag` with the name of your pack, | ||
|
||
```erb | ||
<%= stylesheet_pack_tag 'hello_react' %> | ||
``` | ||
|
||
## Ready for React | ||
|
||
To use Webpacker with React, just create a new app with `rails new myapp --webpack=react` (or run `rails webpacker:install:react` on a Rails 5.1 app already setup with webpack), and all the relevant dependencies | ||
To use Webpacker with React, just create a new app with `rails new myapp --webpack=react` (or run `rails webpacker:install:react` on a Rails app already setup with webpacker), and all the relevant dependencies | ||
will be added via yarn and changes to the configuration files made. Now you can create JSX files and | ||
have them properly compiled automatically. | ||
|
||
## Ready for Angular with TypeScript | ||
|
||
To use Webpacker with Angular, just create a new app with `rails new myapp --webpack=angular` (or run `rails webpacker:install:angular` on a Rails 5.1 app already setup with webpack). TypeScript support and the Angular core libraries will be added via yarn and changes to the configuration files made. An example component written in TypeScript is also added to your project in `app/javascript` so that you can experiment Angular right away. | ||
To use Webpacker with Angular, just create a new app with `rails new myapp --webpack=angular` (or run `rails webpacker:install:angular` on a Rails app already setup with webpacker). TypeScript support and the Angular core libraries will be added via yarn and changes to the configuration files made. An example component written in TypeScript is also added to your project in `app/javascript` so that you can experiment Angular right away. | ||
|
||
## Ready for Vue | ||
|
||
To use Webpacker with Vue, just create a new app with `rails new myapp --webpack=vue` (or run `rails webpacker:install:vue` on a Rails 5.1 app already setup with webpack). Vue and its supported libraries will be added via yarn and changes to the configuration files made. An example component is also added to your project in `app/javascript` so that you can experiment Vue right away. | ||
To use Webpacker with Vue, just create a new app with `rails new myapp --webpack=vue` (or run `rails webpacker:install:vue` on a Rails app already setup with webpacker). Vue and its supported libraries will be added via yarn and changes to the configuration files made. An example component is also added to your project in `app/javascript` so that you can experiment Vue right away. | ||
|
||
|
||
## Wishlist | ||
|
||
- Improve process for linking to assets compiled by sprockets - shouldn't need to specify | ||
` <% helpers = ActionController::Base.helpers %>` at the beginning of each file | ||
- Consider chunking setup | ||
- Consider on-demand compiling with digests when digesting=true | ||
|
||
## License | ||
Webpacker is released under the [MIT License](https://opensource.org/licenses/MIT). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,31 @@ | ||
<%= shebang %> | ||
$stdout.sync = true | ||
|
||
require 'shellwords' | ||
require 'json' | ||
|
||
ENV['RAILS_ENV'] ||= 'development' | ||
RAILS_ENV = ENV['RAILS_ENV'] | ||
RAILS_ENV = ENV['RAILS_ENV'] | ||
|
||
ENV['NODE_ENV'] ||= RAILS_ENV | ||
NODE_ENV = ENV['NODE_ENV'] | ||
NODE_ENV = ENV['NODE_ENV'] | ||
|
||
APP_PATH = File.expand_path('../', __dir__) | ||
ESCAPED_APP_PATH = APP_PATH.shellescape | ||
|
||
SET_NODE_PATH = "NODE_PATH=#{ESCAPED_APP_PATH}/node_modules" | ||
WEBPACKER_BIN = "./node_modules/.bin/webpack-dev-server" | ||
WEBPACK_CONFIG = "#{ESCAPED_APP_PATH}/config/webpack/#{NODE_ENV}.js" | ||
|
||
# Warn the user if the configuration is not set | ||
RAILS_ENV_CONFIG = File.join("config", "environments", "#{RAILS_ENV}.rb") | ||
|
||
# Look into the environment file for a non-commented variable declaration | ||
unless File.foreach(File.join(APP_PATH, RAILS_ENV_CONFIG)).detect { |line| line.match(/^\s*[^#]*config\.x\.webpacker\[\:dev_server_host\].*=/) } | ||
puts "Warning: if you want to use webpack-dev-server, you need to tell Webpacker to serve asset packs from it. Please set config.x.webpacker[:dev_server_host] in #{RAILS_ENV_CONFIG}.\n\n" | ||
begin | ||
config = JSON.parse(File.read(File.join(APP_PATH, 'package.json'))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a CR after this. |
||
NODE_MODULES_PATH = File.join(APP_PATH.shellescape, config['webpacker']['nodeModulesPath']) | ||
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, config['webpacker']['configPath']) | ||
PACKS_PATH = File.join(APP_PATH.shellescape, config['webpacker']['distPath']) | ||
WEBPACK_BIN = "#{NODE_MODULES_PATH}/.bin/webpack-dev-server" | ||
WEBPACK_CONFIG = "#{WEBPACK_CONFIG_PATH}/development.server.js" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Align the assignment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ohh, my bad. Will fix 👍 |
||
rescue Errno::ENOENT, NoMethodError | ||
puts 'Package.json or [webpacker, devServer] config key not found.' | ||
puts 'Please run bundle exec rails webpacker:install to install webpacker' | ||
exit! | ||
end | ||
|
||
Dir.chdir(APP_PATH) do | ||
exec "#{SET_NODE_PATH} #{WEBPACKER_BIN} --config #{WEBPACK_CONFIG} --content-base #{ESCAPED_APP_PATH}/public/packs #{ARGV.join(" ")}" | ||
exec "NODE_PATH=#{NODE_MODULES_PATH} #{WEBPACK_BIN} " \ | ||
"--config #{WEBPACK_CONFIG} --content-base #{PACKS_PATH} #{ARGV.join(" ")}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Let's read that from the package.json rather than having the shell script read it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
<%= shebang %> | ||
$stdout.sync = true | ||
|
||
require 'shellwords' | ||
require 'json' | ||
|
||
ENV['RAILS_ENV'] ||= 'development' | ||
RAILS_ENV = ENV['RAILS_ENV'] | ||
|
@@ -8,12 +11,21 @@ ENV['NODE_ENV'] ||= RAILS_ENV | |
NODE_ENV = ENV['NODE_ENV'] | ||
|
||
APP_PATH = File.expand_path('../', __dir__) | ||
ESCAPED_APP_PATH = APP_PATH.shellescape | ||
|
||
SET_NODE_PATH = "NODE_PATH=#{ESCAPED_APP_PATH}/node_modules" | ||
WEBPACK_BIN = "./node_modules/webpack/bin/webpack.js" | ||
WEBPACK_CONFIG = "#{ESCAPED_APP_PATH}/config/webpack/#{NODE_ENV}.js" | ||
begin | ||
config = JSON.parse(File.read(File.join(APP_PATH, 'package.json'))) | ||
NODE_MODULES_PATH = File.join(APP_PATH.shellescape, config['webpacker']['nodeModulesPath']) | ||
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, config['webpacker']['configPath']) | ||
rescue Errno::ENOENT, NoMethodError | ||
puts 'Package.json or [webpacker, devServer] config key not found.' | ||
puts 'Please run bundle exec rails webpacker:install to install webpacker' | ||
exit! | ||
end | ||
|
||
WEBPACK_BIN = "#{NODE_MODULES_PATH}/.bin/webpack" | ||
WEBPACK_CONFIG = "#{WEBPACK_CONFIG_PATH}/#{NODE_ENV}.js" | ||
|
||
Dir.chdir(APP_PATH) do | ||
exec "#{SET_NODE_PATH} #{WEBPACK_BIN} --config #{WEBPACK_CONFIG} #{ARGV.join(" ")}" | ||
exec "NODE_PATH=#{NODE_MODULES_PATH} #{WEBPACK_BIN} --config #{WEBPACK_CONFIG}" \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see comments from prior file |
||
" #{ARGV.join(" ")}" | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome to have rubocop!