webpacker 4.0.0.pre.3 → 4.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.node-version +1 -1
  3. data/.travis.yml +6 -4
  4. data/CHANGELOG.md +38 -0
  5. data/CONTRIBUTING.md +33 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +64 -59
  8. data/README.md +16 -4
  9. data/docs/assets.md +7 -4
  10. data/docs/css.md +51 -8
  11. data/docs/es6.md +1 -1
  12. data/docs/troubleshooting.md +1 -1
  13. data/docs/webpack.md +42 -1
  14. data/gemfiles/Gemfile-rails-edge +1 -1
  15. data/gemfiles/Gemfile-rails.4.2.x +1 -1
  16. data/gemfiles/Gemfile-rails.5.0.x +1 -1
  17. data/gemfiles/Gemfile-rails.5.1.x +1 -1
  18. data/gemfiles/Gemfile-rails.5.2.x +1 -1
  19. data/lib/install/coffee.rb +2 -2
  20. data/lib/install/config/babel.config.js +70 -0
  21. data/lib/install/config/postcss.config.js +12 -0
  22. data/lib/install/config/webpacker.yml +22 -0
  23. data/lib/install/elm.rb +2 -2
  24. data/lib/install/erb.rb +2 -2
  25. data/lib/install/examples/elm/Main.elm +5 -4
  26. data/lib/install/examples/elm/hello_elm.js +6 -2
  27. data/lib/install/examples/react/babel.config.js +83 -0
  28. data/lib/install/examples/vue/hello_vue.js +6 -4
  29. data/lib/install/loaders/typescript.js +8 -3
  30. data/lib/install/react.rb +6 -20
  31. data/lib/install/template.rb +5 -4
  32. data/lib/install/typescript.rb +3 -3
  33. data/lib/install/vue.rb +4 -4
  34. data/lib/tasks/webpacker/compile.rake +3 -5
  35. data/lib/tasks/webpacker/yarn_install.rake +1 -1
  36. data/lib/webpacker/compiler.rb +4 -13
  37. data/lib/webpacker/configuration.rb +8 -0
  38. data/lib/webpacker/dev_server.rb +0 -9
  39. data/lib/webpacker/dev_server_runner.rb +12 -5
  40. data/lib/webpacker/helper.rb +10 -14
  41. data/lib/webpacker/manifest.rb +58 -21
  42. data/lib/webpacker/railtie.rb +3 -2
  43. data/lib/webpacker/version.rb +1 -1
  44. data/lib/webpacker/webpack_runner.rb +13 -2
  45. data/package.json +31 -27
  46. data/package/__tests__/config.js +25 -3
  47. data/package/config.js +15 -7
  48. data/package/environments/__tests__/base.js +5 -3
  49. data/package/environments/base.js +41 -4
  50. data/package/environments/production.js +17 -6
  51. data/package/rules/babel.js +10 -4
  52. data/package/rules/file.js +2 -2
  53. data/package/rules/index.js +7 -2
  54. data/package/rules/node_modules.js +22 -0
  55. data/package/utils/__tests__/get_style_rule.js +20 -0
  56. data/package/utils/get_style_rule.js +6 -5
  57. data/package/utils/helpers.js +12 -1
  58. data/test/compiler_test.rb +2 -0
  59. data/test/dev_server_runner_test.rb +51 -0
  60. data/test/helper_test.rb +28 -5
  61. data/test/manifest_test.rb +10 -0
  62. data/test/rake_tasks_test.rb +34 -0
  63. data/test/test_app/config/application.rb +1 -0
  64. data/test/test_app/config/webpack/development.js +0 -0
  65. data/test/test_app/config/webpacker.yml +25 -0
  66. data/test/test_app/package.json +13 -0
  67. data/test/test_app/public/packs/manifest.json +10 -1
  68. data/test/test_app/yarn.lock +11 -0
  69. data/test/webpack_runner_test.rb +51 -0
  70. data/yarn.lock +2669 -1809
  71. metadata +20 -8
  72. data/lib/install/config/.babelrc +0 -41
  73. data/lib/install/config/.postcssrc.yml +0 -3
  74. data/lib/install/examples/react/.babelrc +0 -47
@@ -5,7 +5,7 @@
5
5
 
6
6
  Webpacker ships with [babel](https://babeljs.io/) - a JavaScript compiler so
7
7
  you can use next generation JavaScript, today. The Webpacker installer sets up a
8
- standard `.babelrc` file in your app root, which will work great in most cases
8
+ standard `babel.config.js` file in your app root, which will work great in most cases
9
9
  because of [@babel/preset-env](https://github.com/babel/babel/tree/master/packages/babel-preset-env).
10
10
 
11
11
  Following ES6/7 features are supported out of the box:
@@ -86,7 +86,7 @@ chmod +x $HOME/your_rails_app/node_modules/.bin/elm-make
86
86
  ```
87
87
 
88
88
  ## Rake assets:precompile fails. ExecJS::RuntimeError
89
- This error occurs because you are trying to uglify a pack that's already been minified by Webpacker. To avoid this conflict and prevent appearing of ExecJS::RuntimeError error, you will need to disable uglifier from Rails config:
89
+ This error occurs because you are trying to minify by terser a pack that's already been minified by Webpacker. To avoid this conflict and prevent appearing of ExecJS::RuntimeError error, you will need to disable uglifier from Rails config:
90
90
 
91
91
  ```ruby
92
92
  // production.rb
@@ -256,7 +256,48 @@ const { environment } = require('@rails/webpacker')
256
256
  environment.resolvedModules.append('vendor', 'vendor')
257
257
  ```
258
258
 
259
- ### Add common chunks
259
+ ### Add SplitChunks (Webpack V4)
260
+ Originally, chunks (and modules imported inside them) were connected by a parent-child relationship in the internal webpack graph. The CommonsChunkPlugin was used to avoid duplicated dependencies across them, but further optimizations were not possible
261
+
262
+ Since webpack v4, the CommonsChunkPlugin was removed in favor of optimization.splitChunks.
263
+
264
+ For the full configuration options of SplitChunks, see the [Webpack documentation](https://webpack.js.org/plugins/split-chunks-plugin/).
265
+
266
+ ```js
267
+ // config/webpack/environment.js
268
+ const WebpackAssetsManifest = require('webpack-assets-manifest');
269
+
270
+ const splitChunks = {
271
+ optimization: {
272
+ splitChunks: {
273
+ chunks: 'all'
274
+ },
275
+ },
276
+ };
277
+
278
+ environment.config.merge(splitChunks);
279
+
280
+ // Should override the existing manifest plugin
281
+ environment.plugins.insert(
282
+ 'Manifest',
283
+ new WebpackAssetsManifest({
284
+ entrypoints: true, // default in rails is false
285
+ writeToDisk: true, // rails defaults copied from webpacker
286
+ publicPath: true // rails defaults copied from webpacker
287
+ })
288
+ )
289
+ ```
290
+
291
+ To use the `javascript_pack_tag` or the `stylesheet_pack_tag` with `SplitChunks` or `RuntimeChunks` you can refer to the packs as usual.
292
+
293
+ ```erb
294
+ javascript_pack_tag "your-entrypoint-javascript-file"
295
+ stylesheet_pack_tag "your-entrypoint-stylesheet-file"
296
+ ```
297
+
298
+ For the old configuration with the CommonsChunkPlugin see below. **Note** that this functionality is deprecated in Webpack V4.
299
+
300
+ ### Add common chunks (deprecated in Webpack V4)
260
301
 
261
302
  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.
262
303
 
@@ -7,7 +7,7 @@ gem "webpacker", path: ".."
7
7
  gem "rails", github: "rails/rails"
8
8
  gem "arel", github: "rails/arel"
9
9
  gem "rake", ">= 11.1"
10
- gem "rubocop", ">= 0.49", require: false
10
+ gem "rubocop", git: "https://github.com/rubocop-hq/rubocop.git", require: false
11
11
  gem "rack-proxy", require: false
12
12
  gem "minitest", "~> 5.0"
13
13
  gem "byebug"
@@ -4,7 +4,7 @@ gem "webpacker", path: ".."
4
4
 
5
5
  gem "rails", "~> 4.2.0"
6
6
  gem "rake", ">= 11.1"
7
- gem "rubocop", ">= 0.49", require: false
7
+ gem "rubocop", git: "https://github.com/rubocop-hq/rubocop.git", require: false
8
8
  gem "rack-proxy", require: false
9
9
  gem "minitest", "~> 5.0"
10
10
  gem "byebug"
@@ -4,7 +4,7 @@ gem "webpacker", path: ".."
4
4
 
5
5
  gem "rails", "~> 5.0.0"
6
6
  gem "rake", ">= 11.1"
7
- gem "rubocop", ">= 0.49", require: false
7
+ gem "rubocop", git: "https://github.com/rubocop-hq/rubocop.git", require: false
8
8
  gem "rack-proxy", require: false
9
9
  gem "minitest", "~> 5.0"
10
10
  gem "byebug"
@@ -4,7 +4,7 @@ gem "webpacker", path: ".."
4
4
 
5
5
  gem "rails", "~> 5.1.0"
6
6
  gem "rake", ">= 11.1"
7
- gem "rubocop", ">= 0.49", require: false
7
+ gem "rubocop", git: "https://github.com/rubocop-hq/rubocop.git", require: false
8
8
  gem "rack-proxy", require: false
9
9
  gem "minitest", "~> 5.0"
10
10
  gem "byebug"
@@ -4,7 +4,7 @@ gem "webpacker", path: ".."
4
4
 
5
5
  gem "rails", "~> 5.2.0"
6
6
  gem "rake", ">= 11.1"
7
- gem "rubocop", ">= 0.49", require: false
7
+ gem "rubocop", git: "https://github.com/rubocop-hq/rubocop.git", require: false
8
8
  gem "rack-proxy", require: false
9
9
  gem "minitest", "~> 5.0"
10
10
  gem "byebug"
@@ -9,11 +9,11 @@ insert_into_file Rails.root.join("config/webpack/environment.js").to_s,
9
9
  after: "require('@rails/webpacker')\n"
10
10
 
11
11
  insert_into_file Rails.root.join("config/webpack/environment.js").to_s,
12
- "environment.loaders.append('coffee', coffee)\n",
12
+ "environment.loaders.prepend('coffee', coffee)\n",
13
13
  before: "module.exports"
14
14
 
15
15
  say "Updating webpack paths to include .coffee file extension"
16
- insert_into_file Webpacker.config.config_path, "- .coffee\n".indent(4), after: /extensions:\n/
16
+ insert_into_file Webpacker.config.config_path, "- .coffee\n".indent(4), after: /\s+extensions:\n/
17
17
 
18
18
  say "Copying the example entry file to #{Webpacker.config.source_entry_path}"
19
19
  copy_file "#{__dir__}/examples/coffee/hello_coffee.coffee",
@@ -0,0 +1,70 @@
1
+ module.exports = function(api) {
2
+ var validEnv = ['development', 'test', 'production']
3
+ var currentEnv = api.env()
4
+ var isDevelopmentEnv = api.env('development')
5
+ var isProductionEnv = api.env('production')
6
+ var isTestEnv = api.env('test')
7
+
8
+ if (!validEnv.includes(currentEnv)) {
9
+ throw new Error(
10
+ 'Please specify a valid `NODE_ENV` or ' +
11
+ '`BABEL_ENV` environment variables. Valid values are "development", ' +
12
+ '"test", and "production". Instead, received: ' +
13
+ JSON.stringify(currentEnv) +
14
+ '.'
15
+ )
16
+ }
17
+
18
+ return {
19
+ presets: [
20
+ isTestEnv && [
21
+ require('@babel/preset-env').default,
22
+ {
23
+ targets: {
24
+ node: 'current'
25
+ }
26
+ }
27
+ ],
28
+ (isProductionEnv || isDevelopmentEnv) && [
29
+ require('@babel/preset-env').default,
30
+ {
31
+ forceAllTransforms: true,
32
+ useBuiltIns: 'entry',
33
+ modules: false,
34
+ exclude: ['transform-typeof-symbol']
35
+ }
36
+ ]
37
+ ].filter(Boolean),
38
+ plugins: [
39
+ require('babel-plugin-macros'),
40
+ require('@babel/plugin-syntax-dynamic-import').default,
41
+ isTestEnv && require('babel-plugin-dynamic-import-node'),
42
+ require('@babel/plugin-transform-destructuring').default,
43
+ [
44
+ require('@babel/plugin-proposal-class-properties').default,
45
+ {
46
+ loose: true
47
+ }
48
+ ],
49
+ [
50
+ require('@babel/plugin-proposal-object-rest-spread').default,
51
+ {
52
+ useBuiltIns: true
53
+ }
54
+ ],
55
+ [
56
+ require('@babel/plugin-transform-runtime').default,
57
+ {
58
+ helpers: false,
59
+ regenerator: true
60
+ }
61
+ ],
62
+ [
63
+ require('@babel/plugin-transform-regenerator').default,
64
+ {
65
+ async: false
66
+ }
67
+ ]
68
+ ].filter(Boolean)
69
+ }
70
+ }
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ plugins: [
3
+ require('postcss-import'),
4
+ require('postcss-flexbugs-fixes'),
5
+ require('postcss-preset-env')({
6
+ autoprefixer: {
7
+ flexbox: 'no-2009'
8
+ },
9
+ stage: 3
10
+ })
11
+ ]
12
+ }
@@ -6,6 +6,7 @@ default: &default
6
6
  public_output_path: packs
7
7
  cache_path: tmp/cache/webpacker
8
8
  check_yarn_integrity: false
9
+ webpack_compile_output: false
9
10
 
10
11
  # Additional paths webpack should lookup modules
11
12
  # ['app/assets', 'engine/foo/app/assets']
@@ -14,7 +15,25 @@ default: &default
14
15
  # Reload manifest.json on all requests so we reload latest compiled packs
15
16
  cache_manifest: false
16
17
 
18
+ # Extract and emit a css file
19
+ extract_css: false
20
+
21
+ static_assets_extensions:
22
+ - .jpg
23
+ - .jpeg
24
+ - .png
25
+ - .gif
26
+ - .tiff
27
+ - .ico
28
+ - .svg
29
+ - .eot
30
+ - .otf
31
+ - .ttf
32
+ - .woff
33
+ - .woff2
34
+
17
35
  extensions:
36
+ - .mjs
18
37
  - .js
19
38
  - .sass
20
39
  - .scss
@@ -68,5 +87,8 @@ production:
68
87
  # Production depends on precompilation of packs prior to booting for performance.
69
88
  compile: false
70
89
 
90
+ # Extract and emit a css file
91
+ extract_css: true
92
+
71
93
  # Cache manifest.json for performance
72
94
  cache_manifest: true
@@ -9,7 +9,7 @@ insert_into_file Rails.root.join("config/webpack/environment.js").to_s,
9
9
  after: "require('@rails/webpacker')\n"
10
10
 
11
11
  insert_into_file Rails.root.join("config/webpack/environment.js").to_s,
12
- "environment.loaders.append('elm', elm)\n",
12
+ "environment.loaders.prepend('elm', elm)\n",
13
13
  before: "module.exports"
14
14
 
15
15
  say "Copying Elm example entry file to #{Webpacker.config.source_entry_path}"
@@ -27,7 +27,7 @@ run "yarn run elm init"
27
27
  run "yarn run elm make"
28
28
 
29
29
  say "Updating webpack paths to include .elm file extension"
30
- insert_into_file Webpacker.config.config_path, "- .elm\n".indent(4), after: /extensions:\n/
30
+ insert_into_file Webpacker.config.config_path, "- .elm\n".indent(4), after: /\s+extensions:\n/
31
31
 
32
32
  say "Updating Elm source location"
33
33
  gsub_file "elm.json", /\"\src\"\n/,
@@ -9,11 +9,11 @@ insert_into_file Rails.root.join("config/webpack/environment.js").to_s,
9
9
  after: "require('@rails/webpacker')\n"
10
10
 
11
11
  insert_into_file Rails.root.join("config/webpack/environment.js").to_s,
12
- "environment.loaders.append('erb', erb)\n",
12
+ "environment.loaders.prepend('erb', erb)\n",
13
13
  before: "module.exports"
14
14
 
15
15
  say "Updating webpack paths to include .erb file extension"
16
- insert_into_file Webpacker.config.config_path, "- .erb\n".indent(4), after: /extensions:\n/
16
+ insert_into_file Webpacker.config.config_path, "- .erb\n".indent(4), after: /\s+extensions:\n/
17
17
 
18
18
  say "Copying the example entry file to #{Webpacker.config.source_entry_path}"
19
19
  copy_file "#{__dir__}/examples/erb/hello_erb.js.erb",
@@ -1,5 +1,6 @@
1
1
  module Main exposing (..)
2
2
 
3
+ import Browser
3
4
  import Html exposing (Html, h1, text)
4
5
  import Html.Attributes exposing (style)
5
6
 
@@ -21,7 +22,7 @@ view : Model -> Html Message
21
22
  view model =
22
23
  -- The inline style is being used for example purposes in order to keep this example simple and
23
24
  -- avoid loading additional resources. Use a proper stylesheet when building your own app.
24
- h1 [style [("display", "flex"), ("justify-content", "center")]]
25
+ h1 [style "display" "flex", style "justify-content" "center"]
25
26
  [text "Hello Elm!"]
26
27
 
27
28
  -- MESSAGE
@@ -43,11 +44,11 @@ subscriptions model =
43
44
 
44
45
  -- MAIN
45
46
 
46
- main : Program Never Model Message
47
+ main : Program (Maybe {}) Model Message
47
48
  main =
48
- Html.program
49
+ Browser.element
49
50
  {
50
- init = init,
51
+ init = always init,
51
52
  view = view,
52
53
  update = update,
53
54
  subscriptions = subscriptions
@@ -2,11 +2,15 @@
2
2
  // head of your layout file, like app/views/layouts/application.html.erb.
3
3
  // It will render "Hello Elm!" within the page.
4
4
 
5
- import Elm from '../Main'
5
+ import {
6
+ Elm
7
+ } from '../Main'
6
8
 
7
9
  document.addEventListener('DOMContentLoaded', () => {
8
10
  const target = document.createElement('div')
9
11
 
10
12
  document.body.appendChild(target)
11
- Elm.Main.embed(target)
13
+ Elm.Main.init({
14
+ node: target
15
+ })
12
16
  })
@@ -0,0 +1,83 @@
1
+ module.exports = function(api) {
2
+ var validEnv = ['development', 'test', 'production']
3
+ var currentEnv = api.env()
4
+ var isDevelopmentEnv = api.env('development')
5
+ var isProductionEnv = api.env('production')
6
+ var isTestEnv = api.env('test')
7
+
8
+ if (!validEnv.includes(currentEnv)) {
9
+ throw new Error(
10
+ 'Please specify a valid `NODE_ENV` or ' +
11
+ '`BABEL_ENV` environment variables. Valid values are "development", ' +
12
+ '"test", and "production". Instead, received: ' +
13
+ JSON.stringify(env) +
14
+ '.'
15
+ )
16
+ }
17
+
18
+ return {
19
+ presets: [
20
+ isTestEnv && [
21
+ require('@babel/preset-env').default,
22
+ {
23
+ targets: {
24
+ node: 'current'
25
+ }
26
+ }
27
+ ],
28
+ (isProductionEnv || isDevelopmentEnv) && [
29
+ require('@babel/preset-env').default,
30
+ {
31
+ forceAllTransforms: true,
32
+ useBuiltIns: 'entry',
33
+ modules: false,
34
+ exclude: ['transform-typeof-symbol']
35
+ }
36
+ ],
37
+ [
38
+ require('@babel/preset-react').default,
39
+ {
40
+ development: isDevelopmentEnv || isTestEnv,
41
+ useBuiltIns: true
42
+ }
43
+ ]
44
+ ].filter(Boolean),
45
+ plugins: [
46
+ require('babel-plugin-macros'),
47
+ require('@babel/plugin-syntax-dynamic-import').default,
48
+ isTestEnv && require('babel-plugin-dynamic-import-node'),
49
+ require('@babel/plugin-transform-destructuring').default,
50
+ [
51
+ require('@babel/plugin-proposal-class-properties').default,
52
+ {
53
+ loose: true
54
+ }
55
+ ],
56
+ [
57
+ require('@babel/plugin-proposal-object-rest-spread').default,
58
+ {
59
+ useBuiltIns: true
60
+ }
61
+ ],
62
+ [
63
+ require('@babel/plugin-transform-runtime').default,
64
+ {
65
+ helpers: false,
66
+ regenerator: true
67
+ }
68
+ ],
69
+ [
70
+ require('@babel/plugin-transform-regenerator').default,
71
+ {
72
+ async: false
73
+ }
74
+ ],
75
+ isProductionEnv && [
76
+ require('babel-plugin-transform-react-remove-prop-types').default,
77
+ {
78
+ removeImport: true
79
+ }
80
+ ]
81
+ ].filter(Boolean)
82
+ }
83
+ }
@@ -48,9 +48,9 @@ document.addEventListener('DOMContentLoaded', () => {
48
48
  //
49
49
  //
50
50
  //
51
- // If the using turbolinks, install 'vue-turbolinks':
51
+ // If the project is using turbolinks, install 'vue-turbolinks':
52
52
  //
53
- // yarn add 'vue-turbolinks'
53
+ // yarn add vue-turbolinks
54
54
  //
55
55
  // Then uncomment the code block below:
56
56
  //
@@ -63,8 +63,10 @@ document.addEventListener('DOMContentLoaded', () => {
63
63
  // document.addEventListener('turbolinks:load', () => {
64
64
  // const app = new Vue({
65
65
  // el: '#hello',
66
- // data: {
67
- // message: "Can you say hello?"
66
+ // data: () => {
67
+ // return {
68
+ // message: "Can you say hello?"
69
+ // }
68
70
  // },
69
71
  // components: { App }
70
72
  // })