webpacker 1.2 → 2.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/CHANGELOG.md +93 -9
- data/Gemfile.lock +2 -2
- data/README.md +979 -93
- data/lib/install/angular.rb +2 -2
- data/lib/install/bin/webpack-dev-server.tt +20 -10
- data/lib/install/bin/webpack.tt +10 -15
- data/lib/install/config/.babelrc +13 -1
- data/lib/install/config/loaders/core/sass.js +3 -2
- data/lib/install/config/loaders/installers/elm.js +20 -0
- data/lib/install/config/loaders/installers/vue.js +1 -0
- data/lib/install/config/webpack/configuration.js +22 -13
- data/lib/install/config/webpack/development.js +17 -1
- data/lib/install/config/webpack/production.js +16 -2
- data/lib/install/config/webpack/shared.js +15 -11
- data/lib/install/config/{webpack/paths.yml → webpacker.yml} +12 -7
- data/lib/install/elm.rb +29 -0
- data/lib/install/examples/angular/tsconfig.json +1 -0
- data/lib/install/examples/elm/Main.elm +54 -0
- data/lib/install/examples/elm/hello_elm.js +11 -0
- data/lib/install/examples/vue/hello_vue.js +4 -8
- data/lib/install/react.rb +2 -2
- data/lib/install/template.rb +10 -11
- data/lib/install/vue.rb +2 -2
- data/lib/tasks/installers.rake +1 -0
- data/lib/tasks/webpacker.rake +11 -9
- data/lib/tasks/webpacker/check_webpack_binstubs.rake +11 -0
- data/lib/tasks/webpacker/check_yarn.rake +6 -3
- data/lib/tasks/webpacker/clobber.rake +3 -3
- data/lib/tasks/webpacker/compile.rake +14 -20
- data/lib/tasks/webpacker/verify_install.rake +2 -2
- data/lib/tasks/webpacker/yarn_install.rake +2 -2
- data/lib/webpacker.rb +16 -1
- data/lib/webpacker/compiler.rb +20 -0
- data/lib/webpacker/configuration.rb +30 -22
- data/lib/webpacker/env.rb +2 -6
- data/lib/webpacker/helper.rb +0 -2
- data/lib/webpacker/manifest.rb +23 -6
- data/lib/webpacker/version.rb +1 -1
- data/package.json +1 -1
- data/test/configuration_test.rb +32 -0
- data/test/env_test.rb +3 -5
- data/test/helper_test.rb +23 -0
- data/test/manifest_test.rb +30 -0
- data/test/test_app/config/secrets.yml +5 -0
- data/test/test_app/public/packs/manifest.json +4 -0
- data/test/webpacker_test.rb +2 -1
- metadata +20 -7
- data/lib/install/bin/yarn.tt +0 -11
- data/lib/install/config/webpack/development.server.js +0 -17
- data/lib/install/config/webpack/development.server.yml +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a0e2ae99bad3184ab44d798809fbd0efe458e38
|
4
|
+
data.tar.gz: 0a6a47fa0b5a829e4ff418891310a1cfeb7e2288
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e162e508430b3179b5e0aded52ddf815be5b4f6f67dbf01cd822a18c9f6227773b0f44adfef45a74d9c11e2b73dce64e0209352236f8156602bd08e2009b95b4
|
7
|
+
data.tar.gz: da29a763948aadb84689b1cc94f884e78489d28319a920bfd76e43f8d6ac8b6d61df74db4de707de101c47407fbafe770b29db9e67c1e9d24292042c55bdbdf7
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,94 @@
|
|
1
|
+
## [2.0] - 2017-05-24
|
2
|
+
|
3
|
+
|
4
|
+
### Fixed
|
5
|
+
- Update `.babelrc` to fix compilation issues - [#306](https://github.com/rails/webpacker/issues/306)
|
6
|
+
|
7
|
+
- Duplicated asset hosts - [#320](https://github.com/rails/webpacker/issues/320), [#397](https://github.com/rails/webpacker/pull/397)
|
8
|
+
|
9
|
+
- Missing asset host when defined as a `Proc` or on `ActionController::Base.asset_host` directly - [#397](https://github.com/rails/webpacker/pull/397)
|
10
|
+
|
11
|
+
- Incorrect asset host when running `webpacker:compile` or `bin/webpack` in development mode - [#397](https://github.com/rails/webpacker/pull/397)
|
12
|
+
|
13
|
+
- Update `webpacker:compile` task to use `stdout` and `stderr` for better logging - [#395](https://github.com/rails/webpacker/issues/395)
|
14
|
+
|
15
|
+
- ARGV support for `webpack-dev-server` - [#286](https://github.com/rails/webpacker/issues/286)
|
16
|
+
|
17
|
+
|
18
|
+
### Added
|
19
|
+
- [Elm](http://elm-lang.org) support. You can now add Elm support via the following methods:
|
20
|
+
- New app: `rails new <app> --webpack=elm`
|
21
|
+
- Within an existing app: `rails webpacker:install:elm`
|
22
|
+
|
23
|
+
- Support for custom `public_output_path` paths independent of `source_entry_path` in `config/webpacker.yml`. `output` is also now relative to `public/`. - [#397](https://github.com/rails/webpacker/pull/397)
|
24
|
+
|
25
|
+
Before (compile to `public/packs`):
|
26
|
+
```yaml
|
27
|
+
source_entry_path: packs
|
28
|
+
public_output_path: packs
|
29
|
+
```
|
30
|
+
After (compile to `public/sweet/js`):
|
31
|
+
```yaml
|
32
|
+
source_entry_path: packs
|
33
|
+
public_output_path: sweet/js
|
34
|
+
```
|
35
|
+
|
36
|
+
- `https` option to use `https` mode, particularly on platforms like - https://community.c9.io/t/running-a-rails-app/1615 or locally - [#176](https://github.com/rails/webpacker/issues/176)
|
37
|
+
|
38
|
+
- [Babel] Dynamic import() and Class Fields and Static Properties babel plugin to `.babelrc`
|
39
|
+
|
40
|
+
```json
|
41
|
+
{
|
42
|
+
"presets": [
|
43
|
+
["env", {
|
44
|
+
"modules": false,
|
45
|
+
"targets": {
|
46
|
+
"browsers": "> 1%",
|
47
|
+
"uglify": true
|
48
|
+
},
|
49
|
+
"useBuiltIns": true
|
50
|
+
}]
|
51
|
+
],
|
52
|
+
|
53
|
+
"plugins": [
|
54
|
+
"syntax-dynamic-import",
|
55
|
+
"transform-class-properties", { "spec": true }
|
56
|
+
]
|
57
|
+
}
|
58
|
+
```
|
59
|
+
|
60
|
+
- Source-map support for production bundle
|
61
|
+
|
62
|
+
|
63
|
+
#### Breaking Change
|
64
|
+
|
65
|
+
- Consolidate and flatten `paths.yml` and `development.server.yml` config into one file - `config/webpacker.yml` - [#403](https://github.com/rails/webpacker/pull/403). This is a breaking change and requires you to re-install webpacker and cleanup old configuration files.
|
66
|
+
|
67
|
+
```bash
|
68
|
+
bundle update webpacker
|
69
|
+
bundle exec rails webpacker:install
|
70
|
+
|
71
|
+
# Remove old/unused configuration files
|
72
|
+
rm config/paths.yml
|
73
|
+
rm config/development.server.yml
|
74
|
+
rm config/development.server.js
|
75
|
+
```
|
76
|
+
|
77
|
+
|
1
78
|
## [1.2] - 2017-04-27
|
2
79
|
Some of the changes made requires you to run below commands to install new changes.
|
3
80
|
|
4
|
-
```
|
81
|
+
```
|
5
82
|
bundle update webpacker
|
6
83
|
bundle exec rails webpacker:install
|
7
84
|
```
|
8
85
|
|
86
|
+
|
9
87
|
### Fixed
|
10
88
|
- Support Spring - [#205](https://github.com/rails/webpacker/issues/205)
|
11
89
|
|
12
90
|
```ruby
|
13
|
-
|
91
|
+
Spring.after_fork { Webpacker.bootstrap } if defined?(Spring)
|
14
92
|
```
|
15
93
|
- Check node version and yarn before installing webpacker - [#217](https://github.com/rails/webpacker/issues/217)
|
16
94
|
|
@@ -24,31 +102,36 @@ bundle exec rails webpacker:install
|
|
24
102
|
|
25
103
|
- Move babel presets and plugins to .babelrc - [#202](https://github.com/rails/webpacker/issues/202)
|
26
104
|
|
105
|
+
|
27
106
|
### Added
|
28
107
|
- A changelog - [#211](https://github.com/rails/webpacker/issues/211)
|
29
108
|
- Minimize CSS assets - [#218](https://github.com/rails/webpacker/issues/218)
|
30
109
|
- Pack namespacing support - [#201](https://github.com/rails/webpacker/pull/201)
|
31
110
|
|
32
|
-
|
33
|
-
|
34
|
-
app/javascript/packs/admin/
|
35
|
-
app/javascript/packs/
|
36
|
-
app/javascript/packs/
|
37
|
-
|
111
|
+
For example:
|
112
|
+
```
|
113
|
+
app/javascript/packs/admin/hello_vue.js
|
114
|
+
app/javascript/packs/admin/hello.vue
|
115
|
+
app/javascript/packs/hello_vue.js
|
116
|
+
app/javascript/packs/hello.vue
|
117
|
+
```
|
38
118
|
- Add tree-shaking support - [#250](https://github.com/rails/webpacker/pull/250)
|
39
119
|
- Add initial test case by @kimquy [#259](https://github.com/rails/webpacker/pull/259)
|
40
120
|
- Compile assets before test:controllers and test:system
|
41
121
|
|
122
|
+
|
42
123
|
### Removed
|
43
124
|
- Webpack watcher - [#295](https://github.com/rails/webpacker/pull/295)
|
44
125
|
|
126
|
+
|
45
127
|
## [1.1] - 2017-03-24
|
46
128
|
|
47
129
|
This release requires you to run below commands to install new features.
|
48
130
|
|
49
|
-
```
|
131
|
+
```
|
50
132
|
bundle update webpacker
|
51
133
|
bundle exec rails webpacker:install
|
134
|
+
|
52
135
|
# if installed react, vue or angular
|
53
136
|
bundle exec rails webpacker:install:[react, angular, vue]
|
54
137
|
```
|
@@ -57,6 +140,7 @@ bundle exec rails webpacker:install:[react, angular, vue]
|
|
57
140
|
- Static assets support - [#153](https://github.com/rails/webpacker/pull/153)
|
58
141
|
- Advanced webpack configuration - [#153](https://github.com/rails/webpacker/pull/153)
|
59
142
|
|
143
|
+
|
60
144
|
### Removed
|
61
145
|
|
62
146
|
```rb
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,72 +1,501 @@
|
|
1
1
|
# Webpacker
|
2
|
+
|
2
3
|
![travis-ci status](https://api.travis-ci.org/rails/webpacker.svg?branch=master)
|
3
4
|
[![node.js](https://img.shields.io/badge/node-%3E%3D%206.4.0-brightgreen.svg)](https://nodejs.org/en/)
|
4
5
|
[![Gem](https://img.shields.io/gem/v/webpacker.svg)](https://github.com/rails/webpacker)
|
5
6
|
|
6
|
-
Webpacker makes it easy to use the JavaScript
|
7
|
+
Webpacker makes it easy to use the JavaScript pre-processor and bundler
|
8
|
+
[Webpack 2.x.x+](https://webpack.js.org/)
|
7
9
|
to manage application-like JavaScript in Rails. It coexists with the asset pipeline,
|
8
|
-
as the primary purpose for Webpack is app-like JavaScript, not images,
|
9
|
-
even JavaScript Sprinkles (that all continues to live in app/assets).
|
10
|
-
|
11
|
-
|
12
|
-
JavaScript frameworks.
|
10
|
+
as the primary purpose for Webpack is app-like JavaScript, not images, CSS, or
|
11
|
+
even JavaScript Sprinkles (that all continues to live in app/assets).
|
12
|
+
|
13
|
+
However, it is possible to use Webpacker for CSS, images and fonts assets as well,
|
14
|
+
in which case you may not even need the asset pipeline. This is mostly relevant when exclusively using component-based JavaScript frameworks.
|
15
|
+
|
16
|
+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
17
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
18
|
+
## Table of Contents
|
19
|
+
|
20
|
+
- [Prerequisites](#prerequisites)
|
21
|
+
- [Features](#features)
|
22
|
+
- [Installation](#installation)
|
23
|
+
- [Integrations](#integrations)
|
24
|
+
- [React](#react)
|
25
|
+
- [Angular with TypeScript](#angular-with-typescript)
|
26
|
+
- [Vue](#vue)
|
27
|
+
- [Elm](#elm)
|
28
|
+
- [Binstubs](#binstubs)
|
29
|
+
- [Webpack dev server](#webpack-dev-server)
|
30
|
+
- [Webpack](#webpack)
|
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)
|
63
|
+
- [Deployment](#deployment)
|
64
|
+
- [Heroku](#heroku)
|
65
|
+
- [Testing](#testing)
|
66
|
+
- [Troubleshooting](#troubleshooting)
|
67
|
+
- [Wishlist](#wishlist)
|
68
|
+
- [License](#license)
|
69
|
+
|
70
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
13
71
|
|
14
|
-
It's designed to work with Rails 5.1+ and makes use of the [Yarn](https://yarnpkg.com) dependency management
|
15
|
-
that's been made default from that version forward.
|
16
72
|
|
17
73
|
## Prerequisites
|
18
74
|
|
19
75
|
* Ruby 2.2+
|
20
76
|
* Rails 4.2+
|
21
77
|
* Node.js 6.4.0+
|
22
|
-
* Yarn
|
78
|
+
* Yarn 0.20.1+
|
79
|
+
|
80
|
+
|
81
|
+
## Features
|
82
|
+
|
83
|
+
* [Webpack 2](https://webpack.js.org/)
|
84
|
+
* ES6 with [babel](https://babeljs.io/)
|
85
|
+
* Automatic code splitting using multiple entry points
|
86
|
+
* Stylesheets - sass and CSS
|
87
|
+
* Images and fonts
|
88
|
+
* PostCSS - auto-prefixer
|
89
|
+
* Asset compression, source-maps, and minification
|
90
|
+
* CDN support
|
91
|
+
* React, Angular, Elm and Vue support out-of-the-box
|
92
|
+
* Rails view helpers
|
93
|
+
* Extensible and configurable
|
94
|
+
|
23
95
|
|
24
96
|
## Installation
|
25
97
|
|
26
|
-
|
27
|
-
|
98
|
+
You can either add Webpacker during setup of a new Rails 5.1+ application
|
99
|
+
using new `--webpack` option:
|
28
100
|
|
29
|
-
|
30
|
-
|
101
|
+
```bash
|
102
|
+
# Available Rails 5.1+
|
103
|
+
./bin/rails new myapp --webpack
|
104
|
+
```
|
31
105
|
|
32
|
-
|
106
|
+
Or add it to your `Gemfile`, run bundle and `./bin/rails webpacker:install` or `bundle exec rake webpacker:install` (on rails version < 5.0):
|
33
107
|
|
34
108
|
```ruby
|
35
|
-
|
109
|
+
# Gemfile
|
110
|
+
gem 'webpacker', '~> 2.0'
|
111
|
+
|
112
|
+
# OR if you prefer to use master
|
113
|
+
gem 'webpacker', git: 'https://github.com/rails/webpacker.git'
|
114
|
+
```
|
115
|
+
|
116
|
+
**Note:** Use `rake` instead of `rails` if you are using webpacker
|
117
|
+
with rails version < 5.0
|
118
|
+
|
119
|
+
|
120
|
+
## Integrations
|
121
|
+
|
122
|
+
Webpacker by default ships with basic out-of-the-box integration
|
123
|
+
for React, Angular, Vue and Elm. You can see a list of available
|
124
|
+
commands/tasks by running:
|
125
|
+
|
126
|
+
```bash
|
127
|
+
./bin/rails webpacker
|
128
|
+
```
|
129
|
+
|
130
|
+
or in rails version < 5.0
|
131
|
+
|
132
|
+
```bash
|
133
|
+
./bin/rake webpacker
|
134
|
+
```
|
135
|
+
|
136
|
+
|
137
|
+
### React
|
138
|
+
|
139
|
+
To use Webpacker with [React](https://facebook.github.io/react/), create a
|
140
|
+
new Rails 5.1+ app using `--webpack=react` option:
|
141
|
+
|
142
|
+
```bash
|
143
|
+
# Rails 5.1+
|
144
|
+
./bin/rails new myapp --webpack=react
|
145
|
+
```
|
146
|
+
|
147
|
+
(or run `./bin/rails webpacker:install:react` in a existing Rails app already
|
148
|
+
setup with webpacker).
|
149
|
+
|
150
|
+
The installer will add all relevant dependencies using yarn, any changes
|
151
|
+
to the configuration files and an example React component to your
|
152
|
+
project in `app/javascript/packs` so that you can experiment with React right away.
|
153
|
+
|
154
|
+
|
155
|
+
### Angular with TypeScript
|
156
|
+
|
157
|
+
To use Webpacker with [Angular](https://angularjs.org/), create a
|
158
|
+
new Rails 5.1+ app using `--webpack=angular` option:
|
159
|
+
|
160
|
+
```bash
|
161
|
+
# Rails 5.1+
|
162
|
+
./bin/rails new myapp --webpack=angular
|
163
|
+
```
|
164
|
+
|
165
|
+
(or run `./bin/rails webpacker:install:angular` on a Rails app already
|
166
|
+
setup with webpacker).
|
167
|
+
|
168
|
+
The installer will add TypeScript and Angular core libraries using yarn plus
|
169
|
+
any changes to the configuration files. An example component is written in
|
170
|
+
TypeScript will also be added to your project in `app/javascript` so that
|
171
|
+
you can experiment with Angular right away.
|
172
|
+
|
173
|
+
|
174
|
+
### Vue
|
175
|
+
|
176
|
+
To use Webpacker with [Vue](https://vuejs.org/), create a
|
177
|
+
new Rails 5.1+ app using `--webpack=vue` option:
|
178
|
+
|
179
|
+
```bash
|
180
|
+
# Rails 5.1+
|
181
|
+
./bin/rails new myapp --webpack=vue
|
182
|
+
```
|
183
|
+
(or run `./bin/rails webpacker:install:vue` on a Rails app already setup with webpacker).
|
184
|
+
|
185
|
+
The installer will add Vue and required libraries using yarn plus
|
186
|
+
any changes to the configuration files. An example component will
|
187
|
+
also be added to your project in `app/javascript` so that you can
|
188
|
+
experiment Vue right away.
|
189
|
+
|
190
|
+
|
191
|
+
### Elm
|
192
|
+
|
193
|
+
To use Webpacker with [Elm](http://elm-lang.org), create a
|
194
|
+
new Rails 5.1+ app using `--webpack=elm` option:
|
195
|
+
|
196
|
+
```
|
197
|
+
./bin/rails new myapp --webpack=elm
|
36
198
|
```
|
37
199
|
|
38
|
-
|
200
|
+
(or run `./bin/rails webpacker:install:elm` on a Rails app already setup with webpacker).
|
201
|
+
|
202
|
+
The Elm library and core packages will be added via Yarn and Elm itself.
|
203
|
+
An example `Main.elm` app will also be added to your project in `app/javascript`
|
204
|
+
so that you can experiment with Elm right away.
|
205
|
+
|
39
206
|
|
40
207
|
## Binstubs
|
41
208
|
|
42
209
|
Webpacker ships with two binstubs: `./bin/webpack` and `./bin/webpack-dev-server`.
|
43
|
-
|
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/)
|
44
224
|
|
45
|
-
|
46
|
-
|
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
|
+
```
|
47
261
|
|
48
|
-
In development, you'll need to run `./bin/webpack-dev-server` 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](https://ddollar.github.io/foreman). `./bin/webpack-dev-server` launches the [Webpack Dev Server](https://webpack.js.org/configuration/dev-server/), which serves your pack files on http://localhost:8080/, and provides advanced Webpack features, such as [Hot Module Replacement](https://webpack.js.org/guides/hmr-react/).
|
49
262
|
|
50
263
|
## Configuration
|
51
264
|
|
52
|
-
Webpacker gives you a default set of configuration files for development and production. They
|
53
|
-
all live together with the shared points in `config/webpack/*.js`. By default, you shouldn't have to
|
54
|
-
make any changes for a basic setup out the box. But this is where you do go if you need something
|
55
|
-
more advanced.
|
56
265
|
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
305
|
+
|
306
|
+
By default, webpacker ships with simple conventions for where the javascript
|
307
|
+
app files and compiled webpack bundles will go in your rails app,
|
308
|
+
but all these options are configurable from `config/webpacker.yml` file.
|
309
|
+
|
310
|
+
The configuration for what Webpack is supposed to compile by default rests
|
311
|
+
on the convention that every file in `app/javascript/packs/*`**(default)**
|
312
|
+
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).
|
314
|
+
|
315
|
+
Suppose you want to change the source directory from `app/javascript`
|
316
|
+
to `frontend` and output to `assets/packs` this is how you would do it:
|
317
|
+
|
318
|
+
```yml
|
319
|
+
# config/webpacker.yml
|
320
|
+
source_path: frontend
|
321
|
+
source_entry_path: packs
|
322
|
+
public_output_path: assets/packs => public/assets/packs
|
323
|
+
```
|
324
|
+
|
325
|
+
Similary you can also control and configure `webpack-dev-server` settings from `config/webpacker.yml` file:
|
326
|
+
|
327
|
+
```yml
|
328
|
+
# config/webpacker.yml
|
329
|
+
development:
|
330
|
+
dev_server:
|
331
|
+
host: 0.0.0.0
|
332
|
+
port: 8080
|
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.
|
60
351
|
|
61
|
-
|
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:
|
62
490
|
|
63
491
|
```js
|
64
492
|
// app/javascript/packs/calendar.js
|
65
|
-
|
493
|
+
|
494
|
+
import 'calendar'
|
66
495
|
```
|
67
496
|
|
68
497
|
```
|
69
|
-
app/javascript/calendar/index.js // gets loaded by
|
498
|
+
app/javascript/calendar/index.js // gets loaded by import 'calendar'
|
70
499
|
app/javascript/calendar/components/grid.jsx
|
71
500
|
app/javascript/calendar/styles/grid.sass
|
72
501
|
app/javascript/calendar/models/month.js
|
@@ -74,13 +503,17 @@ app/javascript/calendar/models/month.js
|
|
74
503
|
|
75
504
|
```erb
|
76
505
|
<%# app/views/layouts/application.html.erb %>
|
506
|
+
|
77
507
|
<%= javascript_pack_tag 'calendar' %>
|
78
508
|
<%= stylesheet_pack_tag 'calendar' %>
|
79
509
|
```
|
80
510
|
|
81
511
|
But it could also look a million other ways.
|
82
512
|
|
83
|
-
|
513
|
+
|
514
|
+
#### Namespacing
|
515
|
+
|
516
|
+
You can also namespace your packs using directories similar to a Rails app.
|
84
517
|
|
85
518
|
```
|
86
519
|
app/javascript/packs/admin/orders.js
|
@@ -91,6 +524,7 @@ and reference them in your views like this:
|
|
91
524
|
|
92
525
|
```erb
|
93
526
|
<%# app/views/admin/orders/index.html.erb %>
|
527
|
+
|
94
528
|
<%= javascript_pack_tag 'admin/orders' %>
|
95
529
|
```
|
96
530
|
|
@@ -98,82 +532,504 @@ and
|
|
98
532
|
|
99
533
|
```erb
|
100
534
|
<%# app/views/shop/orders/index.html.erb %>
|
535
|
+
|
101
536
|
<%= javascript_pack_tag 'shop/orders' %>
|
102
537
|
```
|
103
538
|
|
104
|
-
## Advanced Configuration
|
105
539
|
|
106
|
-
|
107
|
-
but all these options are configurable from `config/webpack/paths.yml` file.
|
540
|
+
### Pass data from view
|
108
541
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
+
})
|
116
579
|
```
|
117
580
|
|
118
|
-
*Note:* Behind the scenes, webpacker will use same `entry` directory name inside `output`
|
119
|
-
directory to emit bundles. For ex, `public/packs`
|
120
581
|
|
121
|
-
|
122
|
-
|
582
|
+
#### Vue
|
583
|
+
|
584
|
+
```erb
|
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
|
702
|
+
|
703
|
+
To add any new JS module you can use `yarn`:
|
704
|
+
|
705
|
+
```bash
|
706
|
+
yarn add bootstrap material-ui
|
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
|
123
816
|
|
124
817
|
```yml
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
818
|
+
extensions:
|
819
|
+
- .elm
|
820
|
+
- .coffee
|
821
|
+
- .html
|
822
|
+
```
|
823
|
+
|
824
|
+
4. Setup a custom `d.ts` definition
|
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
|
+
}
|
129
855
|
```
|
130
856
|
|
131
|
-
|
132
|
-
`paths.yml` as `contentBase`.
|
857
|
+
That's all. Voila!
|
133
858
|
|
134
|
-
## Linking to static assets
|
135
859
|
|
136
|
-
|
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:
|
137
879
|
|
138
880
|
```js
|
139
|
-
// React component example
|
140
|
-
// app/javascripts/packs/hello_react.jsx
|
141
881
|
import React from 'react'
|
142
|
-
import
|
143
|
-
import helloIcon from '../hello_react/images/icon.png'
|
144
|
-
import '../hello_react/styles/hello-react.sass'
|
882
|
+
import styles from './styles.css'
|
145
883
|
|
146
884
|
const Hello = props => (
|
147
|
-
<div className=
|
148
|
-
<img src={
|
149
|
-
<
|
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>
|
150
890
|
</div>
|
151
891
|
)
|
152
892
|
```
|
153
893
|
|
154
|
-
under the hood webpack uses [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) plugin to extract all the referenced styles and compile it into a separate `[pack_name].css` bundle so that within your view you can use the `stylesheet_pack_tag` helper,
|
155
894
|
|
156
|
-
|
157
|
-
|
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
|
+
}
|
158
933
|
```
|
159
934
|
|
160
|
-
|
935
|
+
And now all files with `.vue~` will be ignored by the webpack compiler.
|
936
|
+
|
937
|
+
|
938
|
+
### Link sprocket assets
|
939
|
+
|
161
940
|
|
162
|
-
|
941
|
+
#### Using helpers
|
163
942
|
|
164
|
-
|
165
|
-
for an asset used in your pack code you can reference them like this in your view,
|
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:
|
166
944
|
|
167
945
|
```erb
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
946
|
+
<%# app/javascript/my_pack/example.js.erb %>
|
947
|
+
|
948
|
+
<% helpers = ActionController::Base.helpers %>
|
949
|
+
var railsImagePath = "<%= helpers.image_path('rails.png') %>"
|
172
950
|
```
|
173
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:
|
979
|
+
|
980
|
+
```js
|
981
|
+
// Note: we don't have do any ../../ jazz
|
982
|
+
|
983
|
+
import FooImage from 'assets/images/foo-image.png'
|
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
|
+
}
|
1008
|
+
```
|
1009
|
+
|
1010
|
+
```js
|
1011
|
+
// config/webpack/production.js
|
1012
|
+
|
1013
|
+
const { plugins } = require('./app-config.js')
|
1014
|
+
|
1015
|
+
plugins: appConfig.plugins.concat([
|
1016
|
+
|
1017
|
+
// ...existing plugins
|
1018
|
+
|
1019
|
+
])
|
1020
|
+
```
|
1021
|
+
|
1022
|
+
But this could be done million other ways.
|
1023
|
+
|
1024
|
+
|
174
1025
|
## Deployment
|
175
1026
|
|
176
|
-
Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`.
|
1027
|
+
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` during your app deploy.
|
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:
|
177
1033
|
|
178
1034
|
```html
|
179
1035
|
<!-- In development mode with webpack-dev-server -->
|
@@ -187,33 +1043,62 @@ Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which
|
|
187
1043
|
<link rel="stylesheet" media="screen" href="/packs/calendar-dc02976b5f94b507e3b6.css">
|
188
1044
|
```
|
189
1045
|
|
190
|
-
## Linking to sprockets assets
|
191
1046
|
|
192
|
-
|
193
|
-
to your javascript file, then you can use Sprockets' asset helpers:
|
1047
|
+
### Heroku
|
194
1048
|
|
195
|
-
|
196
|
-
|
1049
|
+
Heroku installs yarn and node by default if you deploy a rails app with
|
1050
|
+
Webpacker so all you would need to do:
|
197
1051
|
|
198
|
-
|
199
|
-
|
1052
|
+
```bash
|
1053
|
+
heroku create shiny-webpacker-app
|
1054
|
+
heroku addons:create heroku-postgresql:hobby-dev
|
1055
|
+
git push heroku master
|
200
1056
|
```
|
201
1057
|
|
202
|
-
This is enabled by the `rails-erb-loader` loader rule in `config/webpack/shared.js`.
|
203
1058
|
|
204
|
-
##
|
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
|
+
)
|
205
1076
|
|
206
|
-
|
207
|
-
|
208
|
-
|
1077
|
+
document.addEventListener('DOMContentLoaded', () => {
|
1078
|
+
ReactDOM.render(
|
1079
|
+
<Hello />,
|
1080
|
+
document.body.appendChild(document.createElement('div')),
|
1081
|
+
)
|
1082
|
+
})
|
1083
|
+
```
|
209
1084
|
|
210
|
-
|
1085
|
+
```erb
|
1086
|
+
# views/pages/home.html.erb
|
211
1087
|
|
212
|
-
|
1088
|
+
<%= javascript_pack_tag "hello_react" %>
|
1089
|
+
```
|
213
1090
|
|
214
|
-
|
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
|
+
```
|
215
1101
|
|
216
|
-
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.
|
217
1102
|
|
218
1103
|
## Troubleshooting
|
219
1104
|
|
@@ -226,7 +1111,7 @@ An easy solution is to create a postinstall hook - `npm rebuild node-sass` in
|
|
226
1111
|
you install any new modules.
|
227
1112
|
|
228
1113
|
* If you get this error `Can't find hello_react.js in manifest.json`
|
229
|
-
when loading a view in browser it's because Webpack is still compiling packs.
|
1114
|
+
when loading a view in the browser it's because Webpack is still compiling packs.
|
230
1115
|
Webpacker uses a `manifest.json` file to keep track of packs in all environments,
|
231
1116
|
however since this file is generated after packs are compiled by webpack. So,
|
232
1117
|
if you load a view in browser whilst webpack is compiling you will get this error.
|
@@ -234,11 +1119,12 @@ Therefore, make sure webpack
|
|
234
1119
|
(i.e `./bin/webpack-dev-server`) is running and has
|
235
1120
|
completed the compilation successfully before loading a view.
|
236
1121
|
|
1122
|
+
|
237
1123
|
## Wishlist
|
238
1124
|
|
239
|
-
-
|
240
|
-
|
241
|
-
|
1125
|
+
- HMR - [#188](https://github.com/rails/webpacker/issues/188)
|
1126
|
+
- Support rails engines - [#348](https://github.com/rails/webpacker/issues/348)
|
1127
|
+
|
242
1128
|
|
243
1129
|
## License
|
244
1130
|
Webpacker is released under the [MIT License](https://opensource.org/licenses/MIT).
|