webpacker 6.0.0.beta.2 → 6.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -18
  3. data/Gemfile.lock +1 -1
  4. data/README.md +96 -219
  5. data/docs/assets.md +135 -0
  6. data/docs/cloud9.md +310 -0
  7. data/docs/css.md +303 -0
  8. data/docs/deployment.md +148 -0
  9. data/docs/docker.md +68 -0
  10. data/docs/engines.md +213 -0
  11. data/docs/env.md +68 -0
  12. data/docs/es6.md +72 -0
  13. data/docs/folder-structure.md +66 -0
  14. data/docs/integrations.md +220 -0
  15. data/docs/misc.md +23 -0
  16. data/docs/props.md +187 -0
  17. data/docs/react.md +183 -0
  18. data/docs/target.md +22 -0
  19. data/docs/testing.md +147 -0
  20. data/docs/troubleshooting.md +158 -0
  21. data/docs/typescript.md +190 -0
  22. data/docs/v4-upgrade.md +142 -0
  23. data/docs/webpack-dev-server.md +94 -0
  24. data/docs/webpack.md +315 -0
  25. data/docs/yarn.md +23 -0
  26. data/lib/install/examples/vue3/app.vue +27 -0
  27. data/lib/install/examples/vue3/hello_vue.js +15 -0
  28. data/lib/install/javascript/packs/application.js +1 -3
  29. data/lib/webpacker/compiler.rb +2 -8
  30. data/lib/webpacker/version.rb +1 -1
  31. data/package.json +1 -1
  32. data/package/babel/preset-react.js +62 -0
  33. data/package/babel/preset.js +13 -24
  34. data/package/environments/__tests__/base.js +1 -1
  35. data/package/environments/base.js +19 -19
  36. data/package/environments/production.js +30 -28
  37. data/package/index.js +2 -7
  38. data/package/rules/coffee.js +5 -5
  39. data/package/rules/erb.js +3 -5
  40. data/package/rules/file.js +3 -5
  41. data/package/rules/index.js +17 -9
  42. data/package/rules/less.js +10 -14
  43. data/package/rules/sass.js +9 -13
  44. data/package/rules/svg.js +23 -0
  45. data/package/utils/get_style_rule.js +31 -27
  46. data/package/utils/helpers.js +0 -23
  47. metadata +29 -7
  48. data/6_0_upgrade.md +0 -43
  49. data/package/rules/raw.js +0 -5
  50. data/package/rules/stylus.js +0 -26
@@ -0,0 +1,148 @@
1
+ # Deployment
2
+
3
+
4
+ Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`.
5
+ If you are not using Sprockets `webpacker:compile` is automatically aliased to `assets:precompile`. Remember to set NODE_ENV environment variable to production during deployment or when running the rake task.
6
+
7
+ 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.
8
+
9
+ By default the output will look like this in different environments:
10
+
11
+ ```html
12
+ <!-- In development mode with webpack-dev-server -->
13
+ <script src="http://localhost:8080/calendar-0bd141f6d9360cf4a7f5.js"></script>
14
+ <link rel="stylesheet" media="screen" href="http://localhost:8080/calendar-dc02976b5f94b507e3b6.css">
15
+ <!-- In production or development mode -->
16
+ <script src="/packs/js/calendar-0bd141f6d9360cf4a7f5.js"></script>
17
+ <link rel="stylesheet" media="screen" href="/packs/css/calendar-dc02976b5f94b507e3b6.css">
18
+ ```
19
+
20
+
21
+ ## Heroku
22
+
23
+ In order for your Webpacker app to run on Heroku, you'll need to do a bit of configuration before hand.
24
+
25
+ ```
26
+ heroku create my-webpacker-heroku-app
27
+ heroku addons:create heroku-postgresql:hobby-dev
28
+ heroku buildpacks:add heroku/nodejs
29
+ heroku buildpacks:add heroku/ruby
30
+ git push heroku master
31
+ ```
32
+
33
+ We're essentially doing the following here:
34
+
35
+ * Creating an app on Heroku
36
+ * Creating a Postgres database for the app (this is assuming that you're using Heroku Postgres for your app)
37
+ * Adding the Heroku NodeJS and Ruby buildpacks for your app. This allows the `npm` or `yarn` executables to properly function when compiling your app - as well as Ruby.
38
+ * Pushing our code to Heroku and kicking off the deployment
39
+
40
+
41
+ ## Nginx
42
+
43
+ Webpacker doesn't serve anything in production. You’re expected to configure your web server to serve files in public/ directly.
44
+
45
+ Some servers support sending precompressed versions of files when they're available. For example, nginx offers a `gzip_static` directive that serves files with the `.gz` extension to supported clients. With an optional module, nginx can also serve Brotli compressed files with the `.br` extension (see below for installation and configuration instructions).
46
+
47
+ Here's a sample nginx site config for a Rails app using Webpacker:
48
+
49
+ ```nginx
50
+ upstream app {
51
+ # server unix:///path/to/app/tmp/puma.sock;
52
+ }
53
+
54
+ server {
55
+ listen 80;
56
+ server_name www.example.com;
57
+ root /path/to/app/public;
58
+
59
+ location @app {
60
+ proxy_pass http://app;
61
+ proxy_redirect off;
62
+
63
+ proxy_set_header Host $host;
64
+ proxy_set_header X-Real-IP $remote_addr;
65
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
66
+ proxy_set_header X-Forwarded-Proto $scheme;
67
+ }
68
+
69
+ location / {
70
+ try_files $uri @app;
71
+ }
72
+
73
+ location = /favicon.ico { access_log off; log_not_found off; }
74
+ location = /robots.txt { access_log off; log_not_found off; }
75
+
76
+ location ~ /\.(?!well-known).* {
77
+ deny all;
78
+ }
79
+
80
+ location ~ ^/(assets|packs)/ {
81
+ gzip_static on;
82
+ brotli_static on; # Optional, see below
83
+ expires max;
84
+ add_header Cache-Control public;
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### Installing the ngx_brotli module
90
+
91
+ If you want to serve Brotli compressed files with nginx, you will need to install the `nginx_brotli` module. Installation instructions from source can be found in the official [google/ngx_brotli](https://github.com/google/ngx_brotli) git repository. Alternatively, depending on your platform, the module might be available via a pre-compiled package.
92
+
93
+ Once installed, you need to load the module. As we want to serve the pre-compressed files, we only need the static module. Add the following line to your `nginx.conf` file and reload nginx:
94
+
95
+ ```
96
+ load_module modules/ngx_http_brotli_static_module.so;
97
+ ```
98
+
99
+ Now, you can set `brotli_static on;` in your nginx site config, as per the config in the last section above.
100
+
101
+ ## CDN
102
+
103
+ 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
104
+ you don't need to do anything extra for Webpacker, it just works.
105
+
106
+ ## Capistrano
107
+
108
+ ### Assets compiling on every deployment even if JavaScript and CSS files are not changed
109
+
110
+ Make sure you have `public/packs` and `node_modules` in `:linked_dirs`
111
+
112
+ ```ruby
113
+ append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/packs", ".bundle", "node_modules"
114
+ ```
115
+
116
+ If you have `node_modules` added to `:linked_dirs` you'll need to run yarn install before `deploy:assets:precompile`, so you can add this code snippet at the bottom deploy.rb
117
+
118
+ ```ruby
119
+ before "deploy:assets:precompile", "deploy:yarn_install"
120
+ namespace :deploy do
121
+ desc "Run rake yarn install"
122
+ task :yarn_install do
123
+ on roles(:web) do
124
+ within release_path do
125
+ execute("cd #{release_path} && yarn install --silent --no-progress --no-audit --no-optional")
126
+ end
127
+ end
128
+ end
129
+ end
130
+ ```
131
+
132
+ If you use [nvm](https://github.com/nvm-sh/nvm) to manage node versions for your deployment user, use the below snippet instead:
133
+
134
+ ```ruby
135
+ before "deploy:assets:precompile", "deploy:yarn_install"
136
+ namespace :deploy do
137
+ desc "Run rake yarn install"
138
+ task :yarn_install do
139
+ on roles(:web) do
140
+ within release_path do
141
+ execute("source ~/.nvm/nvm.sh && cd #{release_path} && yarn install --silent --no-progress --no-audit --no-optional")
142
+ end
143
+ end
144
+ end
145
+ end
146
+ ```
147
+ The `source ~/.nvm/nvm.sh` is required because [nvm is not automatically loaded in non-interactive shells](https://github.com/nvm-sh/nvm/issues/1718).
148
+
@@ -0,0 +1,68 @@
1
+ # Docker
2
+
3
+ To setup webpacker with a dockerized Rails application.
4
+
5
+ First, add a new service for webpacker in docker-compose.yml:
6
+
7
+ ```Dockerfile
8
+ version: '3'
9
+ services:
10
+ webpacker:
11
+ build: .
12
+ environment:
13
+ - NODE_ENV=development
14
+ - RAILS_ENV=development
15
+ - WEBPACKER_DEV_SERVER_HOST=0.0.0.0
16
+ command: ./bin/webpack-dev-server
17
+ volumes:
18
+ - .:/webpacker-example-app
19
+ ports:
20
+ - '127.0.0.1:3035:3035'
21
+ ```
22
+
23
+ add nodejs and yarn as dependencies in Dockerfile,
24
+
25
+ ```dockerfile
26
+ FROM ruby:2.4.1
27
+
28
+ RUN apt-get update -qq && apt-get install -y build-essential nodejs \
29
+ && rm -rf /var/lib/apt/lists/* \
30
+ && curl -o- -L https://yarnpkg.com/install.sh | bash
31
+
32
+ # Rest of the commands....
33
+ ```
34
+
35
+ Please note: if using `assets:precompile` in the Dockerfile or have issues with the snippet above then try:
36
+
37
+ ```dockerfile
38
+ FROM ruby:2.4.1
39
+
40
+ RUN curl -sL https://deb.nodesource.com/setup_8.x | bash \
41
+ && apt-get update && apt-get install -y nodejs && rm -rf /var/lib/apt/lists/* \
42
+ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
43
+ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
44
+ && apt-get update && apt-get install -y yarn && rm -rf /var/lib/apt/lists/*
45
+
46
+ # Rest of the commands....
47
+ ```
48
+
49
+ then add the webpacker host name environment variable to the web/app service:
50
+
51
+ ```Dockerfile
52
+ web:
53
+ build:
54
+ context: .
55
+ command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
56
+ volumes:
57
+ - .:/usr/src/app
58
+ ports:
59
+ - "127.0.0.1:3000:3000"
60
+ environment:
61
+ - WEBPACKER_DEV_SERVER_HOST=webpacker
62
+ ```
63
+
64
+ Lastly, rebuild your container:
65
+
66
+ ```bash
67
+ docker-compose up --build
68
+ ```
@@ -0,0 +1,213 @@
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 official [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
+ - File `lib/my_engine.rb`
25
+
26
+ ```ruby
27
+ module MyEngine
28
+ ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
29
+
30
+ class << self
31
+ def webpacker
32
+ @webpacker ||= ::Webpacker::Instance.new(
33
+ root_path: ROOT_PATH,
34
+ config_path: ROOT_PATH.join("config/webpacker.yml")
35
+ )
36
+ end
37
+ end
38
+ end
39
+ ```
40
+
41
+ ## Step 4: Configure dev server proxy.
42
+
43
+ - File `lib/my_engine/engine.rb`
44
+
45
+ ```ruby
46
+ module MyEngine
47
+ class Engine < ::Rails::Engine
48
+ initializer "webpacker.proxy" do |app|
49
+ insert_middleware = begin
50
+ MyEngine.webpacker.config.dev_server.present?
51
+ rescue
52
+ nil
53
+ end
54
+ next unless insert_middleware
55
+
56
+ app.middleware.insert_before(
57
+ 0, Webpacker::DevServerProxy, # "Webpacker::DevServerProxy" if Rails version < 5
58
+ ssl_verify_none: true,
59
+ webpacker: MyEngine.webpacker
60
+ )
61
+ end
62
+ end
63
+ end
64
+ ```
65
+
66
+ 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):
67
+
68
+ ```yml
69
+ # webpacker.yml
70
+ # ...
71
+ development:
72
+ # ...
73
+ dev_server:
74
+ env_prefix: "MY_ENGINE_WEBPACKER_DEV_SERVER"
75
+ # ...
76
+ ```
77
+
78
+ ## Step 5: configure helper.
79
+
80
+ - File `app/helpers/my_engine/application_helper.rb`
81
+
82
+ ```ruby
83
+ require "webpacker/helper"
84
+
85
+ module MyEngine
86
+ module ApplicationHelper
87
+ include ::Webpacker::Helper
88
+
89
+ def current_webpacker_instance
90
+ MyEngine.webpacker
91
+ end
92
+ end
93
+ end
94
+ ```
95
+
96
+ Now you can use `stylesheet_pack_tag` and `javascript_pack_tag` from within your engine.
97
+
98
+ ## Step 6: rake tasks.
99
+
100
+ Add Rake task to compile assets in production (`rake my_engine:webpacker:compile`)
101
+
102
+ - File `lib/tasks/my_engine_tasks.rake`
103
+
104
+ ```ruby
105
+ def ensure_log_goes_to_stdout
106
+ old_logger = Webpacker.logger
107
+ Webpacker.logger = ActiveSupport::Logger.new(STDOUT)
108
+ yield
109
+ ensure
110
+ Webpacker.logger = old_logger
111
+ end
112
+
113
+
114
+ namespace :my_engine do
115
+ namespace :webpacker do
116
+ desc "Install deps with yarn"
117
+ task :yarn_install do
118
+ Dir.chdir(File.join(__dir__, "../..")) do
119
+ system "yarn install --no-progress --production"
120
+ end
121
+ end
122
+
123
+ desc "Compile JavaScript packs using webpack for production with digests"
124
+ task compile: [:yarn_install, :environment] do
125
+ Webpacker.with_node_env("production") do
126
+ ensure_log_goes_to_stdout do
127
+ if MyEngine.webpacker.commands.compile
128
+ # Successful compilation!
129
+ else
130
+ # Failed compilation
131
+ exit!
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ def yarn_install_available?
140
+ rails_major = Rails::VERSION::MAJOR
141
+ rails_minor = Rails::VERSION::MINOR
142
+
143
+ rails_major > 5 || (rails_major == 5 && rails_minor >= 1)
144
+ end
145
+
146
+ def enhance_assets_precompile
147
+ # yarn:install was added in Rails 5.1
148
+ deps = yarn_install_available? ? [] : ["my_engine:webpacker:yarn_install"]
149
+ Rake::Task["assets:precompile"].enhance(deps) do
150
+ Rake::Task["my_engine:webpacker:compile"].invoke
151
+ end
152
+ end
153
+
154
+ # Compile packs after we've compiled all other assets during precompilation
155
+ skip_webpacker_precompile = %w(no false n f).include?(ENV["WEBPACKER_PRECOMPILE"])
156
+
157
+ unless skip_webpacker_precompile
158
+ if Rake::Task.task_defined?("assets:precompile")
159
+ enhance_assets_precompile
160
+ else
161
+ Rake::Task.define_task("assets:precompile" => "my_engine:webpacker:compile")
162
+ end
163
+ end
164
+ ```
165
+
166
+ ## Step 7: serving compiled packs.
167
+
168
+ There are two approaches on serving compiled assets.
169
+
170
+ ### Put engine's assets to the root app's public/ folder
171
+
172
+ You can serve engine's assets using the main app's static files server which serves files from `public/` folder.
173
+
174
+ For that you must configure your engine's webpacker to put compiled assets to the app's `public/` folder:
175
+
176
+ ```yml
177
+ # my_engine/config/webpacker.yml
178
+ default: &default
179
+ # ...
180
+ # public_root_path could be used to override the path to `public/` folder
181
+ # (relative to the engine root)
182
+ public_root_path: ../public
183
+ # use a different sub-folder name
184
+ public_output_path: my-engine-packs
185
+ ```
186
+
187
+ ### Use a separate middleware
188
+
189
+ 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:
190
+
191
+ ```ruby
192
+ # application.rb
193
+
194
+ config.middleware.use(
195
+ Rack::Static,
196
+ urls: ["/my-engine-packs"], root: "my_engine/public"
197
+ )
198
+ ```
199
+ or if you prefer to keep your engine-related configuration within the engine itself
200
+
201
+ ```ruby
202
+ # my-engine-root/lib/my-engine/engine.rb
203
+ module MyEngine
204
+ class Engine < ::Rails:Engine
205
+ config.app_middleware.use(
206
+ Rack::Static,
207
+ urls: ["/my-engine-packs"], root: "my_engine/public"
208
+ )
209
+ end
210
+ end
211
+ ```
212
+
213
+ **NOTE:** in the example above we assume that your `public_output_path` is set to `my-engine-packs` in your engine's `webpacker.yml`.
@@ -0,0 +1,68 @@
1
+ # Environment variables
2
+
3
+
4
+ Environment variables are supported out of the box in Webpacker. For example if
5
+ you run the webpack dev server like so:
6
+ ```
7
+ FOO=hello BAR=world ./bin/webpack-dev-server
8
+ ```
9
+
10
+ You can then reference these variables in your JavaScript app code with
11
+ `process.env`:
12
+
13
+ ```js
14
+ console.log(process.env.FOO) // Compiles to console.log("hello")
15
+ ```
16
+
17
+ You may want to store configuration in environment variables via `.env` files,
18
+ similar to the [dotenv Ruby gem](https://github.com/bkeepers/dotenv).
19
+
20
+ In development, if you use [Foreman](http://ddollar.github.io/foreman) or [Invoker](http://invoker.codemancers.com)
21
+ to launch the webpack server, both of these tools have basic support for a
22
+ `.env` file (Invoker also supports `.env.local`), so no further configuration
23
+ is needed.
24
+
25
+ However, if you run the webpack server without Foreman/Invoker, or if you
26
+ want more control over what `.env` files to load, you can use the
27
+ [dotenv npm package](https://github.com/motdotla/dotenv). Here is what you could
28
+ do to support a "Ruby-like" dotenv:
29
+
30
+ ```
31
+ yarn add dotenv
32
+ ```
33
+
34
+ ```javascript
35
+ // config/webpack/environment.js
36
+
37
+ ...
38
+ const { environment } = require('@rails/webpacker')
39
+ const webpack = require('webpack')
40
+ const dotenv = require('dotenv')
41
+
42
+ const dotenvFiles = [
43
+ `.env.${process.env.NODE_ENV}.local`,
44
+ '.env.local',
45
+ `.env.${process.env.NODE_ENV}`,
46
+ '.env'
47
+ ]
48
+ dotenvFiles.forEach((dotenvFile) => {
49
+ dotenv.config({ path: dotenvFile, silent: true })
50
+ })
51
+
52
+ environment.plugins.insert(
53
+ "Environment",
54
+ new webpack.EnvironmentPlugin(process.env)
55
+ )
56
+
57
+ module.exports = environment
58
+ ```
59
+
60
+ **Warning:** using Foreman/Invoker and npm dotenv at the same time can result in
61
+ confusing behavior, in that Foreman/Invoker variables take precedence over
62
+ npm dotenv variables.
63
+
64
+ If you'd like to pass custom variables to the on demand compiler, use `Webpacker::Compiler.env` attribute.
65
+
66
+ ```rb
67
+ Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
68
+ ```