webpacker 2.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +21 -21
- data/CHANGELOG.md +107 -4
- data/Gemfile +3 -1
- data/Gemfile.lock +15 -8
- data/README.md +137 -937
- data/docs/assets.md +106 -0
- data/docs/css.md +82 -0
- data/docs/deployment.md +39 -0
- data/docs/env.md +62 -0
- data/docs/es6.md +53 -0
- data/docs/folder-structure.md +66 -0
- data/docs/misc.md +23 -0
- data/docs/props.md +105 -0
- data/docs/testing.md +45 -0
- data/docs/troubleshooting.md +65 -0
- data/docs/typescript.md +115 -0
- data/docs/webpack-dev-server.md +32 -0
- data/docs/webpack.md +108 -0
- data/docs/yarn.md +12 -0
- data/lib/install/angular.rb +4 -7
- data/lib/install/bin/webpack-dev-server.tt +35 -11
- data/lib/install/bin/webpack.tt +3 -4
- data/lib/install/config/.babelrc +1 -0
- data/lib/install/config/.postcssrc.yml +1 -2
- data/lib/install/config/webpack/development.js +2 -31
- data/lib/install/config/webpack/environment.js +3 -0
- data/lib/install/config/webpack/production.js +2 -34
- data/lib/install/config/webpack/test.js +2 -5
- data/lib/install/config/webpacker.yml +20 -2
- data/lib/install/elm.rb +6 -11
- data/lib/install/examples/vue/hello_vue.js +31 -2
- data/lib/install/react.rb +2 -5
- data/lib/install/template.rb +3 -8
- data/lib/install/vue.rb +4 -7
- data/lib/tasks/webpacker.rake +1 -1
- data/lib/tasks/webpacker/{check_webpack_binstubs.rake → check_binstubs.rake} +3 -2
- data/lib/tasks/webpacker/check_node.rake +8 -6
- data/lib/tasks/webpacker/check_yarn.rake +2 -2
- data/lib/tasks/webpacker/clobber.rake +2 -3
- data/lib/tasks/webpacker/compile.rake +16 -18
- data/lib/tasks/webpacker/verify_install.rake +5 -5
- data/lib/tasks/webpacker/yarn_install.rake +1 -1
- data/lib/webpacker.rb +15 -11
- data/lib/webpacker/commands.rb +22 -0
- data/lib/webpacker/compiler.rb +66 -10
- data/lib/webpacker/configuration.rb +54 -38
- data/lib/webpacker/dev_server.rb +47 -0
- data/lib/webpacker/dev_server_proxy.rb +24 -0
- data/lib/webpacker/helper.rb +23 -5
- data/lib/webpacker/instance.rb +44 -0
- data/lib/webpacker/manifest.rb +58 -34
- data/lib/webpacker/railtie.rb +22 -3
- data/lib/webpacker/version.rb +2 -1
- data/package.json +37 -7
- data/package/asset_host.js +21 -0
- data/package/config.js +8 -0
- data/package/environment.js +95 -0
- data/package/environments/development.js +47 -0
- data/package/environments/production.js +34 -0
- data/package/environments/test.js +3 -0
- data/package/index.js +16 -0
- data/package/loaders/babel.js +11 -0
- data/{lib/install/config/loaders/core → package/loaders}/coffee.js +0 -0
- data/{lib/install/config/loaders/installers → package/loaders}/elm.js +4 -5
- data/{lib/install/config/loaders/core → package/loaders}/erb.js +0 -0
- data/package/loaders/file.js +15 -0
- data/package/loaders/style.js +31 -0
- data/{lib/install/config/loaders/installers/angular.js → package/loaders/typescript.js} +1 -1
- data/package/loaders/vue.js +12 -0
- data/test/compiler_test.rb +20 -0
- data/test/configuration_test.rb +43 -19
- data/test/dev_server_test.rb +24 -0
- data/test/helper_test.rb +21 -5
- data/test/manifest_test.rb +25 -19
- data/test/test_app/public/packs/manifest.json +3 -1
- data/test/webpacker_test_helper.rb +40 -0
- data/webpacker.gemspec +1 -1
- data/yarn.lock +4701 -578
- metadata +52 -29
- data/lib/install/config/loaders/core/assets.js +0 -12
- data/lib/install/config/loaders/core/babel.js +0 -5
- data/lib/install/config/loaders/core/sass.js +0 -15
- data/lib/install/config/loaders/installers/react.js +0 -5
- data/lib/install/config/loaders/installers/vue.js +0 -13
- data/lib/install/config/webpack/configuration.js +0 -35
- data/lib/install/config/webpack/shared.js +0 -58
- data/lib/webpacker/env.rb +0 -23
- data/lib/webpacker/file_loader.rb +0 -24
- data/test/env_test.rb +0 -14
- data/test/webpacker_test.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d46b2ad0a755995989397dd57d6a3f62fd8b6e29
|
4
|
+
data.tar.gz: 3bc409359bdb19b000d18a85e43d5e32c53c2160
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6b403b49ea4bd344acb77cf3d02f4d05cee50ace386f05d598f70583ba6f19d3f6114fcec33944e46dd8d7bbaccf6590598225ec0d6159168fe1d016844f9d6
|
7
|
+
data.tar.gz: 48d1d6686da5d7a9127bff68a26827e95c772b6f7966960b9ee0000707c0579b86db76bfae232dd4cfb74fbfc062b24940147eae270058f8bb8bcdf4ee4cf75c
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -18,27 +18,27 @@ Style/BracesAroundHashParameters:
|
|
18
18
|
Enabled: true
|
19
19
|
|
20
20
|
# Align `when` with `case`.
|
21
|
-
|
21
|
+
Layout/CaseIndentation:
|
22
22
|
Enabled: true
|
23
23
|
|
24
24
|
# Align comments with method definitions.
|
25
|
-
|
25
|
+
Layout/CommentIndentation:
|
26
26
|
Enabled: true
|
27
27
|
|
28
28
|
# No extra empty lines.
|
29
|
-
|
29
|
+
Layout/EmptyLines:
|
30
30
|
Enabled: true
|
31
31
|
|
32
32
|
# In a regular class definition, no empty lines around the body.
|
33
|
-
|
33
|
+
Layout/EmptyLinesAroundClassBody:
|
34
34
|
Enabled: true
|
35
35
|
|
36
36
|
# In a regular method definition, no empty lines around the body.
|
37
|
-
|
37
|
+
Layout/EmptyLinesAroundMethodBody:
|
38
38
|
Enabled: true
|
39
39
|
|
40
40
|
# In a regular module definition, no empty lines around the body.
|
41
|
-
|
41
|
+
Layout/EmptyLinesAroundModuleBody:
|
42
42
|
Enabled: true
|
43
43
|
|
44
44
|
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
@@ -47,30 +47,30 @@ Style/HashSyntax:
|
|
47
47
|
|
48
48
|
# Method definitions after `private` or `protected` isolated calls need one
|
49
49
|
# extra level of indentation.
|
50
|
-
|
50
|
+
Layout/IndentationConsistency:
|
51
51
|
Enabled: true
|
52
52
|
EnforcedStyle: rails
|
53
53
|
|
54
54
|
# Two spaces, no tabs (for indentation).
|
55
|
-
|
55
|
+
Layout/IndentationWidth:
|
56
56
|
Enabled: true
|
57
57
|
|
58
|
-
|
58
|
+
Layout/SpaceAfterColon:
|
59
59
|
Enabled: true
|
60
60
|
|
61
|
-
|
61
|
+
Layout/SpaceAfterComma:
|
62
62
|
Enabled: true
|
63
63
|
|
64
|
-
|
64
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
65
65
|
Enabled: true
|
66
66
|
|
67
|
-
|
67
|
+
Layout/SpaceAroundKeyword:
|
68
68
|
Enabled: true
|
69
69
|
|
70
|
-
|
70
|
+
Layout/SpaceAroundOperators:
|
71
71
|
Enabled: true
|
72
72
|
|
73
|
-
|
73
|
+
Layout/SpaceBeforeFirstArg:
|
74
74
|
Enabled: true
|
75
75
|
|
76
76
|
# Defining a method with parameters needs parentheses.
|
@@ -78,18 +78,18 @@ Style/MethodDefParentheses:
|
|
78
78
|
Enabled: true
|
79
79
|
|
80
80
|
# Use `foo {}` not `foo{}`.
|
81
|
-
|
81
|
+
Layout/SpaceBeforeBlockBraces:
|
82
82
|
Enabled: true
|
83
83
|
|
84
84
|
# Use `foo { bar }` not `foo {bar}`.
|
85
|
-
|
85
|
+
Layout/SpaceInsideBlockBraces:
|
86
86
|
Enabled: true
|
87
87
|
|
88
88
|
# Use `{ a: 1 }` not `{a:1}`.
|
89
|
-
|
89
|
+
Layout/SpaceInsideHashLiteralBraces:
|
90
90
|
Enabled: true
|
91
91
|
|
92
|
-
|
92
|
+
Layout/SpaceInsideParens:
|
93
93
|
Enabled: true
|
94
94
|
|
95
95
|
# Check quotes usage according to lint rule below.
|
@@ -98,15 +98,15 @@ Style/StringLiterals:
|
|
98
98
|
EnforcedStyle: double_quotes
|
99
99
|
|
100
100
|
# Detect hard tabs, no hard tabs.
|
101
|
-
|
101
|
+
Layout/Tab:
|
102
102
|
Enabled: true
|
103
103
|
|
104
104
|
# Blank lines should not have any spaces.
|
105
|
-
|
105
|
+
Layout/TrailingBlankLines:
|
106
106
|
Enabled: true
|
107
107
|
|
108
108
|
# No trailing whitespace.
|
109
|
-
|
109
|
+
Layout/TrailingWhitespace:
|
110
110
|
Enabled: true
|
111
111
|
|
112
112
|
# Use quotes for string literals when they are enough.
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,102 @@
|
|
1
|
-
## [
|
1
|
+
## [3.0.0] - 2017-08-30
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
- `resolved_paths` option to allow adding additional paths webpack should lookup when resolving modules
|
6
|
+
|
7
|
+
```yml
|
8
|
+
# config/webpacker.yml
|
9
|
+
# Additional paths webpack should lookup modules
|
10
|
+
resolved_paths: [] # empty by default
|
11
|
+
```
|
12
|
+
|
13
|
+
- `Webpacker::Compiler.fresh?` and `Webpacker::Compiler.stale?` answer the question of whether compilation is needed.
|
14
|
+
The old `Webpacker::Compiler.compile?` predicate is deprecated.
|
15
|
+
|
16
|
+
- Dev server config class that exposes config options through singleton.
|
17
|
+
|
18
|
+
```rb
|
19
|
+
Webpacker.dev_server.running?
|
20
|
+
```
|
21
|
+
|
22
|
+
- Rack middleware proxies webpacker requests to dev server so we can always serve from same-origin and the lookup works out of the box - no more paths prefixing
|
23
|
+
|
24
|
+
- `env` attribute on `Webpacker::Compiler` allows setting custom environment variables that the compilation is being run with
|
25
|
+
|
26
|
+
```rb
|
27
|
+
Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
|
28
|
+
```
|
29
|
+
|
30
|
+
### Breaking changes
|
31
|
+
|
32
|
+
**Note:** requires running `bundle exec rails webpacker:install`
|
33
|
+
|
34
|
+
`config/webpack/**/*.js`:
|
35
|
+
|
36
|
+
- The majority of this config moved to the [@rails/webpacker npm package](https://www.npmjs.com/package/@rails/webpacker). `webpacker:install` only creates `config/webpack/{environment,development,test,production}.js` now so if you're upgrading from a previous version you can remove all other files.
|
37
|
+
|
38
|
+
`webpacker.yml`:
|
39
|
+
|
40
|
+
- Move dev-server config options under defaults so it's transparently available in all environments
|
41
|
+
|
42
|
+
- Add new `HMR` option for hot-module-replacement
|
43
|
+
|
44
|
+
- Add HTTPS
|
45
|
+
|
46
|
+
### Removed
|
47
|
+
|
48
|
+
- Host info from manifest.json, now looks like this:
|
49
|
+
|
50
|
+
```json
|
51
|
+
{
|
52
|
+
"hello_react.js": "/packs/hello_react.js"
|
53
|
+
}
|
54
|
+
```
|
55
|
+
|
56
|
+
### Fixed
|
57
|
+
|
58
|
+
- Update `webpack-dev-server.tt` to respect RAILS_ENV and NODE_ENV values [#502](https://github.com/rails/webpacker/issues/502)
|
59
|
+
- Use `0.0.0.0` as default listen address for `webpack-dev-server`
|
60
|
+
- Serve assets using `localhost` from dev server - [#424](https://github.com/rails/webpacker/issues/424)
|
61
|
+
|
62
|
+
```yml
|
63
|
+
dev_server:
|
64
|
+
host: localhost
|
65
|
+
```
|
66
|
+
|
67
|
+
- On Windows, `ruby bin/webpacker` and `ruby bin/webpacker-dev-server` will now bypass yarn, and execute via `node_modules/.bin` directly - [#584](https://github.com/rails/webpacker/pull/584)
|
68
|
+
|
69
|
+
### Breaking changes
|
70
|
+
|
71
|
+
- Add `compile` option to `config/webpacker.yml` for configuring lazy compilation of packs when a file under tracked paths is changed [#503](https://github.com/rails/webpacker/pull/503). To enable expected behavior, update `config/webpacker.yml`:
|
2
72
|
|
73
|
+
```yaml
|
74
|
+
test:
|
75
|
+
compile: true
|
76
|
+
|
77
|
+
development:
|
78
|
+
compile: true
|
79
|
+
|
80
|
+
production:
|
81
|
+
compile: false
|
82
|
+
```
|
83
|
+
|
84
|
+
- Make test compilation cacheable and configurable so that the lazy compilation
|
85
|
+
only triggers if files are changed under tracked paths.
|
86
|
+
Following paths are watched by default -
|
87
|
+
|
88
|
+
```rb
|
89
|
+
["app/javascript/**/*", "yarn.lock", "package.json", "config/webpack/**/*"]
|
90
|
+
```
|
91
|
+
|
92
|
+
To add more paths:
|
93
|
+
|
94
|
+
```rb
|
95
|
+
# config/initializers/webpacker.rb or config/application.rb
|
96
|
+
Webpacker::Compiler.watched_paths << 'bower_components'
|
97
|
+
```
|
98
|
+
|
99
|
+
## [2.0] - 2017-05-24
|
3
100
|
|
4
101
|
### Fixed
|
5
102
|
- Update `.babelrc` to fix compilation issues - [#306](https://github.com/rails/webpacker/issues/306)
|
@@ -69,11 +166,17 @@
|
|
69
166
|
bundle exec rails webpacker:install
|
70
167
|
|
71
168
|
# Remove old/unused configuration files
|
72
|
-
rm config/paths.yml
|
73
|
-
rm config/development.server.yml
|
74
|
-
rm config/development.server.js
|
169
|
+
rm config/webpack/paths.yml
|
170
|
+
rm config/webpack/development.server.yml
|
171
|
+
rm config/webpack/development.server.js
|
75
172
|
```
|
76
173
|
|
174
|
+
__Warning__: For now you also have to add a pattern in `.gitignore` by hand.
|
175
|
+
```diff
|
176
|
+
/public/packs
|
177
|
+
+/public/packs-test
|
178
|
+
/node_modules
|
179
|
+
```
|
77
180
|
|
78
181
|
## [1.2] - 2017-04-27
|
79
182
|
Some of the changes made requires you to run below commands to install new changes.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
webpacker (
|
4
|
+
webpacker (2.0)
|
5
5
|
activesupport (>= 4.2)
|
6
|
-
|
6
|
+
rack-proxy (>= 0.6.1)
|
7
7
|
railties (>= 4.2)
|
8
8
|
|
9
9
|
GEM
|
@@ -49,6 +49,7 @@ GEM
|
|
49
49
|
arel (7.1.4)
|
50
50
|
ast (2.3.0)
|
51
51
|
builder (3.2.3)
|
52
|
+
byebug (9.0.6)
|
52
53
|
concurrent-ruby (1.0.5)
|
53
54
|
erubis (2.7.0)
|
54
55
|
globalid (0.3.7)
|
@@ -64,14 +65,16 @@ GEM
|
|
64
65
|
mime-types-data (3.2016.0521)
|
65
66
|
mini_portile2 (2.1.0)
|
66
67
|
minitest (5.10.1)
|
67
|
-
multi_json (1.12.1)
|
68
68
|
nio4r (1.2.1)
|
69
69
|
nokogiri (1.7.0.1)
|
70
70
|
mini_portile2 (~> 2.1.0)
|
71
|
+
parallel (1.12.0)
|
71
72
|
parser (2.4.0.0)
|
72
73
|
ast (~> 2.2)
|
73
74
|
powerpack (0.1.1)
|
74
75
|
rack (2.0.1)
|
76
|
+
rack-proxy (0.6.1)
|
77
|
+
rack
|
75
78
|
rack-test (0.6.3)
|
76
79
|
rack (>= 1.0)
|
77
80
|
rails (5.0.1)
|
@@ -97,9 +100,11 @@ GEM
|
|
97
100
|
method_source
|
98
101
|
rake (>= 0.8.7)
|
99
102
|
thor (>= 0.18.1, < 2.0)
|
100
|
-
rainbow (2.2.
|
103
|
+
rainbow (2.2.2)
|
104
|
+
rake
|
101
105
|
rake (12.0.0)
|
102
|
-
rubocop (0.
|
106
|
+
rubocop (0.49.1)
|
107
|
+
parallel (~> 1.10)
|
103
108
|
parser (>= 2.3.3.1, < 3.0)
|
104
109
|
powerpack (~> 0.1)
|
105
110
|
rainbow (>= 1.99.1, < 3.0)
|
@@ -117,7 +122,7 @@ GEM
|
|
117
122
|
thread_safe (0.3.6)
|
118
123
|
tzinfo (1.2.2)
|
119
124
|
thread_safe (~> 0.1)
|
120
|
-
unicode-display_width (1.
|
125
|
+
unicode-display_width (1.3.0)
|
121
126
|
websocket-driver (0.6.5)
|
122
127
|
websocket-extensions (>= 0.1.0)
|
123
128
|
websocket-extensions (0.1.2)
|
@@ -127,11 +132,13 @@ PLATFORMS
|
|
127
132
|
|
128
133
|
DEPENDENCIES
|
129
134
|
bundler (~> 1.12)
|
135
|
+
byebug
|
130
136
|
minitest (~> 5.0)
|
137
|
+
rack-proxy
|
131
138
|
rails
|
132
139
|
rake (>= 11.1)
|
133
|
-
rubocop (>= 0.
|
140
|
+
rubocop (>= 0.49)
|
134
141
|
webpacker!
|
135
142
|
|
136
143
|
BUNDLED WITH
|
137
|
-
1.
|
144
|
+
1.15.3
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Webpacker
|
2
2
|
|
3
3
|
![travis-ci status](https://api.travis-ci.org/rails/webpacker.svg?branch=master)
|
4
|
-
[![node.js](https://img.shields.io/badge/node-%3E%3D%206.
|
4
|
+
[![node.js](https://img.shields.io/badge/node-%3E%3D%206.0.0-brightgreen.svg)](https://nodejs.org/en/)
|
5
5
|
[![Gem](https://img.shields.io/gem/v/webpacker.svg)](https://github.com/rails/webpacker)
|
6
6
|
|
7
7
|
Webpacker makes it easy to use the JavaScript pre-processor and bundler
|
8
|
-
[Webpack
|
8
|
+
[Webpack 3.x.x+](https://webpack.js.org/)
|
9
9
|
to manage application-like JavaScript in Rails. It coexists with the asset pipeline,
|
10
10
|
as the primary purpose for Webpack is app-like JavaScript, not images, CSS, or
|
11
11
|
even JavaScript Sprinkles (that all continues to live in app/assets).
|
@@ -20,51 +20,18 @@ in which case you may not even need the asset pipeline. This is mostly relevant
|
|
20
20
|
- [Prerequisites](#prerequisites)
|
21
21
|
- [Features](#features)
|
22
22
|
- [Installation](#installation)
|
23
|
+
- [Usage](#usage)
|
24
|
+
- [Development](#development)
|
23
25
|
- [Integrations](#integrations)
|
24
26
|
- [React](#react)
|
25
27
|
- [Angular with TypeScript](#angular-with-typescript)
|
26
28
|
- [Vue](#vue)
|
27
29
|
- [Elm](#elm)
|
28
|
-
- [
|
29
|
-
- [
|
30
|
-
- [
|
31
|
-
- [Configuration](#configuration)
|
32
|
-
- [Webpack](#webpack-1)
|
33
|
-
- [Loaders](#loaders)
|
34
|
-
- [Paths](#paths)
|
35
|
-
- [Babel](#babel)
|
36
|
-
- [Post-Processing CSS](#post-processing-css)
|
37
|
-
- [CDN](#cdn)
|
38
|
-
- [HTTPS in development](#https-in-development)
|
39
|
-
- [Hot module replacement](#hot-module-replacement)
|
40
|
-
- [Linking Styles, Images and Fonts](#linking-styles-images-and-fonts)
|
41
|
-
- [Within your JS app](#within-your-js-app)
|
42
|
-
- [Inside views](#inside-views)
|
43
|
-
- [From node modules folder](#from-node-modules-folder)
|
44
|
-
- [How-tos](#how-tos)
|
45
|
-
- [App structure](#app-structure)
|
46
|
-
- [Namespacing](#namespacing)
|
47
|
-
- [Pass data from view](#pass-data-from-view)
|
48
|
-
- [React](#react-1)
|
49
|
-
- [Vue](#vue-1)
|
50
|
-
- [Add common chunks](#add-common-chunks)
|
51
|
-
- [Module import() vs require()](#module-import-vs-require)
|
52
|
-
- [Add a new npm module](#add-a-new-npm-module)
|
53
|
-
- [Add bootstrap](#add-bootstrap)
|
54
|
-
- [Use Typescript with React](#use-typescript-with-react)
|
55
|
-
- [HTML templates with Typescript](#html-templates-with-typescript)
|
56
|
-
- [CSS modules](#css-modules)
|
57
|
-
- [CSS-Next](#css-next)
|
58
|
-
- [Ignoring swap files](#ignoring-swap-files)
|
59
|
-
- [Link sprocket assets](#link-sprocket-assets)
|
60
|
-
- [Using helpers](#using-helpers)
|
61
|
-
- [Using babel module resolver](#using-babel-module-resolver)
|
62
|
-
- [Extending](#extending)
|
30
|
+
- [Paths](#paths)
|
31
|
+
- [Resolved](#resolved)
|
32
|
+
- [Watched](#watched)
|
63
33
|
- [Deployment](#deployment)
|
64
|
-
|
65
|
-
- [Testing](#testing)
|
66
|
-
- [Troubleshooting](#troubleshooting)
|
67
|
-
- [Wishlist](#wishlist)
|
34
|
+
- [Docs](#docs)
|
68
35
|
- [License](#license)
|
69
36
|
|
70
37
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
@@ -74,18 +41,18 @@ in which case you may not even need the asset pipeline. This is mostly relevant
|
|
74
41
|
|
75
42
|
* Ruby 2.2+
|
76
43
|
* Rails 4.2+
|
77
|
-
* Node.js 6.
|
44
|
+
* Node.js 6.0.0+
|
78
45
|
* Yarn 0.20.1+
|
79
46
|
|
80
47
|
|
81
48
|
## Features
|
82
49
|
|
83
|
-
* [Webpack
|
50
|
+
* [Webpack 3.x.x](https://webpack.js.org/)
|
84
51
|
* ES6 with [babel](https://babeljs.io/)
|
85
52
|
* Automatic code splitting using multiple entry points
|
86
|
-
* Stylesheets -
|
53
|
+
* Stylesheets - SASS and CSS
|
87
54
|
* Images and fonts
|
88
|
-
* PostCSS -
|
55
|
+
* PostCSS - Auto-Prefixer
|
89
56
|
* Asset compression, source-maps, and minification
|
90
57
|
* CDN support
|
91
58
|
* React, Angular, Elm and Vue support out-of-the-box
|
@@ -100,39 +67,107 @@ using new `--webpack` option:
|
|
100
67
|
|
101
68
|
```bash
|
102
69
|
# Available Rails 5.1+
|
103
|
-
|
70
|
+
rails new myapp --webpack
|
104
71
|
```
|
105
72
|
|
106
|
-
Or add it to your `Gemfile
|
73
|
+
Or add it to your `Gemfile`:
|
107
74
|
|
108
75
|
```ruby
|
109
76
|
# Gemfile
|
110
|
-
gem 'webpacker', '~>
|
77
|
+
gem 'webpacker', '~> 3.0'
|
111
78
|
|
112
79
|
# OR if you prefer to use master
|
113
80
|
gem 'webpacker', git: 'https://github.com/rails/webpacker.git'
|
114
81
|
```
|
115
82
|
|
116
|
-
|
117
|
-
with rails version < 5.0
|
83
|
+
and finally, run following to install webpacker:
|
118
84
|
|
85
|
+
```bash
|
86
|
+
bundle
|
87
|
+
bundle exec rails webpacker:install
|
119
88
|
|
120
|
-
|
89
|
+
# OR (on rails version < 5.0)
|
90
|
+
bundle exec rake webpacker:install
|
91
|
+
```
|
92
|
+
|
93
|
+
### Usage
|
94
|
+
|
95
|
+
Once installed you can start writing modern ES6-flavored JavaScript app today:
|
96
|
+
|
97
|
+
```yml
|
98
|
+
app/javascript:
|
99
|
+
├── packs:
|
100
|
+
│ # only webpack entry files here
|
101
|
+
│ └── application.js
|
102
|
+
└── src:
|
103
|
+
│ └── application.css
|
104
|
+
└── images:
|
105
|
+
└── logo.svg
|
106
|
+
```
|
107
|
+
|
108
|
+
You can then link the javascript pack in Rails view using `javascript_pack_tag` helper.
|
109
|
+
If you have styles imported in your pack file, you can link using `stylesheet_pack_tag`:
|
110
|
+
|
111
|
+
```erb
|
112
|
+
<%= javascript_pack_tag 'application' %>
|
113
|
+
<%= stylesheet_pack_tag 'application' %>
|
114
|
+
```
|
115
|
+
|
116
|
+
If you want to link a static asset for `<link rel="prefetch">` or `<img />` tag, you
|
117
|
+
can use `asset_pack_path` helper:
|
118
|
+
|
119
|
+
```erb
|
120
|
+
<link rel="prefetch" href="<%= asset_pack_path 'application.css' %>" />
|
121
|
+
<img src="<%= asset_pack_path 'images/logo.svg' %>" />
|
122
|
+
```
|
123
|
+
|
124
|
+
**Note:** In order for your styles or static assets files to be available in your view,
|
125
|
+
you would need to link them in your "pack" or entry file.
|
126
|
+
|
127
|
+
### Development
|
128
|
+
|
129
|
+
Webpacker ships with two binstubs: `./bin/webpack` and `./bin/webpack-dev-server`.
|
130
|
+
Both are thin wrappers around the standard `webpack.js` and `webpack-dev-server.js`
|
131
|
+
executable to ensure that the right configuration file and environment variables
|
132
|
+
are loaded depending on your environment.
|
133
|
+
|
134
|
+
In development, Webpacker compiles on demand rather than upfront by default. This
|
135
|
+
happens when you refer to any of the pack assets using the Webpacker helper methods.
|
136
|
+
That means you don't have to run any separate process. Compilation errors are logged
|
137
|
+
to the standard Rails log.
|
121
138
|
|
122
|
-
|
123
|
-
|
124
|
-
|
139
|
+
If you want to use live code reloading, or you have enough JavaScript that on-demand compilation is too slow, you'll need to run `./bin/webpack-dev-server` or `ruby ./bin/webpack-dev-server` if on windows,
|
140
|
+
in a separate terminal from `bundle exec rails s`. This process will watch for changes
|
141
|
+
in the `app/javascript/packs/*.js` files and automatically reload the browser to match.
|
125
142
|
|
126
143
|
```bash
|
127
|
-
|
144
|
+
# webpack dev server
|
145
|
+
./bin/webpack-dev-server
|
146
|
+
|
147
|
+
# watcher
|
148
|
+
./bin/webpack --colors --progress
|
149
|
+
|
150
|
+
# standalone build
|
151
|
+
./bin/webpack
|
128
152
|
```
|
129
153
|
|
130
|
-
|
154
|
+
Once you start this development server, Webpacker will automatically start proxying all
|
155
|
+
webpack asset requests to this server. When you stop the server, it'll revert to
|
156
|
+
on-demand compilation again.
|
157
|
+
|
158
|
+
You can also pass CLI options supported by [webpack-dev-server](https://webpack.js.org/configuration/dev-server/). Please note that inline options will always take
|
159
|
+
precedence over the ones already set in the configuration file.
|
131
160
|
|
132
161
|
```bash
|
133
|
-
./bin/
|
162
|
+
./bin/webpack-dev-server --host example.com --inline true --hot false
|
134
163
|
```
|
135
164
|
|
165
|
+
**Note:** Don't forget to prefix `ruby` when running these binstubs on windows
|
166
|
+
|
167
|
+
## Integrations
|
168
|
+
|
169
|
+
Webpacker ships with basic out-of-the-box integration for React, Angular, Vue and Elm.
|
170
|
+
You can see a list of available commands/tasks by running `bundle exec rails webpacker`:
|
136
171
|
|
137
172
|
### React
|
138
173
|
|
@@ -141,10 +176,10 @@ new Rails 5.1+ app using `--webpack=react` option:
|
|
141
176
|
|
142
177
|
```bash
|
143
178
|
# Rails 5.1+
|
144
|
-
|
179
|
+
rails new myapp --webpack=react
|
145
180
|
```
|
146
181
|
|
147
|
-
(or run
|
182
|
+
(or run `bundle exec rails webpacker:install:react` in a existing Rails app already
|
148
183
|
setup with webpacker).
|
149
184
|
|
150
185
|
The installer will add all relevant dependencies using yarn, any changes
|
@@ -159,10 +194,10 @@ new Rails 5.1+ app using `--webpack=angular` option:
|
|
159
194
|
|
160
195
|
```bash
|
161
196
|
# Rails 5.1+
|
162
|
-
|
197
|
+
rails new myapp --webpack=angular
|
163
198
|
```
|
164
199
|
|
165
|
-
(or run
|
200
|
+
(or run `bundle exec rails webpacker:install:angular` on a Rails app already
|
166
201
|
setup with webpacker).
|
167
202
|
|
168
203
|
The installer will add TypeScript and Angular core libraries using yarn plus
|
@@ -178,9 +213,9 @@ new Rails 5.1+ app using `--webpack=vue` option:
|
|
178
213
|
|
179
214
|
```bash
|
180
215
|
# Rails 5.1+
|
181
|
-
|
216
|
+
rails new myapp --webpack=vue
|
182
217
|
```
|
183
|
-
(or run
|
218
|
+
(or run `bundle exec rails webpacker:install:vue` on a Rails app already setup with webpacker).
|
184
219
|
|
185
220
|
The installer will add Vue and required libraries using yarn plus
|
186
221
|
any changes to the configuration files. An example component will
|
@@ -194,114 +229,18 @@ To use Webpacker with [Elm](http://elm-lang.org), create a
|
|
194
229
|
new Rails 5.1+ app using `--webpack=elm` option:
|
195
230
|
|
196
231
|
```
|
197
|
-
|
232
|
+
# Rails 5.1+
|
233
|
+
rails new myapp --webpack=elm
|
198
234
|
```
|
199
235
|
|
200
|
-
(or run
|
236
|
+
(or run `bundle exec rails webpacker:install:elm` on a Rails app already setup with webpacker).
|
201
237
|
|
202
238
|
The Elm library and core packages will be added via Yarn and Elm itself.
|
203
239
|
An example `Main.elm` app will also be added to your project in `app/javascript`
|
204
240
|
so that you can experiment with Elm right away.
|
205
241
|
|
206
242
|
|
207
|
-
##
|
208
|
-
|
209
|
-
Webpacker ships with two binstubs: `./bin/webpack` and `./bin/webpack-dev-server`.
|
210
|
-
Both are thin wrappers around the standard `webpack.js` and `webpack-dev-server.js`
|
211
|
-
executable to ensure that the right configuration file and environment variables
|
212
|
-
are loaded depending on your environment.
|
213
|
-
|
214
|
-
|
215
|
-
### Webpack dev server
|
216
|
-
|
217
|
-
In development, you'll need to run `./bin/webpack-dev-server` in a separate terminal
|
218
|
-
from `./bin/rails server` to have your `app/javascript/packs/*.js` files compiled
|
219
|
-
as you make changes.
|
220
|
-
|
221
|
-
`./bin/webpack-dev-server` launches the [Webpack Dev Server](https://webpack.js.org/configuration/dev-server/), which serves your pack files
|
222
|
-
on `http://localhost:8080/` by default and supports live code reloading in the development environment. You will need to install additional plugins for Webpack if you want
|
223
|
-
features like [Hot Module Replacement](https://webpack.js.org/guides/hmr-react/)
|
224
|
-
|
225
|
-
If you'd rather not have to run the two processes separately by hand, you can use [Foreman](https://ddollar.github.io/foreman):
|
226
|
-
|
227
|
-
```bash
|
228
|
-
gem install foreman
|
229
|
-
```
|
230
|
-
|
231
|
-
```yml
|
232
|
-
# Procfile
|
233
|
-
web: bundle exec rails s
|
234
|
-
webpacker: ./bin/webpack-dev-server
|
235
|
-
```
|
236
|
-
|
237
|
-
```bash
|
238
|
-
foreman start
|
239
|
-
```
|
240
|
-
|
241
|
-
You can also pass CLI options supported by [webpack-dev-server](https://webpack.js.org/configuration/dev-server/). Please note that inline options will always take
|
242
|
-
precedence over the ones already set in the configuration file.
|
243
|
-
|
244
|
-
```bash
|
245
|
-
./bin/webpack-dev-server --host 0.0.0.0 --inline true --hot false
|
246
|
-
```
|
247
|
-
|
248
|
-
|
249
|
-
### Webpack
|
250
|
-
|
251
|
-
We recommend using `webpack-dev-server` during development for a better experience,
|
252
|
-
however, if you don't want that for some reason you can always use `webpack` binstub with
|
253
|
-
watch option, which uses webpack Command Line Interface (CLI). This will use `public_output_path` from `config/webpacker.yml`
|
254
|
-
directory to serve your packs using configured rails server.
|
255
|
-
|
256
|
-
You can pass cli options available with [Webpack](https://webpack.js.org/api/cli/):
|
257
|
-
|
258
|
-
```bash
|
259
|
-
./bin/webpack --watch --progress --colours
|
260
|
-
```
|
261
|
-
|
262
|
-
|
263
|
-
## Configuration
|
264
|
-
|
265
|
-
|
266
|
-
### Webpack
|
267
|
-
|
268
|
-
Webpacker gives you a default set of configuration files for test, development and
|
269
|
-
production environments. They all live together with the shared
|
270
|
-
points in `config/webpack/*.js`.
|
271
|
-
|
272
|
-
![screen shot 2017-05-23 at 19 56 18](https://cloud.githubusercontent.com/assets/771039/26371229/0983add2-3ff2-11e7-9dc3-d9c2c1094032.png)
|
273
|
-
|
274
|
-
By default, you shouldn't have to make any changes to `config/webpack/*.js`
|
275
|
-
files since it's all standard production-ready configuration however
|
276
|
-
if you do need to customize or add a new loader this is where you would go.
|
277
|
-
|
278
|
-
|
279
|
-
### Loaders
|
280
|
-
|
281
|
-
Webpack enables the use of loaders to preprocess files. This allows you to
|
282
|
-
bundle any static resource way beyond JavaScript. All base loaders
|
283
|
-
that ships with webpacker are located inside `config/webpack/loaders`.
|
284
|
-
|
285
|
-
If you want to add a new loader, for example, to process `json` files via webpack:
|
286
|
-
|
287
|
-
```
|
288
|
-
yarn add json-loader
|
289
|
-
```
|
290
|
-
|
291
|
-
And create a `json.js` file inside `loaders` directory:
|
292
|
-
|
293
|
-
```js
|
294
|
-
module.exports = {
|
295
|
-
test: /\.json$/,
|
296
|
-
use: 'json-loader'
|
297
|
-
}
|
298
|
-
```
|
299
|
-
|
300
|
-
Now if you `import()` any `.json` files inside your javascript
|
301
|
-
they will be processed using `json-loader`. Voila!
|
302
|
-
|
303
|
-
|
304
|
-
### Paths
|
243
|
+
## Paths
|
305
244
|
|
306
245
|
By default, webpacker ships with simple conventions for where the javascript
|
307
246
|
app files and compiled webpack bundles will go in your rails app,
|
@@ -310,820 +249,81 @@ but all these options are configurable from `config/webpacker.yml` file.
|
|
310
249
|
The configuration for what Webpack is supposed to compile by default rests
|
311
250
|
on the convention that every file in `app/javascript/packs/*`**(default)**
|
312
251
|
or whatever path you set for `source_entry_path` in the `webpacker.yml` configuration
|
313
|
-
is turned into their own output files (or entry points, as Webpack calls it).
|
252
|
+
is turned into their own output files (or entry points, as Webpack calls it). Therefore you don't want to put anything inside `packs` directory that you do want to be
|
253
|
+
an entry file. As a rule thumb, put all files your want to link in your views inside
|
254
|
+
"packs" directory and keep everything else under `app/javascript`.
|
314
255
|
|
315
256
|
Suppose you want to change the source directory from `app/javascript`
|
316
|
-
to `frontend` and output to `assets/packs
|
257
|
+
to `frontend` and output to `assets/packs`. This is how you would do it:
|
317
258
|
|
318
259
|
```yml
|
319
260
|
# config/webpacker.yml
|
320
261
|
source_path: frontend
|
321
262
|
source_entry_path: packs
|
322
|
-
public_output_path: assets/packs => public/assets/packs
|
263
|
+
public_output_path: assets/packs # outputs to => public/assets/packs
|
323
264
|
```
|
324
265
|
|
325
|
-
|
266
|
+
Similarly you can also control and configure `webpack-dev-server` settings from `config/webpacker.yml` file:
|
326
267
|
|
327
268
|
```yml
|
328
269
|
# config/webpacker.yml
|
329
270
|
development:
|
330
271
|
dev_server:
|
331
|
-
host:
|
332
|
-
port:
|
333
|
-
https: false
|
334
|
-
```
|
335
|
-
|
336
|
-
|
337
|
-
### Babel
|
338
|
-
|
339
|
-
Webpacker ships with [babel](https://babeljs.io/) - a JavaScript compiler so
|
340
|
-
you can use next generation JavaScript, today. The Webpacker installer sets up a
|
341
|
-
standard `.babelrc` file in your app root, which will work great in most cases
|
342
|
-
because of [babel-env-preset](https://github.com/babel/babel-preset-env).
|
343
|
-
|
344
|
-
Following ES6/7 features are supported out of the box:
|
345
|
-
|
346
|
-
* Async/await.
|
347
|
-
* Object Rest/Spread Properties.
|
348
|
-
* Exponentiation Operator.
|
349
|
-
* Dynamic import() - useful for route level code-splitting
|
350
|
-
* Class Fields and Static Properties.
|
351
|
-
|
352
|
-
We have also included [babel polyfill](https://babeljs.io/docs/usage/polyfill/)
|
353
|
-
that includes a custom regenerator runtime and core-js.
|
354
|
-
|
355
|
-
|
356
|
-
### Post-Processing CSS
|
357
|
-
|
358
|
-
Webpacker out-of-the-box provides CSS post-processing using
|
359
|
-
[postcss-loader](https://github.com/postcss/postcss-loader)
|
360
|
-
and the installer sets up a standard `.postcssrc.yml`
|
361
|
-
file in your app root with standard plugins.
|
362
|
-
|
363
|
-
```yml
|
364
|
-
plugins:
|
365
|
-
postcss-smart-import: {}
|
366
|
-
precss: {}
|
367
|
-
autoprefixer: {}
|
368
|
-
```
|
369
|
-
|
370
|
-
|
371
|
-
### CDN
|
372
|
-
|
373
|
-
Webpacker out-of-the-box provides CDN support using your Rails app `config.action_controller.asset_host` setting. If you already have [CDN](http://guides.rubyonrails.org/asset_pipeline.html#cdns) added in your rails app
|
374
|
-
you don't need to do anything extra for webpacker, it just works.
|
375
|
-
|
376
|
-
### HTTPS in development
|
377
|
-
|
378
|
-
You may require the `webpack-dev-server` to serve views over HTTPS in development.
|
379
|
-
To do this, set the `https` option for `webpack-dev-server`
|
380
|
-
to `true` in `config/webpacker.yml`, then start the dev server as usual
|
381
|
-
with `./bin/webpack-dev-server`.
|
382
|
-
|
383
|
-
Please note that the `webpack-dev-server` will use a self-signed certificate,
|
384
|
-
so your web browser will display a warning upon accessing the page.
|
385
|
-
|
386
|
-
|
387
|
-
### Hot module replacement
|
388
|
-
|
389
|
-
Webpacker out-of-the-box doesn't ship with HMR just yet. You will need to
|
390
|
-
install additional plugins for Webpack if you want to add HMR support.
|
391
|
-
|
392
|
-
You can checkout these links on this subject:
|
393
|
-
|
394
|
-
- https://webpack.js.org/configuration/dev-server/#devserver-hot
|
395
|
-
- https://webpack.js.org/guides/hmr-react/
|
396
|
-
|
397
|
-
|
398
|
-
## Linking Styles, Images and Fonts
|
399
|
-
|
400
|
-
Static assets like images, fonts and stylesheets support is enabled out-of-box
|
401
|
-
and you can link them into your javascript app code and have them
|
402
|
-
compiled automatically.
|
403
|
-
|
404
|
-
|
405
|
-
### Within your JS app
|
406
|
-
|
407
|
-
```sass
|
408
|
-
// app/javascript/hello_react/styles/hello-react.sass
|
409
|
-
|
410
|
-
.hello-react
|
411
|
-
padding: 20px
|
412
|
-
font-size: 12px
|
413
|
-
```
|
414
|
-
|
415
|
-
```js
|
416
|
-
// React component example
|
417
|
-
// app/javascripts/packs/hello_react.jsx
|
418
|
-
|
419
|
-
import React from 'react'
|
420
|
-
import helloIcon from '../hello_react/images/icon.png'
|
421
|
-
import '../hello_react/styles/hello-react.sass'
|
422
|
-
|
423
|
-
const Hello = props => (
|
424
|
-
<div className="hello-react">
|
425
|
-
<img src={helloIcon} alt="hello-icon" />
|
426
|
-
<p>Hello {props.name}!</p>
|
427
|
-
</div>
|
428
|
-
)
|
429
|
-
```
|
430
|
-
|
431
|
-
|
432
|
-
### Inside views
|
433
|
-
|
434
|
-
Under the hood webpack uses
|
435
|
-
[extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) plugin to extract all the referenced styles within your app and compile it into
|
436
|
-
a separate `[pack_name].css` bundle so that in your view you can use the
|
437
|
-
`stylesheet_pack_tag` helper,
|
438
|
-
|
439
|
-
```erb
|
440
|
-
<%= stylesheet_pack_tag 'hello_react' %>
|
441
|
-
```
|
442
|
-
|
443
|
-
You can also link js/images/styles used within your js app in views using
|
444
|
-
`asset_pack_path` helper. This helper is useful in cases where you just want to
|
445
|
-
create a `<link rel="prefetch">` or `<img />` for an asset.
|
446
|
-
|
447
|
-
```erb
|
448
|
-
<%= asset_pack_path 'hello_react.css' %>
|
449
|
-
<% # => "/packs/hello_react.css" %>
|
450
|
-
|
451
|
-
<img src="<%= asset_pack_path 'calendar.png' %>" />
|
452
|
-
<% # => <img src="/packs/calendar.png" /> %>
|
453
|
-
```
|
454
|
-
|
455
|
-
|
456
|
-
### From node modules folder
|
457
|
-
|
458
|
-
You can also import styles from `node_modules` using the following syntax.
|
459
|
-
Please note that your styles will always be extracted into `[pack_name].css`:
|
460
|
-
|
461
|
-
```sass
|
462
|
-
// app/javascript/app-styles.sass
|
463
|
-
// ~ to tell webpack that this is not a relative import:
|
464
|
-
|
465
|
-
@import '~@material/animation/mdc-animation.scss'
|
466
|
-
@import '~boostrap/dist/bootstrap.css'
|
467
|
-
```
|
468
|
-
|
469
|
-
```js
|
470
|
-
// Your main app pack
|
471
|
-
// app/javascript/packs/app.js
|
472
|
-
|
473
|
-
import '../app-styles'
|
474
|
-
```
|
475
|
-
|
476
|
-
```erb
|
477
|
-
<%# In your views %>
|
478
|
-
|
479
|
-
<%= javascript_pack_tag 'app' %>
|
480
|
-
<%= stylesheet_pack_tag 'app' %>
|
481
|
-
```
|
482
|
-
|
483
|
-
|
484
|
-
## How-tos
|
485
|
-
|
486
|
-
|
487
|
-
### App structure
|
488
|
-
|
489
|
-
Let's say you're building a calendar app. Your JS app structure could look like this:
|
490
|
-
|
491
|
-
```js
|
492
|
-
// app/javascript/packs/calendar.js
|
493
|
-
|
494
|
-
import 'calendar'
|
495
|
-
```
|
496
|
-
|
497
|
-
```
|
498
|
-
app/javascript/calendar/index.js // gets loaded by import 'calendar'
|
499
|
-
app/javascript/calendar/components/grid.jsx
|
500
|
-
app/javascript/calendar/styles/grid.sass
|
501
|
-
app/javascript/calendar/models/month.js
|
502
|
-
```
|
503
|
-
|
504
|
-
```erb
|
505
|
-
<%# app/views/layouts/application.html.erb %>
|
506
|
-
|
507
|
-
<%= javascript_pack_tag 'calendar' %>
|
508
|
-
<%= stylesheet_pack_tag 'calendar' %>
|
509
|
-
```
|
510
|
-
|
511
|
-
But it could also look a million other ways.
|
512
|
-
|
513
|
-
|
514
|
-
#### Namespacing
|
515
|
-
|
516
|
-
You can also namespace your packs using directories similar to a Rails app.
|
517
|
-
|
518
|
-
```
|
519
|
-
app/javascript/packs/admin/orders.js
|
520
|
-
app/javascript/packs/shop/orders.js
|
521
|
-
```
|
522
|
-
|
523
|
-
and reference them in your views like this:
|
524
|
-
|
525
|
-
```erb
|
526
|
-
<%# app/views/admin/orders/index.html.erb %>
|
527
|
-
|
528
|
-
<%= javascript_pack_tag 'admin/orders' %>
|
529
|
-
```
|
530
|
-
|
531
|
-
and
|
532
|
-
|
533
|
-
```erb
|
534
|
-
<%# app/views/shop/orders/index.html.erb %>
|
535
|
-
|
536
|
-
<%= javascript_pack_tag 'shop/orders' %>
|
537
|
-
```
|
538
|
-
|
539
|
-
|
540
|
-
### Pass data from view
|
541
|
-
|
542
|
-
|
543
|
-
#### React
|
544
|
-
|
545
|
-
You may consider using [react-rails](https://github.com/reactjs/react-rails) or
|
546
|
-
[webpacker-react](https://github.com/renchap/webpacker-react) for more advanced react integration. However here is how you can do it yourself:
|
547
|
-
|
548
|
-
```erb
|
549
|
-
<%# views/layouts/application.html.erb %>
|
550
|
-
|
551
|
-
<%= content_tag :div,
|
552
|
-
id: "hello-react",
|
553
|
-
data: {
|
554
|
-
message: 'Hello!',
|
555
|
-
name: 'David'
|
556
|
-
}.to_json do %>
|
557
|
-
<% end %>
|
558
|
-
```
|
559
|
-
|
560
|
-
```js
|
561
|
-
// app/javascript/packs/hello_react.js
|
562
|
-
|
563
|
-
const Hello = props => (
|
564
|
-
<div className='react-app-wrapper'>
|
565
|
-
<img src={clockIcon} alt="clock" />
|
566
|
-
<h5 className='hello-react'>
|
567
|
-
{props.message} {props.name}!
|
568
|
-
</h5>
|
569
|
-
</div>
|
570
|
-
)
|
571
|
-
|
572
|
-
// Render component with data
|
573
|
-
document.addEventListener('DOMContentLoaded', () => {
|
574
|
-
const node = document.getElementById('hello-react')
|
575
|
-
const data = JSON.parse(node.getAttribute('data'))
|
576
|
-
|
577
|
-
ReactDOM.render(<Hello {...data} />, node)
|
578
|
-
})
|
272
|
+
host: localhost
|
273
|
+
port: 3035
|
579
274
|
```
|
580
275
|
|
276
|
+
If you have `hmr` turned to true, then the `stylesheet_pack_tag` generates no output, as you will want to configure your styles to be inlined in your JavaScript for hot reloading. During production and testing, the `stylesheet_pack_tag` will create the appropriate HTML tags.
|
581
277
|
|
582
|
-
#### Vue
|
583
278
|
|
584
|
-
|
585
|
-
<%= content_tag :div,
|
586
|
-
id: "hello-vue",
|
587
|
-
data: {
|
588
|
-
message: "Hello!",
|
589
|
-
name: "David"
|
590
|
-
} do %>
|
591
|
-
<% end %>
|
592
|
-
```
|
593
|
-
|
594
|
-
```html
|
595
|
-
<div id="hello-vue" data-name="David" data-message="Hello!"></div>
|
596
|
-
```
|
597
|
-
|
598
|
-
```js
|
599
|
-
// Render component with data
|
600
|
-
|
601
|
-
document.addEventListener('DOMContentLoaded', () => {
|
602
|
-
const node = document.getElementById('hello-vue')
|
603
|
-
const data = JSON.parse(node.getAttribute('data'))
|
604
|
-
|
605
|
-
const app = new Vue({
|
606
|
-
data: data,
|
607
|
-
el: '#vue-app',
|
608
|
-
template: '<App/>',
|
609
|
-
components: { App }
|
610
|
-
})
|
611
|
-
|
612
|
-
console.log(app)
|
613
|
-
})
|
614
|
-
```
|
615
|
-
|
616
|
-
You can follow same steps for Angular too.
|
617
|
-
|
618
|
-
|
619
|
-
### Add common chunks
|
620
|
-
|
621
|
-
The CommonsChunkPlugin is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points. By separating common modules from bundles, the resulting chunked file can be loaded once initially, and stored in the cache for later use. This results in page speed optimizations as the browser can quickly serve the shared code from the cache, rather than being forced to load a larger bundle whenever a new page is visited.
|
622
|
-
|
623
|
-
Create a `app-config.js` file inside `config/webpack` and in that file add:
|
624
|
-
|
625
|
-
```js
|
626
|
-
module.exports = {
|
627
|
-
plugins: [
|
628
|
-
// Creates a common vendor.js with all shared modules
|
629
|
-
new webpack.optimize.CommonsChunkPlugin({
|
630
|
-
name: 'vendor',
|
631
|
-
minChunks: (module) => {
|
632
|
-
// this assumes your vendor imports exist in the node_modules directory
|
633
|
-
return module.context && module.context.indexOf('node_modules') !== -1;
|
634
|
-
}
|
635
|
-
}),
|
636
|
-
// Webpack code chunk - manifest.js
|
637
|
-
new webpack.optimize.CommonsChunkPlugin({
|
638
|
-
name: 'manifest',
|
639
|
-
minChunks: Infinity
|
640
|
-
})
|
641
|
-
]
|
642
|
-
}
|
643
|
-
```
|
644
|
-
|
645
|
-
You can add this in `shared.js` too but we are doing this to ensure smoother upgrades.
|
646
|
-
|
647
|
-
```js
|
648
|
-
// config/webpack/shared.js
|
649
|
-
// .... rest of the config
|
650
|
-
|
651
|
-
const appConfig = require('./app-config.js')
|
652
|
-
|
653
|
-
plugins: appConfig.plugins.concat([
|
654
|
-
|
655
|
-
// ...existing plugins
|
656
|
-
|
657
|
-
])
|
658
|
-
```
|
659
|
-
|
660
|
-
Now, add these files to your `layouts/application.html.erb`:
|
661
|
-
|
662
|
-
```erb
|
663
|
-
<%= # Head %>
|
664
|
-
|
665
|
-
<%= javascript_pack_tag 'manifest' %>
|
666
|
-
<%= javascript_pack_tag 'vendor' %>
|
667
|
-
|
668
|
-
<%= # If importing any styles from node_modules in your JS app %>
|
669
|
-
|
670
|
-
<%= stylesheet_pack_tag 'vendor' %>
|
671
|
-
```
|
672
|
-
|
673
|
-
|
674
|
-
### Module import() vs require()
|
675
|
-
|
676
|
-
While you are free to use `require()` and `module.exports`, we encourage you
|
677
|
-
to use `import` and `export` instead since it reads and looks much better.
|
678
|
-
|
679
|
-
```js
|
680
|
-
import Button from 'react-bootstrap/lib/Button'
|
681
|
-
|
682
|
-
// or
|
683
|
-
import { Button } from 'react-bootstrap'
|
684
|
-
|
685
|
-
class Foo {
|
686
|
-
// code...
|
687
|
-
}
|
688
|
-
|
689
|
-
export default Foo
|
690
|
-
import Foo from './foo'
|
691
|
-
```
|
692
|
-
|
693
|
-
You can also use named export and import
|
694
|
-
|
695
|
-
```js
|
696
|
-
export const foo = () => console.log('hello world')
|
697
|
-
import { foo } from './foo'
|
698
|
-
```
|
699
|
-
|
700
|
-
|
701
|
-
### Add a new npm module
|
279
|
+
### Resolved
|
702
280
|
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
### Add bootstrap
|
711
|
-
|
712
|
-
You can use yarn to add bootstrap or any other modules available on npm:
|
713
|
-
|
714
|
-
```bash
|
715
|
-
yarn add bootstrap
|
716
|
-
```
|
717
|
-
|
718
|
-
Import Bootstrap and theme(optional) CSS in your app/javascript/packs/app.js file:
|
719
|
-
|
720
|
-
```js
|
721
|
-
import 'bootstrap/dist/css/bootstrap.css'
|
722
|
-
import 'bootstrap/dist/css/bootstrap-theme.css'
|
723
|
-
```
|
724
|
-
|
725
|
-
Or in your app/javascript/app.sass file:
|
726
|
-
|
727
|
-
```sass
|
728
|
-
// ~ to tell that this is not a relative import
|
729
|
-
|
730
|
-
@import '~bootstrap/dist/css/bootstrap.css'
|
731
|
-
@import '~bootstrap/dist/css/bootstrap-theme.css'
|
732
|
-
```
|
733
|
-
|
734
|
-
|
735
|
-
### Use Typescript with React
|
736
|
-
|
737
|
-
1. Setup react using webpacker [react installer](#react). Then add required depedencies
|
738
|
-
for using typescript with React:
|
739
|
-
|
740
|
-
```bash
|
741
|
-
yarn add ts-loader typescript @types/react @types/react-dom
|
742
|
-
|
743
|
-
# You don't need this with typescript
|
744
|
-
yarn remove prop-types
|
745
|
-
```
|
746
|
-
|
747
|
-
2. Add a `tsconfig.json` to project root:
|
748
|
-
|
749
|
-
``` json
|
750
|
-
{
|
751
|
-
"compilerOptions": {
|
752
|
-
"declaration": false,
|
753
|
-
"emitDecoratorMetadata": true,
|
754
|
-
"experimentalDecorators": true,
|
755
|
-
"lib": ["es6", "dom"],
|
756
|
-
"module": "es6",
|
757
|
-
"moduleResolution": "node",
|
758
|
-
"sourceMap": true,
|
759
|
-
"jsx": "react",
|
760
|
-
"target": "es5"
|
761
|
-
},
|
762
|
-
"exclude": [
|
763
|
-
"**/*.spec.ts",
|
764
|
-
"node_modules",
|
765
|
-
"public"
|
766
|
-
],
|
767
|
-
"compileOnSave": false
|
768
|
-
}
|
769
|
-
```
|
770
|
-
|
771
|
-
3. Add a new loader `config/webpack/loaders/typescript.js`:
|
772
|
-
|
773
|
-
``` js
|
774
|
-
module.exports = {
|
775
|
-
test: /.(ts|tsx)$/,
|
776
|
-
loader: 'ts-loader'
|
777
|
-
}
|
778
|
-
```
|
779
|
-
|
780
|
-
4. Finally add `.tsx` to the list of extensions in `config/webpacker.yml`
|
781
|
-
and rename your generated `hello_react.js` using react installer
|
782
|
-
to `hello_react.tsx` and make it valid typescript and now you can use
|
783
|
-
typescript, JSX with React.
|
784
|
-
|
785
|
-
|
786
|
-
### Use HTML templates with Typescript and Angular
|
787
|
-
|
788
|
-
After you have installed angular using [angular installer](#angular-with-typescript)
|
789
|
-
you would need to follow these steps to add HTML templates support:
|
790
|
-
|
791
|
-
1. Use `yarn` to add html-loader
|
792
|
-
|
793
|
-
```bash
|
794
|
-
yarn add html-loader
|
795
|
-
```
|
796
|
-
|
797
|
-
2. Add html-loader to `config/webpacker/loaders/html.js`
|
798
|
-
|
799
|
-
```js
|
800
|
-
module.exports = {
|
801
|
-
test: /\.html$/,
|
802
|
-
use: [{
|
803
|
-
loader: 'html-loader',
|
804
|
-
options: {
|
805
|
-
minimize: true,
|
806
|
-
removeAttributeQuotes: false,
|
807
|
-
caseSensitive: true,
|
808
|
-
customAttrSurround: [ [/#/, /(?:)/], [/\*/, /(?:)/], [/\[?\(?/, /(?:)/] ],
|
809
|
-
customAttrAssign: [ /\)?\]?=/ ]
|
810
|
-
}
|
811
|
-
}]
|
812
|
-
}
|
813
|
-
```
|
814
|
-
|
815
|
-
3. Add `.html` to extensions list
|
281
|
+
If you are adding webpacker to an existing app that has most of the assets inside
|
282
|
+
`app/assets` or inside an engine and you want to share that
|
283
|
+
with webpack modules then you can use `resolved_paths`
|
284
|
+
option available in `config/webpacker.yml`, which lets you
|
285
|
+
add additional paths webpack should lookup when resolving modules:
|
816
286
|
|
817
287
|
```yml
|
818
|
-
|
819
|
-
- .elm
|
820
|
-
- .coffee
|
821
|
-
- .html
|
288
|
+
resolved_paths: ['app/assets']
|
822
289
|
```
|
823
290
|
|
824
|
-
|
825
|
-
|
826
|
-
```ts
|
827
|
-
// app/javascript/hello_angular/html.d.ts
|
828
|
-
|
829
|
-
declare module "*.html" {
|
830
|
-
const content: string
|
831
|
-
export default content
|
832
|
-
}
|
833
|
-
```
|
834
|
-
|
835
|
-
5. Add a template.html file relative to `app.component.ts`
|
836
|
-
|
837
|
-
```html
|
838
|
-
<h1>Hello {{name}}</h1>
|
839
|
-
```
|
840
|
-
|
841
|
-
6. Import template into `app.component.ts`
|
842
|
-
|
843
|
-
```ts
|
844
|
-
import { Component } from '@angular/core'
|
845
|
-
import templateString from './template.html'
|
846
|
-
|
847
|
-
@Component({
|
848
|
-
selector: 'hello-angular',
|
849
|
-
template: templateString
|
850
|
-
})
|
851
|
-
|
852
|
-
export class AppComponent {
|
853
|
-
name = 'Angular!'
|
854
|
-
}
|
855
|
-
```
|
856
|
-
|
857
|
-
That's all. Voila!
|
858
|
-
|
859
|
-
|
860
|
-
### CSS modules
|
861
|
-
|
862
|
-
To enable CSS modules, you would need to update `config/webpack/loaders/sass.js`
|
863
|
-
file, particularly `css-loader`:
|
864
|
-
|
865
|
-
```js
|
866
|
-
// Add css-modules
|
867
|
-
|
868
|
-
{
|
869
|
-
loader: 'css-loader',
|
870
|
-
options: {
|
871
|
-
minimize: env.NODE_ENV === 'production',
|
872
|
-
modules: true,
|
873
|
-
localIdentName: '[path][name]__[local]--[hash:base64:5]'
|
874
|
-
}
|
875
|
-
}
|
876
|
-
```
|
877
|
-
|
878
|
-
That's all. Now, you can use CSS modules within your JS app:
|
879
|
-
|
880
|
-
```js
|
881
|
-
import React from 'react'
|
882
|
-
import styles from './styles.css'
|
883
|
-
|
884
|
-
const Hello = props => (
|
885
|
-
<div className={styles.wrapper}>
|
886
|
-
<img src={clockIcon} alt="clock" className={styles.img} />
|
887
|
-
<h5 lassName={styles.name}>
|
888
|
-
{props.message} {props.name}!
|
889
|
-
</h5>
|
890
|
-
</div>
|
891
|
-
)
|
892
|
-
```
|
893
|
-
|
894
|
-
|
895
|
-
### CSS-Next
|
896
|
-
|
897
|
-
If you want to use [css-next](http://cssnext.io/) inside your app, add postcss
|
898
|
-
plugin for `css-next`
|
899
|
-
|
900
|
-
```bash
|
901
|
-
yarn add postcss-cssnext
|
902
|
-
```
|
903
|
-
|
904
|
-
and update your `.postcssrc.yml`
|
905
|
-
|
906
|
-
```
|
907
|
-
plugins:
|
908
|
-
postcss-smart-import: {}
|
909
|
-
cssnext: {}
|
910
|
-
```
|
911
|
-
|
912
|
-
That's all. Now, you can use latest css features, today.
|
913
|
-
|
914
|
-
|
915
|
-
### Ignoring swap files
|
916
|
-
|
917
|
-
If you are using vim or emacs and want to ignore certain files you can add `ignore-loader`:
|
918
|
-
|
919
|
-
```
|
920
|
-
yard add ignore-loader
|
921
|
-
```
|
922
|
-
|
923
|
-
and create a new loader file inside `config/webpack/loaders`:
|
924
|
-
|
925
|
-
```js
|
926
|
-
// config/webpack/loaders/ignores.js
|
927
|
-
// ignores vue~ swap files
|
928
|
-
|
929
|
-
module.exports = {
|
930
|
-
test: /.vue~$/,
|
931
|
-
loader: 'ignore-loader'
|
932
|
-
}
|
933
|
-
```
|
934
|
-
|
935
|
-
And now all files with `.vue~` will be ignored by the webpack compiler.
|
936
|
-
|
937
|
-
|
938
|
-
### Link sprocket assets
|
939
|
-
|
940
|
-
|
941
|
-
#### Using helpers
|
942
|
-
|
943
|
-
It's possible to link to assets that have been precompiled by sprockets. Add the `.erb` extension to your javascript file, then you can use Sprockets' asset helpers:
|
944
|
-
|
945
|
-
```erb
|
946
|
-
<%# app/javascript/my_pack/example.js.erb %>
|
947
|
-
|
948
|
-
<% helpers = ActionController::Base.helpers %>
|
949
|
-
var railsImagePath = "<%= helpers.image_path('rails.png') %>"
|
950
|
-
```
|
951
|
-
|
952
|
-
This is enabled by the `rails-erb-loader` loader rule in `config/loaders/erb.js`.
|
953
|
-
|
954
|
-
|
955
|
-
#### Using babel module resolver
|
956
|
-
|
957
|
-
You can also use [babel-plugin-module-resolver](https://github.com/tleunen/babel-plugin-module-resolver) to reference assets directly from `app/assets/**`
|
958
|
-
|
959
|
-
```bash
|
960
|
-
yarn add babel-plugin-module-resolver
|
961
|
-
```
|
962
|
-
|
963
|
-
Specify the plugin in your `.babelrc` with the custom root or alias. Here's an example:
|
964
|
-
|
965
|
-
```json
|
966
|
-
{
|
967
|
-
"plugins": [
|
968
|
-
["module-resolver", {
|
969
|
-
"root": ["./app"],
|
970
|
-
"alias": {
|
971
|
-
"assets": "./assets"
|
972
|
-
}
|
973
|
-
}]
|
974
|
-
]
|
975
|
-
}
|
976
|
-
```
|
977
|
-
|
978
|
-
And then within your javascript app code:
|
291
|
+
You can then import them inside your modules like so:
|
979
292
|
|
980
293
|
```js
|
981
|
-
// Note
|
982
|
-
|
983
|
-
import
|
984
|
-
import 'assets/stylesheets/bar.sass'
|
985
|
-
```
|
986
|
-
|
987
|
-
## Extending
|
988
|
-
|
989
|
-
We suggest you don't directly overwrite the provided configuration files
|
990
|
-
and extend instead for smoother upgrades. Here is one way to do it:
|
991
|
-
|
992
|
-
Create a `app-config.js` file inside `config/webpack`, and in that add:
|
993
|
-
|
994
|
-
```js
|
995
|
-
module.exports = {
|
996
|
-
production: {
|
997
|
-
plugins: [
|
998
|
-
// ... Add plugins
|
999
|
-
]
|
1000
|
-
},
|
1001
|
-
|
1002
|
-
development: {
|
1003
|
-
output: {
|
1004
|
-
// ... Custom output path
|
1005
|
-
}
|
1006
|
-
}
|
1007
|
-
}
|
294
|
+
// Note it's relative to parent directory i.e. app/assets
|
295
|
+
import 'stylesheets/main'
|
296
|
+
import 'images/rails.png'
|
1008
297
|
```
|
1009
298
|
|
1010
|
-
|
1011
|
-
|
299
|
+
**Note:** Please be careful when adding paths here otherwise it
|
300
|
+
will make the compilation slow, consider adding specific paths instead of
|
301
|
+
whole parent directory if you just need to reference one or two modules
|
1012
302
|
|
1013
|
-
const { plugins } = require('./app-config.js')
|
1014
303
|
|
1015
|
-
|
304
|
+
### Watched
|
1016
305
|
|
1017
|
-
|
306
|
+
By default, the lazy compilation is cached until a file is changed under
|
307
|
+
tracked paths. You can configure the paths tracked
|
308
|
+
by adding new paths to `watched_paths` array, much like rails `autoload_paths`:
|
1018
309
|
|
1019
|
-
|
310
|
+
```rb
|
311
|
+
# config/initializers/webpacker.rb
|
312
|
+
# or config/application.rb
|
313
|
+
Webpacker::Compiler.watched_paths << 'bower_components'
|
1020
314
|
```
|
1021
315
|
|
1022
|
-
But this could be done million other ways.
|
1023
|
-
|
1024
316
|
|
1025
317
|
## Deployment
|
1026
318
|
|
1027
319
|
Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`. If you are not using sprockets you
|
1028
|
-
can manually trigger `bundle exec rails webpacker:compile`
|
1029
|
-
|
1030
|
-
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.
|
1031
|
-
|
1032
|
-
By default the output will look like this in different environments:
|
1033
|
-
|
1034
|
-
```html
|
1035
|
-
<!-- In development mode with webpack-dev-server -->
|
1036
|
-
<script src="http://localhost:8080/calendar.js"></script>
|
1037
|
-
<link rel="stylesheet" media="screen" href="http://localhost:8080/calendar.css">
|
1038
|
-
<!-- In development mode -->
|
1039
|
-
<script src="/packs/calendar.js"></script>
|
1040
|
-
<link rel="stylesheet" media="screen" href="/packs/calendar.css">
|
1041
|
-
<!-- In production mode -->
|
1042
|
-
<script src="/packs/calendar-0bd141f6d9360cf4a7f5.js"></script>
|
1043
|
-
<link rel="stylesheet" media="screen" href="/packs/calendar-dc02976b5f94b507e3b6.css">
|
1044
|
-
```
|
1045
|
-
|
1046
|
-
|
1047
|
-
### Heroku
|
1048
|
-
|
1049
|
-
Heroku installs yarn and node by default if you deploy a rails app with
|
1050
|
-
Webpacker so all you would need to do:
|
1051
|
-
|
1052
|
-
```bash
|
1053
|
-
heroku create shiny-webpacker-app
|
1054
|
-
heroku addons:create heroku-postgresql:hobby-dev
|
1055
|
-
git push heroku master
|
1056
|
-
```
|
1057
|
-
|
1058
|
-
|
1059
|
-
## Testing
|
1060
|
-
|
1061
|
-
Webpacker lazily compiles assets in test env so you can write your tests without any extra
|
1062
|
-
setup and everything will just work out of the box.
|
1063
|
-
|
1064
|
-
Here is a sample system test case with hello_react example component:
|
1065
|
-
|
1066
|
-
```js
|
1067
|
-
// Example react component
|
1068
|
-
|
1069
|
-
import React from 'react'
|
1070
|
-
import ReactDOM from 'react-dom'
|
1071
|
-
import PropTypes from 'prop-types'
|
1072
|
-
|
1073
|
-
const Hello = props => (
|
1074
|
-
<div>Hello David</div>
|
1075
|
-
)
|
1076
|
-
|
1077
|
-
document.addEventListener('DOMContentLoaded', () => {
|
1078
|
-
ReactDOM.render(
|
1079
|
-
<Hello />,
|
1080
|
-
document.body.appendChild(document.createElement('div')),
|
1081
|
-
)
|
1082
|
-
})
|
1083
|
-
```
|
1084
|
-
|
1085
|
-
```erb
|
1086
|
-
# views/pages/home.html.erb
|
1087
|
-
|
1088
|
-
<%= javascript_pack_tag "hello_react" %>
|
1089
|
-
```
|
1090
|
-
|
1091
|
-
```rb
|
1092
|
-
# Tests example react component
|
1093
|
-
require "application_system_test_case"
|
1094
|
-
class HomesTest < ApplicationSystemTestCase
|
1095
|
-
test "can see the hello message" do
|
1096
|
-
visit root_url
|
1097
|
-
assert_selector "h5", text: "Hello! David"
|
1098
|
-
end
|
1099
|
-
end
|
1100
|
-
```
|
1101
|
-
|
1102
|
-
|
1103
|
-
## Troubleshooting
|
1104
|
-
|
1105
|
-
* If you get this error `ENOENT: no such file or directory - node-sass` on Heroku
|
1106
|
-
or elsewhere during `assets:precompile` or `bundle exec rails webpacker:compile`
|
1107
|
-
then you would need to rebuild node-sass. It's a bit weird error,
|
1108
|
-
basically, it can't find the `node-sass` binary.
|
1109
|
-
An easy solution is to create a postinstall hook - `npm rebuild node-sass` in
|
1110
|
-
`package.json` and that will ensure `node-sass` is rebuild whenever
|
1111
|
-
you install any new modules.
|
1112
|
-
|
1113
|
-
* If you get this error `Can't find hello_react.js in manifest.json`
|
1114
|
-
when loading a view in the browser it's because Webpack is still compiling packs.
|
1115
|
-
Webpacker uses a `manifest.json` file to keep track of packs in all environments,
|
1116
|
-
however since this file is generated after packs are compiled by webpack. So,
|
1117
|
-
if you load a view in browser whilst webpack is compiling you will get this error.
|
1118
|
-
Therefore, make sure webpack
|
1119
|
-
(i.e `./bin/webpack-dev-server`) is running and has
|
1120
|
-
completed the compilation successfully before loading a view.
|
320
|
+
can manually trigger `NODE_ENV=production bundle exec rails webpacker:compile`
|
321
|
+
during your app deploy.
|
1121
322
|
|
1122
323
|
|
1123
|
-
##
|
324
|
+
## Docs
|
1124
325
|
|
1125
|
-
|
1126
|
-
- Support rails engines - [#348](https://github.com/rails/webpacker/issues/348)
|
326
|
+
You can find more detailed guides under [docs](./docs).
|
1127
327
|
|
1128
328
|
|
1129
329
|
## License
|