webpacker 3.6.0 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.node-version +1 -0
  3. data/.travis.yml +12 -4
  4. data/CHANGELOG.md +240 -28
  5. data/CONTRIBUTING.md +33 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +78 -71
  8. data/MIT-LICENSE +1 -1
  9. data/README.md +75 -16
  10. data/docs/assets.md +7 -4
  11. data/docs/css.md +47 -14
  12. data/docs/deployment.md +11 -0
  13. data/docs/engines.md +155 -0
  14. data/docs/es6.md +5 -5
  15. data/docs/testing.md +1 -1
  16. data/docs/troubleshooting.md +4 -4
  17. data/docs/v4-upgrade.md +132 -0
  18. data/docs/webpack.md +56 -3
  19. data/docs/yarn.md +12 -1
  20. data/gemfiles/Gemfile-rails-edge +1 -1
  21. data/gemfiles/Gemfile-rails.4.2.x +2 -2
  22. data/gemfiles/Gemfile-rails.5.0.x +2 -2
  23. data/gemfiles/Gemfile-rails.5.1.x +2 -2
  24. data/gemfiles/Gemfile-rails.5.2.x +10 -0
  25. data/lib/install/bin/webpack +5 -1
  26. data/lib/install/bin/webpack-dev-server +5 -1
  27. data/lib/install/coffee.rb +2 -2
  28. data/lib/install/config/.browserslistrc +1 -0
  29. data/lib/install/config/babel.config.js +70 -0
  30. data/lib/install/config/postcss.config.js +12 -0
  31. data/lib/install/config/webpacker.yml +26 -0
  32. data/lib/install/elm.rb +2 -2
  33. data/lib/install/erb.rb +2 -2
  34. data/lib/install/examples/react/babel.config.js +83 -0
  35. data/lib/install/examples/stimulus/application.js +1 -6
  36. data/lib/install/examples/stimulus/controllers/index.js +9 -0
  37. data/lib/install/examples/typescript/tsconfig.json +4 -0
  38. data/lib/install/examples/vue/hello_vue.js +6 -4
  39. data/lib/install/javascript/packs/application.js +8 -0
  40. data/lib/install/loaders/typescript.js +8 -3
  41. data/lib/install/loaders/vue.js +1 -8
  42. data/lib/install/react.rb +6 -19
  43. data/lib/install/template.rb +29 -30
  44. data/lib/install/typescript.rb +4 -4
  45. data/lib/install/vue.rb +14 -5
  46. data/lib/tasks/installers.rake +4 -2
  47. data/lib/tasks/webpacker/binstubs.rake +3 -2
  48. data/lib/tasks/webpacker/compile.rake +10 -5
  49. data/lib/tasks/webpacker/install.rake +3 -2
  50. data/lib/tasks/webpacker/verify_install.rake +1 -4
  51. data/lib/tasks/webpacker/yarn_install.rake +1 -1
  52. data/lib/webpacker/commands.rb +0 -1
  53. data/lib/webpacker/compiler.rb +17 -13
  54. data/lib/webpacker/configuration.rb +13 -5
  55. data/lib/webpacker/dev_server.rb +7 -10
  56. data/lib/webpacker/dev_server_proxy.rb +13 -6
  57. data/lib/webpacker/dev_server_runner.rb +13 -6
  58. data/lib/webpacker/helper.rb +78 -20
  59. data/lib/webpacker/manifest.rb +64 -21
  60. data/lib/webpacker/railtie.rb +16 -7
  61. data/lib/webpacker/runner.rb +3 -3
  62. data/lib/webpacker/version.rb +1 -1
  63. data/lib/webpacker/webpack_runner.rb +14 -3
  64. data/package.json +46 -34
  65. data/package/__tests__/config.js +37 -3
  66. data/package/__tests__/dev_server.js +15 -0
  67. data/package/__tests__/production.js +2 -2
  68. data/package/__tests__/staging.js +3 -3
  69. data/package/__tests__/test.js +2 -1
  70. data/package/config.js +21 -9
  71. data/package/config_types/config_list.js +5 -6
  72. data/package/dev_server.js +3 -1
  73. data/package/environments/__tests__/base.js +7 -5
  74. data/package/environments/base.js +84 -31
  75. data/package/environments/development.js +6 -2
  76. data/package/environments/production.js +46 -36
  77. data/package/rules/babel.js +10 -4
  78. data/package/rules/file.js +8 -3
  79. data/package/rules/index.js +7 -2
  80. data/package/rules/node_modules.js +23 -0
  81. data/package/utils/__tests__/get_style_rule.js +20 -0
  82. data/package/utils/deep_merge.js +5 -6
  83. data/package/utils/get_style_rule.js +29 -42
  84. data/package/utils/helpers.js +18 -6
  85. data/package/utils/objectify.js +1 -2
  86. data/test/compiler_test.rb +15 -3
  87. data/test/configuration_test.rb +9 -0
  88. data/test/dev_server_runner_test.rb +51 -0
  89. data/test/helper_test.rb +48 -5
  90. data/test/manifest_test.rb +14 -0
  91. data/test/rake_tasks_test.rb +34 -0
  92. data/test/test_app/config.ru +5 -0
  93. data/test/test_app/config/application.rb +1 -0
  94. data/test/test_app/config/webpack/development.js +0 -0
  95. data/test/test_app/config/webpacker.yml +20 -0
  96. data/test/test_app/config/webpacker_public_root.yml +19 -0
  97. data/test/test_app/package.json +13 -0
  98. data/test/test_app/public/packs/manifest.json +22 -1
  99. data/test/test_app/yarn.lock +11 -0
  100. data/test/test_helper.rb +1 -3
  101. data/test/webpack_runner_test.rb +51 -0
  102. data/yarn.lock +4077 -2816
  103. metadata +28 -6
  104. data/lib/install/config/.babelrc +0 -18
  105. data/lib/install/config/.postcssrc.yml +0 -3
  106. data/lib/install/examples/react/.babelrc +0 -6
@@ -1,4 +1,4 @@
1
- Copyright (c) 2016-2018 David Heinemeier Hansson, Basecamp
1
+ Copyright (c) 2016-2019 David Heinemeier Hansson, Basecamp
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # Webpacker
2
2
 
3
- ![travis-ci status](https://api.travis-ci.org/rails/webpacker.svg?branch=3-x-stable)
4
- [![node.js](https://img.shields.io/badge/node-%3E%3D%206.0.0-brightgreen.svg)](https://nodejs.org/en/)
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.14.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 3.x.x+](https://webpack.js.org/)
8
+ [webpack 4.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).
@@ -13,6 +13,8 @@ even JavaScript Sprinkles (that all continues to live in app/assets).
13
13
  However, it is possible to use Webpacker for CSS, images and fonts assets as well,
14
14
  in which case you may not even need the asset pipeline. This is mostly relevant when exclusively using component-based JavaScript frameworks.
15
15
 
16
+ **NOTE:** The master branch now hosts the code for v4.x.x. Please refer to [3-x-stable](https://github.com/rails/webpacker/tree/3-x-stable) branch for 3.x documentation. See the [v4-upgrade guide](docs/v4-upgrade.md) for an overview of the changes.
17
+
16
18
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
17
19
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
18
20
  ## Table of Contents
@@ -39,6 +41,7 @@ in which case you may not even need the asset pipeline. This is mostly relevant
39
41
  - [Watched](#watched)
40
42
  - [Deployment](#deployment)
41
43
  - [Docs](#docs)
44
+ - [Contributing](#contributing)
42
45
  - [License](#license)
43
46
 
44
47
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -48,13 +51,13 @@ in which case you may not even need the asset pipeline. This is mostly relevant
48
51
 
49
52
  * Ruby 2.2+
50
53
  * Rails 4.2+
51
- * Node.js 6.0.0+
52
- * Yarn 0.25.2+
54
+ * Node.js 6.14.4+
55
+ * Yarn 1.x+
53
56
 
54
57
 
55
58
  ## Features
56
59
 
57
- * [webpack 3.x.x](https://webpack.js.org/)
60
+ * [webpack 4.x.x](https://webpack.js.org/)
58
61
  * ES6 with [babel](https://babeljs.io/)
59
62
  * Automatic code splitting using multiple entry points
60
63
  * Stylesheets - Sass and CSS
@@ -85,9 +88,14 @@ gem 'webpacker', '~> 3.5'
85
88
 
86
89
  # OR if you prefer to use master
87
90
  gem 'webpacker', git: 'https://github.com/rails/webpacker.git'
91
+ yarn add https://github.com/rails/webpacker.git
92
+
93
+ # OR to try out 4.x pre-release
94
+ gem 'webpacker', '>= 4.0.x'
95
+ yarn add @rails/webpacker@next
88
96
  ```
89
97
 
90
- Finally, run following to install Webpacker:
98
+ Finally, run the following to install Webpacker:
91
99
 
92
100
  ```bash
93
101
  bundle
@@ -97,6 +105,11 @@ bundle exec rails webpacker:install
97
105
  bundle exec rake webpacker:install
98
106
  ```
99
107
 
108
+ Optional: To fix ["unmet peer dependency" warnings](https://github.com/rails/webpacker/issues/1078),
109
+
110
+ ```bash
111
+ yarn upgrade
112
+ ```
100
113
 
101
114
  ### Usage
102
115
 
@@ -129,6 +142,31 @@ can use the `asset_pack_path` helper:
129
142
  <img src="<%= asset_pack_path 'images/logo.svg' %>" />
130
143
  ```
131
144
 
145
+ If you are using new webpack 4 split chunks API, then consider using `javascript_packs_with_chunks_tag` helper, which creates html
146
+ tags for a pack and all the dependent chunks.
147
+
148
+ ```erb
149
+ <%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %>
150
+
151
+ <script src="/packs/vendor-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
152
+ <script src="/packs/calendar~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
153
+ <script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
154
+ <script src="/packs/map~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
155
+ <script src="/packs/map-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
156
+ ```
157
+
158
+ **Important:** Pass all your pack names when using `javascript_packs_with_chunks_tag`
159
+ helper otherwise you will get duplicated chunks on the page.
160
+
161
+ ```erb
162
+ <%# DO %>
163
+ <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
164
+
165
+ <%# DON'T %>
166
+ <%= javascript_packs_with_chunks_tag 'calendar' %>
167
+ <%= javascript_packs_with_chunks_tag 'map' %>
168
+ ```
169
+
132
170
  **Note:** In order for your styles or static assets files to be available in your view,
133
171
  you would need to link them in your "pack" or entry file.
134
172
 
@@ -186,7 +224,9 @@ WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpack-dev-server
186
224
  **Note:** You need to allow webpack-dev-server host as an allowed origin for `connect-src` if you are running your application in a restrict CSP environment (like Rails 5.2+). This can be done in Rails 5.2+ in the CSP initializer `config/initializers/content_security_policy.rb` with a snippet like this:
187
225
 
188
226
  ```ruby
189
- policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035' if Rails.env.development?
227
+ Rails.application.config.content_security_policy do |policy|
228
+ policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035' if Rails.env.development?
229
+ end
190
230
  ```
191
231
 
192
232
  **Note:** Don't forget to prefix `ruby` when running these binstubs on Windows
@@ -216,7 +256,7 @@ staging:
216
256
  public_output_path: packs-staging
217
257
  ```
218
258
 
219
- or, Webpacker will use production environment as a fallback environment for loading configurations. Please note, `NODE_ENV` can either be set to `production` or `development`.
259
+ or, Webpacker will use production environment as a fallback environment for loading configurations. Please note, `NODE_ENV` can either be set to `production`, `development` or `test`.
220
260
  This means you don't need to create additional environment files inside `config/webpacker/*` and instead use webpacker.yml to load different configurations using `RAILS_ENV`.
221
261
 
222
262
  For example, the below command will compile assets in production mode but will use staging configurations from `config/webpacker.yml` if available or use fallback production environment configuration:
@@ -252,24 +292,32 @@ You can run following commands to upgrade Webpacker to the latest stable version
252
292
 
253
293
  ```bash
254
294
  bundle update webpacker
295
+ rails webpacker:binstubs
255
296
  yarn upgrade @rails/webpacker --latest
256
- yarn add webpack-dev-server@^2.11.1
297
+ yarn add webpack-dev-server@^3.1.14
298
+
299
+ # Or to install a latest release (including pre-releases)
300
+ yarn add @rails/webpacker@next
257
301
  ```
258
302
 
259
303
  ### Yarn Integrity
260
304
 
261
305
  By default, in development, webpacker runs a yarn integrity check to ensure that all local JavaScript packages are up-to-date. This is similar to what bundler does currently in Rails, but for JavaScript packages. If your system is out of date, then Rails will not initialize. You will be asked to upgrade your local JavaScript packages by running `yarn install`.
262
306
 
263
- To turn off this option, you will need to override the default by adding a new config option to your Rails development environment configuration file (`config/environment/development.rb`):
307
+ To turn off this option, you will need to change the default setting in `config/webpacker.yml`:
264
308
 
265
- ```
266
- config.webpacker.check_yarn_integrity = false
309
+ ```yaml
310
+ # config/webpacker.yml
311
+ development:
312
+ ...
313
+ # Verifies that versions and hashed value of the package contents in the project's package.json
314
+ check_yarn_integrity: false
267
315
  ```
268
316
 
269
- You may also turn on this feature by adding the config option to any Rails environment configuration file:
317
+ You may also turn on this feature by adding the config option for any Rails environment in `config/webpacker.yml`:
270
318
 
271
- ```
272
- config.webpacker.check_yarn_integrity = true
319
+ ```yaml
320
+ check_yarn_integrity: true
273
321
  ```
274
322
 
275
323
  ## Integrations
@@ -323,11 +371,13 @@ development environment. This can be done in the `config/initializers/content_se
323
371
  with the following code:
324
372
 
325
373
  ```ruby
374
+ Rails.application.config.content_security_policy do |policy|
326
375
  if Rails.env.development?
327
376
  policy.script_src :self, :https, :unsafe_eval
328
377
  else
329
378
  policy.script_src :self, :https
330
379
  end
380
+ end
331
381
  ```
332
382
 
333
383
 
@@ -351,11 +401,13 @@ This can be done in the `config/initializers/content_security_policy.rb` with th
351
401
  configuration:
352
402
 
353
403
  ```ruby
404
+ Rails.application.config.content_security_policy do |policy|
354
405
  if Rails.env.development?
355
406
  policy.script_src :self, :https, :unsafe_eval
356
407
  else
357
408
  policy.script_src :self, :https
358
409
  end
410
+ end
359
411
  ```
360
412
  You can read more about this in the [Vue docs](https://vuejs.org/v2/guide/installation.html#CSP-environments).
361
413
 
@@ -488,10 +540,17 @@ Webpacker::Compiler.watched_paths << 'bower_components'
488
540
 
489
541
  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, `webpacker:compile` is automatically aliased to `assets:precompile`. Similar to sprockets both rake tasks will compile packs in production mode but will use `RAILS_ENV` to load configuration from `config/webpacker.yml` (if available).
490
542
 
543
+
491
544
  ## Docs
492
545
 
493
546
  You can find more detailed guides under [docs](./docs).
494
547
 
495
548
 
549
+ ## Contributing
550
+ [![Code Helpers](https://www.codetriage.com/rails/webpacker/badges/users.svg)](https://www.codetriage.com/rails/webpacker)
551
+
552
+ We encourage you to contribute to Webpacker! See [CONTRIBUTING](CONTRIBUTING.md) for guidelines about how to proceed.
553
+
554
+
496
555
  ## License
497
556
  Webpacker is released under the [MIT License](https://opensource.org/licenses/MIT).
@@ -56,12 +56,12 @@ You can also use [babel-plugin-module-resolver](https://github.com/tleunen/babel
56
56
  yarn add babel-plugin-module-resolver
57
57
  ```
58
58
 
59
- Specify the plugin in your `.babelrc` with the custom root or alias. Here's an example:
59
+ Specify the plugin in your `babel.config.js` with the custom root or alias. Here's an example:
60
60
 
61
- ```json
61
+ ```js
62
62
  {
63
- "plugins": [
64
- ["module-resolver", {
63
+ plugins: [
64
+ [require("babel-plugin-module-resolver").default, {
65
65
  "root": ["./app"],
66
66
  "alias": {
67
67
  "assets": "./assets"
@@ -103,4 +103,7 @@ app/javascript:
103
103
 
104
104
  <img src="<%= asset_pack_path 'images/calendar.png' %>" />
105
105
  <% # => <img src="/packs/images/calendar.png" /> %>
106
+
107
+ <%= image_pack_tag 'images/calendar.png' %>
108
+ <% # => <img src="/packs/images/calendar.png" /> %>
106
109
  ```
@@ -16,7 +16,7 @@ Webpacker supports importing CSS, Sass and SCSS files directly into your JavaScr
16
16
 
17
17
  ```js
18
18
  // React component example
19
- // app/javascripts/packs/hello_react.jsx
19
+ // app/javascript/packs/hello_react.jsx
20
20
 
21
21
  import React from 'react'
22
22
  import helloIcon from '../hello_react/images/icon.png'
@@ -44,7 +44,7 @@ Stylesheets end with `.module.*` is treated as [CSS Modules](https://github.com/
44
44
 
45
45
  ```js
46
46
  // React component example
47
- // app/javascripts/packs/hello_react.jsx
47
+ // app/javascript/packs/hello_react.jsx
48
48
 
49
49
  import React from 'react'
50
50
  import helloIcon from '../hello_react/images/icon.png'
@@ -64,7 +64,7 @@ const Hello = props => (
64
64
  ## Link styles from your Rails views
65
65
 
66
66
  Under the hood webpack uses
67
- [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
67
+ [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) plugin to extract all the referenced styles within your app and compile it into
68
68
  a separate `[pack_name].css` bundle so that in your view you can use the
69
69
  `stylesheet_pack_tag` helper.
70
70
 
@@ -72,6 +72,7 @@ a separate `[pack_name].css` bundle so that in your view you can use the
72
72
  <%= stylesheet_pack_tag 'hello_react' %>
73
73
  ```
74
74
 
75
+ Webpacker emits css files only if `extract_css` is set to true in webpacker.yml otherwise `stylesheet_pack_tag` returns nil.
75
76
 
76
77
  ## Add bootstrap
77
78
 
@@ -102,13 +103,22 @@ Or in your app/javascript/app.sass file:
102
103
 
103
104
  Webpacker out-of-the-box provides CSS post-processing using
104
105
  [postcss-loader](https://github.com/postcss/postcss-loader)
105
- and the installer sets up a standard `.postcssrc.yml`
106
+ and the installer sets up a standard `postcss.config.js`
106
107
  file in your app root with standard plugins.
107
108
 
108
- ```yml
109
- plugins:
110
- postcss-import: {}
111
- postcss-cssnext: {}
109
+ ```js
110
+ module.exports = {
111
+ plugins: [
112
+ require('postcss-import'),
113
+ require('postcss-flexbugs-fixes'),
114
+ require('postcss-preset-env')({
115
+ autoprefixer: {
116
+ flexbox: 'no-2009'
117
+ },
118
+ stage: 3
119
+ })
120
+ ]
121
+ }
112
122
  ```
113
123
 
114
124
  ## Using CSS with [vue-loader](https://github.com/vuejs/vue-loader)
@@ -145,12 +155,35 @@ environment.loaders.get('sass').use.splice(-1, 0, {
145
155
  });
146
156
  ```
147
157
 
148
- ## Configure [Autoprefixer](https://github.com/postcss/autoprefixer)
158
+ ## Working with TypeScript
159
+
160
+ In order to get CSS to work with typescript you have two options.
161
+ You can either use `require` to bypass typescript special `import`.
162
+
163
+ ```ts
164
+ const styles = require('../hello_react/styles/hello-react');
165
+ ```
166
+ You may also use the package [typings-for-css-modules-loader](https://github.com/Jimdo/typings-for-css-modules-loader) instead of `css-loader` to automatically generate typescript `.d.ts` files in order to help resolve any css/scss styles. To do that:
149
167
 
150
- By default, Autoprefixer does not apply Internet Explorer CSS grid polyfills. If you wish to enable these, or change any other Autoprefixer config, do it through `.postcssrc.yml`:
168
+ ```js
169
+ // app/javascript/packs/hello_react.jsx
170
+ import * as styles from '../hello_react.styles/hello-react.module.scss';
171
+ ```
151
172
 
152
- ```yml
153
- plugins:
154
- postcss-import: {}
155
- postcss-cssnext: { features: { autoprefixer: { grid: true } } }
173
+ ```bash
174
+ yarn add --dev typings-for-css-modules-loader
175
+ ```
176
+
177
+ ```js
178
+ // webpack/environment.js
179
+ const { environment } = require('@rails/webpacker')
180
+
181
+ // replace css-loader with typings-for-css-modules-loader
182
+ environment.loaders.get('moduleSass').use = environment.loaders.get('moduleSass').use.map((u) => {
183
+ if(u.loader == 'css-loader') {
184
+ return { ...u, loader: 'typings-for-css-modules-loader' };
185
+ } else {
186
+ return u;
187
+ }
188
+ });
156
189
  ```
@@ -72,3 +72,14 @@ server {
72
72
 
73
73
  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
74
74
  you don't need to do anything extra for Webpacker, it just works.
75
+
76
+ ## Capistrano
77
+
78
+ ### Assets compiling on every deployment even if JavaScript and CSS files are not changed
79
+
80
+ Make sure you have `public/packs` and `node_modules` in `:linked_dirs`
81
+
82
+ ```ruby
83
+ append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/packs", ".bundle", "node_modules"
84
+ ```
85
+
@@ -0,0 +1,155 @@
1
+ # Using in Rails engines
2
+
3
+ If the application UI consists of multiple frontend application, you'd probably like to isolate their building too (e.g. if you use different frameworks/versions). Hence we needed our webpack(-er) to be isolated too: separate `package.json`, dev server, compilation process.
4
+
5
+ You can do this by adding another Webpacker instance to your application.
6
+
7
+ This guide describes how to do that using [Rails engines](https://guides.rubyonrails.org/engines.html).
8
+
9
+
10
+ ## Step 1: create Rails engine.
11
+
12
+ First, you create a Rails engine (say, `MyEngine`). See the offical [Rails guide](https://guides.rubyonrails.org/engines.html).
13
+
14
+ ## Step 2: install Webpacker within the engine.
15
+
16
+ There is no built-in tasks to install Webpacker within the engine, thus you have to add all the require files manually (you can copy them from the main app):
17
+ - Add `config/webpacker.yml` and `config/webpack/*.js` files
18
+ - Add `bin/webpack` and `bin/webpack-dev-server` files
19
+ - Add `package.json` with required deps.
20
+
21
+
22
+ ## Step 3: configure Webpacker instance.
23
+
24
+ ```ruby
25
+ module MyEngine
26
+ ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
27
+
28
+ class << self
29
+ def webpacker
30
+ @webpacker ||= ::Webpacker::Instance.new(
31
+ root_path: ROOT_PATH,
32
+ config_path: ROOT_PATH.join("config/webpacker.yml")
33
+ )
34
+ end
35
+ end
36
+ end
37
+ ```
38
+
39
+ ## Step 4: Configure dev server proxy.
40
+
41
+ ```ruby
42
+ module MyEngine
43
+ class Engine < ::Rails::Engine
44
+ initializer "webpacker.proxy" do |app|
45
+ insert_middleware = begin
46
+ MyEngine.webpacker.config.dev_server.present?
47
+ rescue
48
+ nil
49
+ end
50
+ next unless insert_middleware
51
+
52
+ app.middleware.insert_before(
53
+ 0, Webpacker::DevServerProxy, # "Webpacker::DevServerProxy" if Rails version < 5
54
+ ssl_verify_none: true,
55
+ webpacker: MyEngine.webpacker
56
+ )
57
+ end
58
+ end
59
+ end
60
+ ```
61
+
62
+ If you have multiple webpackers, you would probably want to run multiple dev servers at a time, and hence be able to configure their setting through env vars (e.g. within a `docker-compose.yml` file):
63
+
64
+ ```yml
65
+ # webpacker.yml
66
+ # ...
67
+ development:
68
+ # ...
69
+ dev_server:
70
+ env_prefix: "MY_ENGINE_WEBPACKER_DEV_SERVER"
71
+ # ...
72
+ ```
73
+
74
+ ## Step 5: configure helper.
75
+
76
+ ```ruby
77
+ require "webpacker/helper"
78
+
79
+ module MyEngine
80
+ module ApplicationHelper
81
+ include ::Webpacker::Helper
82
+
83
+ def current_webpacker_instance
84
+ MyEngine.webpacker
85
+ end
86
+ end
87
+ end
88
+ ```
89
+
90
+ Now you can use `stylesheet_pack_tag` and `javascript_pack_tag` from within your engine.
91
+
92
+ ## Step 6: rake tasks.
93
+
94
+ Add Rake task to compile assets in production (`rake my_engine:webpacker:compile`)
95
+
96
+ ```ruby
97
+ namespace :my_engine do
98
+ namespace :webpacker do
99
+ desc "Install deps with yarn"
100
+ task :yarn_install do
101
+ Dir.chdir(File.join(__dir__, "../..")) do
102
+ system "yarn install --no-progress --production"
103
+ end
104
+ end
105
+
106
+ desc "Compile JavaScript packs using webpack for production with digests"
107
+ task compile: [:yarn_install, :environment] do
108
+ Webpacker.with_node_env("production") do
109
+ if MyEngine.webpacker.commands.compile
110
+ # Successful compilation!
111
+ else
112
+ # Failed compilation
113
+ exit!
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ ```
120
+
121
+ ## Step 7: serving compiled packs.
122
+
123
+ There are two approaches on serving compiled assets.
124
+
125
+ ### Put engine's assets to the root app's public/ folder
126
+
127
+ You can serve engine's assets using the main app's static files server which serves files from `public/` folder.
128
+
129
+ For that you must configure your engine's webpacker to put compiled assets to the app's `public/` folder:
130
+
131
+ ```yml
132
+ # my_engine/config/webpacker.yml
133
+ default: &default
134
+ # ...
135
+ # public_root_path could be used to override the path to `public/` folder
136
+ # (relative to the engine root)
137
+ public_root_path: ../public
138
+ # use a different sub-folder name
139
+ public_output_path: my-engine-packs
140
+ ```
141
+
142
+ ### Use a separate middleware
143
+
144
+ To serve static assets from the engine's `public/` folder you must add a middleware and point it to your engine's webpacker output path:
145
+
146
+ ```ruby
147
+ # application.rb
148
+
149
+ config.middleware.use(
150
+ "Rack::Static",
151
+ urls: ["/my-engine-packs"], root: "my_engine/public"
152
+ )
153
+ ```
154
+
155
+ **NOTE:** in the example above we assume that your `public_output_path` is set to `my-engine-packs` in your engine's `webpacker.yml`.