webpacker 6.0.0.beta.7 → 6.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/jest.yml +1 -1
  3. data/.github/workflows/js-lint.yml +1 -1
  4. data/.github/workflows/ruby.yml +6 -9
  5. data/.rubocop.yml +0 -105
  6. data/CHANGELOG.md +6 -22
  7. data/CONTRIBUTING.md +1 -1
  8. data/Gemfile.lock +90 -93
  9. data/README.md +110 -308
  10. data/docs/assets.md +135 -0
  11. data/docs/cloud9.md +310 -0
  12. data/docs/css.md +303 -0
  13. data/docs/deployment.md +29 -9
  14. data/docs/docker.md +68 -0
  15. data/docs/engines.md +213 -0
  16. data/docs/env.md +68 -0
  17. data/docs/es6.md +72 -0
  18. data/docs/folder-structure.md +66 -0
  19. data/docs/integrations.md +220 -0
  20. data/docs/misc.md +23 -0
  21. data/docs/props.md +187 -0
  22. data/docs/react.md +183 -0
  23. data/docs/target.md +22 -0
  24. data/docs/testing.md +147 -0
  25. data/docs/troubleshooting.md +3 -5
  26. data/docs/typescript.md +190 -0
  27. data/docs/v4-upgrade.md +142 -0
  28. data/docs/webpack-dev-server.md +94 -0
  29. data/docs/webpack.md +315 -0
  30. data/docs/yarn.md +23 -0
  31. data/lib/install/config/webpacker.yml +3 -5
  32. data/lib/install/examples/vue3/app.vue +27 -0
  33. data/lib/install/examples/vue3/hello_vue.js +15 -0
  34. data/lib/install/javascript/packs/application.css +9 -0
  35. data/lib/install/{packs/entrypoints → javascript/packs}/application.js +2 -4
  36. data/lib/install/template.rb +9 -16
  37. data/lib/tasks/webpacker/binstubs.rake +2 -2
  38. data/lib/tasks/webpacker/check_node.rake +0 -1
  39. data/lib/tasks/webpacker/check_yarn.rake +0 -1
  40. data/lib/tasks/webpacker/install.rake +2 -2
  41. data/lib/webpacker/commands.rb +1 -2
  42. data/lib/webpacker/compiler.rb +3 -9
  43. data/lib/webpacker/configuration.rb +4 -4
  44. data/lib/webpacker/dev_server_runner.rb +0 -2
  45. data/lib/webpacker/helper.rb +43 -13
  46. data/lib/webpacker/manifest.rb +1 -1
  47. data/lib/webpacker/version.rb +1 -1
  48. data/lib/webpacker/webpack_runner.rb +0 -1
  49. data/package.json +1 -1
  50. data/package/__tests__/development.js +1 -2
  51. data/package/babel/preset-react.js +62 -0
  52. data/package/babel/preset.js +13 -24
  53. data/package/environments/__tests__/base.js +5 -5
  54. data/package/environments/base.js +20 -15
  55. data/package/environments/development.js +0 -1
  56. data/package/environments/production.js +30 -28
  57. data/package/index.js +2 -7
  58. data/package/rules/babel.js +1 -1
  59. data/package/rules/coffee.js +5 -5
  60. data/package/rules/erb.js +3 -5
  61. data/package/rules/file.js +3 -5
  62. data/package/rules/index.js +17 -9
  63. data/package/rules/less.js +10 -14
  64. data/package/rules/sass.js +9 -13
  65. data/package/rules/svg.js +23 -0
  66. data/package/utils/get_style_rule.js +31 -27
  67. data/package/utils/helpers.js +0 -25
  68. data/test/configuration_test.rb +2 -2
  69. data/test/dev_server_runner_test.rb +2 -10
  70. data/test/helper_test.rb +39 -33
  71. data/test/manifest_test.rb +0 -8
  72. data/test/mounted_app/test/dummy/config/webpacker.yml +3 -3
  73. data/test/test_app/app/{packs/entrypoints → javascript/packs}/application.js +1 -1
  74. data/test/test_app/app/{packs/entrypoints → javascript/packs}/multi_entry.css +0 -0
  75. data/test/test_app/app/{packs/entrypoints → javascript/packs}/multi_entry.js +0 -0
  76. data/test/test_app/config/webpacker.yml +3 -3
  77. data/test/test_app/public/packs/manifest.json +0 -7
  78. metadata +36 -18
  79. data/config/README.md +0 -3
  80. data/config/webpacker.yml +0 -1
  81. data/docs/v6_upgrade.md +0 -86
  82. data/package/__tests__/index.js +0 -9
  83. data/package/rules/raw.js +0 -5
  84. data/package/rules/stylus.js +0 -26
data/docs/deployment.md CHANGED
@@ -1,27 +1,28 @@
1
1
  # Deployment
2
2
 
3
+
3
4
  Webpacker hooks up a new `webpacker:compile` task to `assets:precompile`, which gets run whenever you run `assets:precompile`.
4
- 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.
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.
5
6
 
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.
7
8
 
8
9
  By default the output will look like this in different environments:
9
10
 
10
11
  ```html
11
- <!-- In development mode with webpack-dev-server -->
12
- <script src="http://localhost:8080/calendar-0bd141f6d9360cf4a7f5.js"></script>
13
- <link rel="stylesheet" media="screen" href="http://localhost:8080/calendar-dc02976b5f94b507e3b6.css">
14
-
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">
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
18
  ```
19
19
 
20
+
20
21
  ## Heroku
21
22
 
22
23
  In order for your Webpacker app to run on Heroku, you'll need to do a bit of configuration before hand.
23
24
 
24
- ```bash
25
+ ```
25
26
  heroku create my-webpacker-heroku-app
26
27
  heroku addons:create heroku-postgresql:hobby-dev
27
28
  heroku buildpacks:add heroku/nodejs
@@ -36,6 +37,7 @@ We're essentially doing the following here:
36
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.
37
38
  * Pushing our code to Heroku and kicking off the deployment
38
39
 
40
+
39
41
  ## Nginx
40
42
 
41
43
  Webpacker doesn't serve anything in production. You’re expected to configure your web server to serve files in public/ directly.
@@ -126,3 +128,21 @@ namespace :deploy do
126
128
  end
127
129
  end
128
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
+
data/docs/docker.md ADDED
@@ -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
+ ```
data/docs/engines.md ADDED
@@ -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`.
data/docs/env.md ADDED
@@ -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
+ ```
data/docs/es6.md ADDED
@@ -0,0 +1,72 @@
1
+ # ES6
2
+
3
+ ## Babel
4
+
5
+ Webpacker ships with [babel](https://babeljs.io/) - a JavaScript compiler so
6
+ you can use next generation JavaScript, today. The Webpacker installer sets up a
7
+ standard `babel.config.js` file in your app root, which will work great in most cases
8
+ because of [@babel/preset-env](https://github.com/babel/babel/tree/master/packages/babel-preset-env).
9
+
10
+ Following ES6/7 features are supported out of the box:
11
+
12
+ * Async/await.
13
+ * Object Rest/Spread Properties.
14
+ * Exponentiation Operator.
15
+ * Dynamic import() - useful for route level code-splitting
16
+ * Class Fields and Static Properties.
17
+
18
+ We have also included [core-js](https://github.com/zloirock/core-js) to polyfill features in the
19
+ older browsers.
20
+
21
+ Don't forget to add these lines into your main entry point:
22
+
23
+ ```js
24
+ import "core-js/stable";
25
+ import "regenerator-runtime/runtime";
26
+ ```
27
+
28
+ ## Dynamic/Lazy Chunk Loading
29
+
30
+ For this section, you need Webpack and Webpacker 4. Then enable `SplitChunks` as it is explained in [docs/webpack](webpack.md).
31
+
32
+ [Dynamic code splitting](https://webpack.js.org/guides/code-splitting#dynamic-imports) enables you to conditionally request/run only the JS that you need. For example, if your site has a `searchBarComponent` on every page, you can reduce the page overhead by deferring the request for the `searchBarComponent` code until after the page has loaded, until the user has scrolled it into view, or until the user has clicked on an element.
33
+
34
+ ```js
35
+ function loadSearchBarComponent() {
36
+ return import(/* webpackChunkName: "searchBarComponent" */ './pathTo/searchBarComponent')
37
+ }
38
+ ```
39
+
40
+ The comment you see above (`/* webpackChunkName */`) is not arbitrary, it is one of webpacks [magic comments](https://webpack.js.org/api/module-methods/#magic-comments). They can be used to fine-tune `import()` with settings such as `defer` or `prefetch`.
41
+
42
+ **Warning**: You should not attempt to dynamically load anything from your `packs/` folder. Instead, try to make your `pack` scripts a hub from which you dynamically load `non-pack` scripts.
43
+
44
+ - [Docs for using magic comments](https://webpack.js.org/api/module-methods/#magic-comments)
45
+ - [Docs for configuring `splitChunks` in webpacker](/docs/webpack.md#add-splitchunks-webpack-v4).
46
+ - [Docs for using dynamic `import()`](https://webpack.js.org/guides/code-splitting#dynamic-imports).
47
+
48
+ ## Module import vs require()
49
+
50
+ While you are free to use `require()` and `module.exports`, we encourage you
51
+ to use `import` and `export` instead since it reads and looks much better.
52
+
53
+ ```js
54
+ import Button from 'react-bootstrap/lib/Button'
55
+
56
+ // or
57
+ import { Button } from 'react-bootstrap'
58
+
59
+ class Foo {
60
+ // code...
61
+ }
62
+
63
+ export default Foo
64
+ import Foo from './foo'
65
+ ```
66
+
67
+ You can also use named export and import
68
+
69
+ ```js
70
+ export const foo = () => console.log('hello world')
71
+ import { foo } from './foo'
72
+ ```