shakapacker 6.2.1 → 6.3.0.pre.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd1ab6b39f1ae6a30d35edb3ce88f505aa982751ce798cbc02a7ff1e6d1b1fd4
4
- data.tar.gz: 389b31b8cd3e24b9cbe39e7fef24257037ec3195229d2fae9d35146f82f6c594
3
+ metadata.gz: 862dd1243830eb271661d0a7be8ad35b4837ab8aaabfa2a39cc9a65e5c6d01f3
4
+ data.tar.gz: a9b58deb1b8038aecbac2df1ca3516d59c03dfd2cc5a6a71e06edf480ba3443c
5
5
  SHA512:
6
- metadata.gz: 44e0784025695f8d6686c9c4fecd551da50f4c47c48939abe0c93b55e6e6f9407b68fba15e88c7dfe2169e981248e31c93e240fa1be342f58ffa368a1a6dc4ac
7
- data.tar.gz: 8b51a5b4c2870bea948801afe3db35f24bf79bdfb543f098e63bbdc62dd3be1a23241dc8ebccefceb0a92d0c51e50bc0d75553e1eb9c93f0c362ae7a91ea3b47
6
+ metadata.gz: c03da71f446adc4f470acdca8de67487ff7934650abca9278a4e26c854329432d6a94b02368f5825cca0214f1fb878399711114b67c5f8e1dbb9d27620cf22b9
7
+ data.tar.gz: 900fdb88440208f4860c7255b5ca71ba316d6ba69223f720a67b4564663f633eb11e31403b41247c94e5755488804dd9f6745b9ddbfb6c82c5f928ec360abdd5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,6 @@
1
- * For versions prior to v6, see the [5.x stable branch of rails/webpacker](https://github.com/rails/webpacker/tree/5-x-stable).
2
- * Please see [v6 Upgrade Guide](./docs/v6_upgrade.md) to go from version prior to v6.
1
+ * For the changelog of versions prior to v6, see the [5.x stable branch of rails/webpacker](https://github.com/rails/webpacker/tree/5-x-stable).
2
+ * Please see the [v6 Upgrade Guide](./docs/v6_upgrade.md) to go from versions prior to v6.
3
+ * [ShakaCode](https://www.shakacode.com) offers support for upgrading from webpacker or using Shakapacker. If interested, contact [justin@shakacode.com](mailto:justin@shakacode.com).
3
4
 
4
5
  ## Versions
5
6
  ## [Unreleased]
@@ -7,6 +8,29 @@ Changes since last non-beta release.
7
8
 
8
9
  *Please add entries here for your pull requests that are not yet released.*
9
10
 
11
+ ## [v6.3.0-rc.1] - April 24, 2024
12
+
13
+ ### Changed
14
+ - Remove Loose mode from the default @babel-preset/env configuration. [PR 107](https://github.com/shakacode/shakapacker/pull/107) by [Jeremy Liberman](https://github.com/MrLeebo).
15
+
16
+ Loose mode compiles the bundle down to be compatible with ES5, but saves space by skipping over behaviors that are considered edge cases. Loose mode can affect how your code runs in a variety of ways, but in newer versions of Babel it's better to use [Compiler Assumptions](https://babeljs.io/docs/en/assumptions) to have finer-grained control over which edge cases you're choosing to ignore.
17
+
18
+ This change may increase the file size of your bundles, and may change some behavior in your app if your code touches upon one of the edge cases where Loose mode differs from native JavaScript. There are notes in the linked PR about how to turn Loose mode back on if you need to, but consider migrating to Compiler Assumptions when you can. If you have already customized your babel config, this change probably won't affect you.
19
+
20
+ ### Added
21
+ - Adds `webpacker_precompile` setting to `webpacker.yml` to allow controlling precompile behaviour, similar to existing `ENV["WEBPACKER_PRECOMPILE"]` variable. [PR 102](https://github.com/shakacode/shakapacker/pull/102) by [Judahmeek](https://github.com/Judahmeek).
22
+ - Adds `append_javascript_pack_tag` helper. Allows for easier usage and coordination of multiple javascript packs. [PR 94](https://github.com/shakacode/shakapacker/pull/94) by [tomdracz](https://github.com/tomdracz).
23
+
24
+ ### Improved
25
+ - Use last modified timestamps rather than file digest to determine compiler freshness. [PR 97](https://github.com/shakacode/shakapacker/pull/97) by [tomdracz](https://github.com/tomdracz).
26
+
27
+ Rather than calculating SHA digest of all the files in the paths watched by the compiler, we are now comparing the modified time of the `manifest.json` file versues the latest modified timestamp of files and directories in watched paths. Unlike calculating digest, which only looked at the files, the new calculation also considers directory timestamps, including the parent ones (i.e. `config.source_path` folder timestamp will be checked together will timestamps of all files and directories inside of it).
28
+
29
+ This change should result in improved compiler checks performance but might be breaking for certain setups and edge cases. If you encounter any issues, please report them at https://github.com/shakacode/shakapacker/issues.
30
+
31
+ - Bump dependency versions in package.json to address security vulnerabilities. [PR 109](https://github.com/shakacode/shakapacker/pull/109) by [tomdracz](https://github.com/tomdracz).
32
+ - Add `webpack-dev-server` as `peerDependency` to make its usage clear. [PR 109](https://github.com/shakacode/shakapacker/pull/109) by [tomdracz](https://github.com/tomdracz).
33
+
10
34
  ## [v6.2.1] - April 15, 2022
11
35
  ### Fixed
12
36
  - Put back config.public_manifest_path, removed in 6.2.0 in PR 78. [PR 104](https://github.com/shakacode/shakapacker/pull/104) by [justin808](https://github.com/justin808).
@@ -91,7 +115,9 @@ Changes since last non-beta release.
91
115
  ## v5.4.3 and prior changes from rails/webpacker
92
116
  See [CHANGELOG.md in rails/webpacker (up to v5.4.3)](https://github.com/rails/webpacker/blob/master/CHANGELOG.md)
93
117
 
94
- [Unreleased]: https://github.com/shakacode/shakapacker/compare/v6.2.0...master
118
+ [Unreleased]: https://github.com/shakacode/shakapacker/compare/v6.3.0-rc.1...master
119
+ [v6.3.0-rc.0]: https://github.com/shakacode/shakapacker/compare/v6.2.1...v6.3.0-rc.1
120
+ [v6.2.1]: https://github.com/shakacode/shakapacker/compare/v6.2.0...v6.2.1
95
121
  [v6.2.0]: https://github.com/shakacode/shakapacker/compare/v6.1.1...v6.2.0
96
122
  [v6.1.1]: https://github.com/shakacode/shakapacker/compare/v6.1.0...v6.1.1
97
123
  [v6.1.0]: https://github.com/shakacode/shakapacker/compare/v6.0.2...v6.1.0
data/CONTRIBUTING.md CHANGED
@@ -56,7 +56,7 @@ If you change the generator, check that install instructions work.
56
56
 
57
57
  1. Update the gemfile so that gem "webpacker" has a line like this, pointing to your install of webpacker
58
58
  ```ruby
59
- gem 'webpacker', path: "~/shakacode/forks/webpacker"
60
- ```
59
+ gem 'webpacker', path: "~/shakacode/forks/shakapacker"
60
+ ```
61
61
  2. `bundle`
62
62
  3. Run the generator confirm that you got the right changes.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shakapacker (6.2.0)
4
+ shakapacker (6.2.1)
5
5
  activesupport (>= 5.2)
6
6
  rack-proxy (>= 0.6.1)
7
7
  railties (>= 5.2)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Shakapacker
2
2
 
3
- _Official, actively maintained successor to [rails/webpacker](https://github.com/rails/webpacker). Internal naming for `shakapacker` will continue to use `webpacker` where possible for v6. ShakaCode stands behind long-term maintainence and development of this project for the Rails community._
3
+ _Official, actively maintained successor to [rails/webpacker](https://github.com/rails/webpacker). Internal naming for `shakapacker` will continue to use `webpacker` where possible for v6. ShakaCode stands behind the long-term maintainence and development of this project for the Rails community._
4
4
 
5
5
  * See [V6 Upgrade](./docs/v6_upgrade.md) for upgrading from v5 or prior v6 releases.
6
6
 
@@ -26,7 +26,7 @@ Discussion forum and Slack to discuss debugging and troubleshooting tips. Please
26
26
  2. [Slack discussion channel](https://reactrails.slack.com/join/shared_invite/enQtNjY3NTczMjczNzYxLTlmYjdiZmY3MTVlMzU2YWE0OWM0MzNiZDI0MzdkZGFiZTFkYTFkOGVjODBmOWEyYWQ3MzA2NGE1YWJjNmVlMGE)
27
27
  3. [Tweets with tag `#shakapacker`](https://twitter.com/hashtag/shakapacker?src=hashtag_click)
28
28
 
29
- [ShakaCode](https://www.shakacode.com) offers suppport for upgrading from webpacker or using Shakapacker. If interested, contact [justin@shakacode.com](mailto:justin@shakacode.com). ShakaCode is [hiring passionate engineers](https://jobs.lever.co/shakacode/3bdbfdb3-4495-4611-a279-01dddb351abe) that love open source.
29
+ [ShakaCode](https://www.shakacode.com) offers support for upgrading from webpacker or using Shakapacker. If interested, contact [justin@shakacode.com](mailto:justin@shakacode.com). ShakaCode is [hiring passionate engineers](https://jobs.lever.co/shakacode/3bdbfdb3-4495-4611-a279-01dddb351abe) that love open source.
30
30
 
31
31
  ---
32
32
 
@@ -216,7 +216,18 @@ However, you may use multiple calls to stylesheet_pack_tag if, say, you require
216
216
  <%= stylesheet_pack_tag 'print', media: 'print' %>
217
217
  ```
218
218
 
219
- If you need to setup the pack name args in partials, [see this discussion](https://github.com/shakacode/shakapacker/issues/39).
219
+ You can also use `append_javascript_pack_tag` helper to bundle additional tags together when calling `javascript_pack_tag`:
220
+
221
+ ```erb
222
+ <% append_javascript_pack_tag 'calendar', 'map' %>
223
+ <%= javascript_pack_tag 'application' %>
224
+ ```
225
+
226
+ In the example above, `calendar` and `map` tags will be bundled together with `application` and deduplicated once `javascript_pack_tag` is used.
227
+
228
+ **Important:** `append_javascript_pack_tag` can be used anywhere in your application as long as it is executed BEFORE the `javascript_pack_tag`. If you attempt to call `append_javascript_pack_tag` helper after `javascript_pack_tag`, an error will be raised. You should aim to have only single `javascript_pack_tag` invocation in your page load.
229
+
230
+ For alternative options of setting the additional packs, [see this discussion](https://github.com/shakacode/shakapacker/issues/39).
220
231
 
221
232
  If you want to link a static asset for `<img />` tag, you can use the `asset_pack_path` helper:
222
233
  ```erb
@@ -247,7 +258,7 @@ If you want to use images in your stylesheets:
247
258
  }
248
259
  ```
249
260
  ### Defer for `javascript_pack_tag`
250
- Note, the default of "defer" for the `javascript_pack_tag`. You can override that to `false`. If you expose jquery globally with `expose-loader,` by using `import $ from "expose-loader?exposes=$,jQuery!jquery"` in your `app/packs/entrypoints/application.js`, pass the option `defer: false` to your `javascript_pack_tag`.
261
+ Note, the default of "defer" for the `javascript_pack_tag`. You can override that to `false`. If you expose jquery globally with `expose-loader,` by using `import $ from "expose-loader?exposes=$,jQuery!jquery"` in your `app/javascript/application.js`, pass the option `defer: false` to your `javascript_pack_tag`.
251
262
 
252
263
  ### Server-Side Rendering (SSR)
253
264
 
@@ -261,6 +272,8 @@ Webpacker ships with two binstubs: `./bin/webpacker` and `./bin/webpacker-dev-se
261
272
 
262
273
  In development, Webpacker compiles on demand rather than upfront by default. This happens when you refer to any of the pack assets using the Webpacker helper methods. This means that you don't have to run any separate processes. Compilation errors are logged to the standard Rails log. However, this auto-compilation happens when a web request is made that requires an updated webpack build, not when files change. Thus, that can be painfully slow for front-end development in this default way. Instead, you should either run the `bin/webpacker --watch` or run `./bin/webpacker-dev-server`
263
274
 
275
+ **Note:** If you are not using webpack dev server, your packs will be served by Rails public file server. If you've enabled caching (Rails application `config.action_controller.perform_caching` setting), your changes will likely not be picked up due to `Cache-Control` header being set and assets being cached in browser memory. For more details see the [issue #88](https://github.com/shakacode/shakapacker/issues/88).
276
+
264
277
  If you want to use live code reloading, or you have enough JavaScript that on-demand compilation is too slow, you'll need to run `./bin/webpacker-dev-server` or `ruby ./bin/webpacker-dev-server`. Windows users will need to run these commands in a terminal separate from `bundle exec rails s`. This process will watch for changes in the relevant files, defined by `webpacker.yml` configuration settings for `source_path`, `source_entry_path`, and `additional_paths`, and it will then automatically reload the browser to match. This feature is also known as [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/).
265
278
 
266
279
  ```bash
@@ -288,13 +301,13 @@ Once you start this webpack development server, Webpacker will automatically sta
288
301
  You can use environment variables as options supported by [webpack-dev-server](https://webpack.js.org/configuration/dev-server/) in the form `WEBPACKER_DEV_SERVER_<OPTION>`. Please note that these environmental variables will always take precedence over the ones already set in the configuration file, and that the _same_ environmental variables must be available to the `rails server` process.
289
302
 
290
303
  ```bash
291
- WEBPACKER_DEV_SERVER_HOST=example.com WEBPACKER_DEV_SERVER_INLINE=true WEBPACKER_DEV_SERVER_HOT=false ./bin/webpacker-dev-server
304
+ WEBPACKER_DEV_SERVER_PORT=4305 WEBPACKER_DEV_SERVER_HOST=example.com WEBPACKER_DEV_SERVER_INLINE=true WEBPACKER_DEV_SERVER_HOT=false ./bin/webpacker-dev-server
292
305
  ```
293
306
 
294
- By default, the webpack dev server listens on `localhost` in development for security purposes. However, if you want your app to be available over local LAN IP or a VM instance like vagrant, you can set the `host` when running `./bin/webpacker-dev-server` binstub:
307
+ By default, the webpack dev server listens on `localhost:3035` in development for security purposes. However, if you want your app to be available on port 4035 over local LAN IP or a VM instance like vagrant, you can set the `port` and `host` when running `./bin/webpacker-dev-server` binstub:
295
308
 
296
309
  ```bash
297
- WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpacker-dev-server
310
+ WEBPACKER_DEV_SERVER_PORT=4305 WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpacker-dev-server
298
311
  ```
299
312
 
300
313
  **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:
@@ -473,7 +486,7 @@ Add tsconfig.json
473
486
  "moduleResolution": "node",
474
487
  "baseUrl": ".",
475
488
  "paths": {
476
- "*": ["node_modules/*", "app/packs/*"]
489
+ "*": ["node_modules/*", "app/javascript/*"]
477
490
  },
478
491
  "sourceMap": true,
479
492
  "target": "es5",
@@ -662,13 +675,13 @@ Also, consult the [CHANGELOG](./CHANGELOG.md) for additional upgrade links.
662
675
 
663
676
  By default, Webpacker ships with simple conventions for where the JavaScript app files and compiled webpack bundles will go in your Rails app. All these options are configurable from `config/webpacker.yml` file.
664
677
 
665
- The configuration for what webpack is supposed to compile by default rests on the convention that every file in `app/packs/entrypoints/*`**(default)** or whatever path you set for `source_entry_path` in the `webpacker.yml` configuration is turned into their own output files (or entry points, as webpack calls it). Therefore you don't want to put anything inside `packs` directory that you do not want to be an entry file. As a rule of thumb, put all files you want to link in your views inside "packs" directory and keep everything else under `app/packs`.
678
+ The configuration for what webpack is supposed to compile by default rests on the convention that every file in `app/javascript/`**(default)** or whatever path you set for `source_entry_path` in the `webpacker.yml` configuration is turned into their own output files (or entry points, as webpack calls it). Therefore you don't want to put any file inside `app/javascript` directory that you do not want to be an entry file. As a rule of thumb, put all files you want to link in your views inside "app/javascript/" directory and keep everything else under subdirectories like `app/javascript/controllers`.
666
679
 
667
- Suppose you want to change the source directory from `app/packs` to `frontend` and output to `assets/packs`. This is how you would do it:
680
+ Suppose you want to change the source directory from `app/javascript` to `frontend` and output to `assets/packs`. This is how you would do it:
668
681
 
669
682
  ```yml
670
683
  # config/webpacker.yml
671
- source_path: frontend # packs are in frontend/packs
684
+ source_path: frontend # packs are the files in frontend/
672
685
  public_output_path: assets/packs # outputs to => public/assets/packs
673
686
  ```
674
687
 
@@ -705,13 +718,15 @@ import 'images/rails.png'
705
718
 
706
719
  **Note:** Please be careful when adding paths here otherwise it will make the compilation slow, consider adding specific paths instead of whole parent directory if you just need to reference one or two modules
707
720
 
708
- **Also note:** While importing assets living outside your `source_path` defined in webpacker.yml (like, for instance, assets under `app/assets`) from within your packs using _relative_ paths like `import '../../assets/javascripts/file.js'` will work in development, Webpacker won't recompile the bundle in production unless a file that lives in one of it's watched paths has changed (check out `Webpacker::Compiler#watched_files_digest`). That's why you'd need to add `app/assets` to the additional_paths as stated above and use `import 'javascripts/file.js'` instead.
721
+ **Also note:** While importing assets living outside your `source_path` defined in webpacker.yml (like, for instance, assets under `app/assets`) from within your packs using _relative_ paths like `import '../../assets/javascripts/file.js'` will work in development, Webpacker won't recompile the bundle in production unless a file that lives in one of it's watched paths has changed (check out `Webpacker::Compiler#latest_modified_timestamp`). That's why you'd need to add `app/assets` to the additional_paths as stated above and use `import 'javascripts/file.js'` instead.
709
722
 
710
723
 
711
724
  ## Deployment
712
725
 
713
726
  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).
714
727
 
728
+ This behavior is optional & can be disabled by either setting an `WEBPACKER_PRECOMPILE` environment variable to `false`, `no`, `n`, or `f`, or by setting a `webpacker_precompile` key in your `webpacker.yml` to `false`. ([source code](./lib/webpacker/configuration.rb#L30))
729
+
715
730
  When compiling assets for production on a remote server, such as a continuous integration environment, it's recommended to use `yarn install --frozen-lockfile` to install NPM packages on the remote host to ensure that the installed packages match the `yarn.lock` file.
716
731
 
717
732
  If you are using a CDN setup, webpacker will use the configured [asset host](https://guides.rubyonrails.org/configuring.html#rails-general-configuration) value to prefix URLs for images or font icons which are included inside JS code or CSS. It is possible to override this value during asset compilation by setting the `WEBPACKER_ASSET_HOST` environment variable.
data/docs/v6_upgrade.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  There are several substantial changes in Shakapacker v6 that you need to manually account for when coming from Webpacker 5. This guide will help you through it.
4
4
 
5
- [ShakaCode](https://www.shakacode.com) offers suppport for upgrading from webpacker or using Shakapacker. If interested, contact [justin@shakacode.com](mailto:justin@shakacode.com).
5
+ [ShakaCode](https://www.shakacode.com) offers support for upgrading from webpacker or using Shakapacker. If interested, contact [justin@shakacode.com](mailto:justin@shakacode.com).
6
6
 
7
7
  ## Webpacker/Shakapacker has become a slimmer wrapper around Webpack
8
8
 
@@ -7,6 +7,8 @@ default: &default
7
7
  public_output_path: packs
8
8
  cache_path: tmp/webpacker
9
9
  webpack_compile_output: true
10
+ # See https://github.com/shakacode/shakapacker#deployment
11
+ webpacker_precompile: true
10
12
 
11
13
  # Location for manifest.json, defaults to {public_output_path}/manifest.json if unset
12
14
  # manifest_path: public/packs/manifest.json
@@ -11,9 +11,7 @@ namespace :webpacker do
11
11
  end
12
12
  end
13
13
 
14
- skip_webpacker_clean = %w(no false n f).include?(ENV["WEBPACKER_PRECOMPILE"])
15
-
16
- unless skip_webpacker_clean
14
+ if Webpacker.config.webpacker_precompile?
17
15
  # Run clean if the assets:clean is run
18
16
  if Rake::Task.task_defined?("assets:clean")
19
17
  Rake::Task["assets:clean"].enhance do
@@ -8,9 +8,7 @@ namespace :webpacker do
8
8
  end
9
9
  end
10
10
 
11
- skip_webpacker_clobber = %w(no false n f).include?(ENV["WEBPACKER_PRECOMPILE"])
12
-
13
- unless skip_webpacker_clobber
11
+ if Webpacker.config.webpacker_precompile?
14
12
  # Run clobber if the assets:clobber is run
15
13
  if Rake::Task.task_defined?("assets:clobber")
16
14
  Rake::Task["assets:clobber"].enhance do
@@ -33,10 +33,7 @@ namespace :webpacker do
33
33
  end
34
34
  end
35
35
 
36
- # Compile packs after we've compiled all other assets during precompilation
37
- skip_webpacker_precompile = %w(no false n f).include?(ENV["WEBPACKER_PRECOMPILE"])
38
-
39
- unless skip_webpacker_precompile
36
+ if Webpacker.config.webpacker_precompile?
40
37
  if Rake::Task.task_defined?("assets:precompile")
41
38
  enhance_assets_precompile
42
39
  else
@@ -1,5 +1,4 @@
1
1
  require "open3"
2
- require "digest/sha1"
3
2
 
4
3
  class Webpacker::Compiler
5
4
  # Additional paths that test compiler needs to watch
@@ -20,25 +19,19 @@ class Webpacker::Compiler
20
19
 
21
20
  def compile
22
21
  if stale?
23
- run_webpack.tap do |success|
24
- # We used to only record the digest on success
25
- # However, the output file is still written on error, meaning that the digest should still be updated.
26
- # If it's not, you can end up in a situation where a recompile doesn't take place when it should.
27
- # See https://github.com/rails/webpacker/issues/2113
28
- record_compilation_digest
29
- end
22
+ run_webpack
30
23
  else
31
24
  logger.debug "Everything's up-to-date. Nothing to do"
32
25
  true
33
26
  end
34
27
  end
35
28
 
36
- # Returns true if all the compiled packs are up to date with the underlying asset files.
29
+ # Returns true if manifest file mtime is newer than the timestamp of the last modified watched file
37
30
  def fresh?
38
- last_compilation_digest&.== watched_files_digest
31
+ manifest_mtime > latest_modified_timestamp
39
32
  end
40
33
 
41
- # Returns true if the compiled packs are out of date with the underlying asset files.
34
+ # Returns true if manifest file mtime is older than the timestamp of the last modified watched file
42
35
  def stale?
43
36
  !fresh?
44
37
  end
@@ -46,12 +39,11 @@ class Webpacker::Compiler
46
39
  private
47
40
  attr_reader :webpacker
48
41
 
49
- def last_compilation_digest
50
- compilation_digest_path.read if compilation_digest_path.exist? && config.manifest_path.exist?
51
- rescue Errno::ENOENT, Errno::ENOTDIR
42
+ def manifest_mtime
43
+ config.manifest_path.exist? ? File.mtime(config.manifest_path).to_i : 0
52
44
  end
53
45
 
54
- def watched_files_digest
46
+ def latest_modified_timestamp
55
47
  if Rails.env.development?
56
48
  warn <<~MSG.strip
57
49
  Webpacker::Compiler - Slow setup for development
@@ -67,14 +59,8 @@ class Webpacker::Compiler
67
59
  expanded_paths = [*default_watched_paths, *watched_paths].map do |path|
68
60
  root_path.join(path)
69
61
  end
70
- files = Dir[*expanded_paths].reject { |f| File.directory?(f) }
71
- file_ids = files.sort.map { |f| "#{File.basename(f)}/#{Digest::SHA1.file(f).hexdigest}" }
72
- Digest::SHA1.hexdigest(file_ids.join("/"))
73
- end
74
-
75
- def record_compilation_digest
76
- config.cache_path.mkpath
77
- compilation_digest_path.write(watched_files_digest)
62
+ latest_modified = Dir[*expanded_paths].max_by { |f| File.mtime(f) }
63
+ File.mtime(latest_modified).to_i
78
64
  end
79
65
 
80
66
  def optionalRubyRunner
@@ -109,17 +95,13 @@ class Webpacker::Compiler
109
95
 
110
96
  def default_watched_paths
111
97
  [
112
- *config.additional_paths.map { |path| "#{path}/**/*" },
113
- "#{config.source_path}/**/*",
98
+ *config.additional_paths.map { |path| "#{path}{,/**/*}" },
99
+ "#{config.source_path}{,/**/*}",
114
100
  "yarn.lock", "package.json",
115
- "config/webpack/**/*"
101
+ "config/webpack{,/**/*}"
116
102
  ].freeze
117
103
  end
118
104
 
119
- def compilation_digest_path
120
- config.cache_path.join("last-compilation-digest-#{webpacker.env}")
121
- end
122
-
123
105
  def webpack_env
124
106
  return env unless defined?(ActionController::Base)
125
107
 
@@ -27,6 +27,12 @@ class Webpacker::Configuration
27
27
  fetch(:ensure_consistent_versioning)
28
28
  end
29
29
 
30
+ def webpacker_precompile?
31
+ # ENV of false takes precedence
32
+ return false if %w(no false n f).include?(ENV["WEBPACKER_PRECOMPILE"])
33
+ return %w(yes true t).include?(ENV["WEBPACKER_PRECOMPILE"]) || fetch(:webpacker_precompile)
34
+ end
35
+
30
36
  def source_path
31
37
  root_path.join(fetch(:source_path))
32
38
  end
@@ -101,9 +101,17 @@ module Webpacker::Helper
101
101
  "Please refer to https://github.com/shakacode/shakapacker/blob/master/README.md#usage for the usage guide"
102
102
  end
103
103
 
104
+ append_javascript_pack_tag(*names, defer: defer)
105
+ non_deferred = sources_from_manifest_entrypoints(javascript_pack_tag_queue[:non_deferred], type: :javascript)
106
+ deferred = sources_from_manifest_entrypoints(javascript_pack_tag_queue[:deferred], type: :javascript) - non_deferred
107
+
104
108
  @javascript_pack_tag_loaded = true
105
109
 
106
- javascript_include_tag(*sources_from_manifest_entrypoints(names, type: :javascript), **options.tap { |o| o[:defer] = defer })
110
+ capture do
111
+ concat javascript_include_tag(*deferred, **options.tap { |o| o[:defer] = true })
112
+ concat "\n" if non_deferred.any? && deferred.any?
113
+ concat javascript_include_tag(*non_deferred, **options.tap { |o| o[:defer] = false })
114
+ end
107
115
  end
108
116
 
109
117
  # Creates a link tag, for preloading, that references a given Webpacker asset.
@@ -153,8 +161,25 @@ module Webpacker::Helper
153
161
  stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
154
162
  end
155
163
 
164
+ def append_javascript_pack_tag(*names, defer: true)
165
+ if @javascript_pack_tag_loaded
166
+ raise "You can only call append_javascript_pack_tag before javascript_pack_tag helper. " \
167
+ "Please refer to https://github.com/shakacode/shakapacker/blob/master/README.md#usage for the usage guide"
168
+ end
169
+
170
+ hash_key = defer ? :deferred : :non_deferred
171
+ javascript_pack_tag_queue[hash_key] |= names
172
+ end
173
+
156
174
  private
157
175
 
176
+ def javascript_pack_tag_queue
177
+ @javascript_pack_tag_queue ||= {
178
+ deferred: [],
179
+ non_deferred: []
180
+ }
181
+ end
182
+
158
183
  def sources_from_manifest_entrypoints(names, type:)
159
184
  names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks!(name.to_s, type: type) }.flatten.uniq
160
185
  end
@@ -104,12 +104,12 @@ class Webpacker::Manifest
104
104
 
105
105
  def missing_file_from_manifest_error(bundle_name)
106
106
  <<-MSG
107
- Webpacker can't find #{bundle_name} in #{config.manifest_path}. Possible causes:
107
+ Shakapacker can't find #{bundle_name} in #{config.manifest_path}. Possible causes:
108
108
  1. You forgot to install node packages (try `yarn install`) or are running an incompatible version of Node
109
109
  2. Your app has code with a non-standard extension (like a `.jsx` file) but the extension is not in the `extensions` config in `config/webpacker.yml`
110
110
  3. You have set compile: false (see `config/webpacker.yml`) for this environment
111
111
  (unless you are using the `bin/webpacker -w` or the `bin/webpacker-dev-server`, in which case maybe you aren't running the dev server in the background?)
112
- 4. webpack has not yet re-run to reflect updates.
112
+ 4. webpack has not yet FINISHED running to reflect updates.
113
113
  5. You have misconfigured Webpacker's `config/webpacker.yml` file.
114
114
  6. Your webpack configuration is not creating a manifest.
115
115
 
@@ -1,4 +1,4 @@
1
1
  module Webpacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "6.2.1".freeze
3
+ VERSION = "6.3.0-rc.1".freeze
4
4
  end
@@ -25,7 +25,6 @@ module.exports = function config(api) {
25
25
  corejs: '3.8',
26
26
  modules: 'auto',
27
27
  bugfixes: true,
28
- loose: true,
29
28
  exclude: ['transform-typeof-symbol']
30
29
  }
31
30
  ],
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shakapacker",
3
- "version": "6.2.1",
3
+ "version": "6.3.0-rc.1",
4
4
  "description": "Use webpack to manage app-like JavaScript modules in Rails",
5
5
  "main": "package/index.js",
6
6
  "files": [
@@ -12,16 +12,17 @@
12
12
  "yarn": ">=1 <4"
13
13
  },
14
14
  "peerDependencies": {
15
- "@babel/core": "^7.15.5",
16
- "@babel/plugin-transform-runtime": "^7.15.0",
17
- "@babel/preset-env": "^7.15.6",
18
- "@babel/runtime": "^7.15.4",
19
- "babel-loader": "^8.2.2",
15
+ "@babel/core": "^7.17.9",
16
+ "@babel/plugin-transform-runtime": "^7.17.9",
17
+ "@babel/preset-env": "^7.16.11",
18
+ "@babel/runtime": "^7.17.9",
19
+ "babel-loader": "^8.2.4",
20
20
  "compression-webpack-plugin": "^9.0.0",
21
- "terser-webpack-plugin": "^5.2.4",
22
- "webpack": "^5.53.0",
21
+ "terser-webpack-plugin": "^5.3.1",
22
+ "webpack": "^5.72.0",
23
23
  "webpack-assets-manifest": "^5.0.6",
24
- "webpack-cli": "^4.8.0",
24
+ "webpack-cli": "^4.9.2",
25
+ "webpack-dev-server": "^4.8.1",
25
26
  "webpack-merge": "^5.8.0"
26
27
  },
27
28
  "dependencies": {
@@ -30,7 +31,7 @@
30
31
  "path-complete-extname": "^1.0.0"
31
32
  },
32
33
  "devDependencies": {
33
- "babel-loader": "^8.2.2",
34
+ "babel-loader": "^8.2.4",
34
35
  "compression-webpack-plugin": "^9.0.0",
35
36
  "esbuild-loader": "^2.18.0",
36
37
  "eslint": "^7.32.0",
@@ -41,7 +42,7 @@
41
42
  "eslint-plugin-react": "^7.26.0",
42
43
  "jest": "^27.2.1",
43
44
  "swc-loader": "^0.1.15",
44
- "webpack": "^5.53.0",
45
+ "webpack": "^5.72.0",
45
46
  "webpack-assets-manifest": "^5.0.6",
46
47
  "webpack-merge": "^5.8.0"
47
48
  },
@@ -1,20 +1,6 @@
1
1
  require "test_helper"
2
2
 
3
3
  class CompilerTest < Minitest::Test
4
- def remove_compilation_digest_path
5
- Webpacker.compiler.send(:compilation_digest_path).tap do |path|
6
- path.delete if path.exist?
7
- end
8
- end
9
-
10
- def setup
11
- remove_compilation_digest_path
12
- end
13
-
14
- def teardown
15
- remove_compilation_digest_path
16
- end
17
-
18
4
  def test_custom_environment_variables
19
5
  assert_nil Webpacker.compiler.send(:webpack_env)["FOO"]
20
6
  Webpacker.compiler.env["FOO"] = "BAR"
@@ -23,37 +9,46 @@ class CompilerTest < Minitest::Test
23
9
  Webpacker.compiler.env = {}
24
10
  end
25
11
 
26
- def test_freshness
27
- assert Webpacker.compiler.stale?
28
- assert !Webpacker.compiler.fresh?
12
+ def setup
13
+ @manifest_timestamp = Time.parse("2021-01-01 12:34:56 UTC")
29
14
  end
30
15
 
31
- def test_compile
32
- assert !Webpacker.compiler.compile
16
+ def with_stubs(latest_timestamp:, manifest_exists: true)
17
+ Webpacker.compiler.stub :latest_modified_timestamp, latest_timestamp do
18
+ FileTest.stub :exist?, manifest_exists do
19
+ File.stub :mtime, @manifest_timestamp do
20
+ yield
21
+ end
22
+ end
23
+ end
33
24
  end
34
25
 
35
- def test_freshness_on_compile_success
36
- status = OpenStruct.new(success?: true)
26
+ def test_freshness_when_manifest_missing
27
+ latest_timestamp = @manifest_timestamp + 3600
37
28
 
38
- assert Webpacker.compiler.stale?
39
- Open3.stub :capture3, [:sterr, :stdout, status] do
40
- Webpacker.compiler.compile
41
- assert Webpacker.compiler.fresh?
29
+ with_stubs(latest_timestamp: latest_timestamp.to_i, manifest_exists: false) do
30
+ assert Webpacker.compiler.stale?
42
31
  end
43
32
  end
44
33
 
45
- def test_freshness_on_compile_fail
46
- status = OpenStruct.new(success?: false)
34
+ def test_freshness_when_manifest_older
35
+ latest_timestamp = @manifest_timestamp + 3600
47
36
 
48
- assert Webpacker.compiler.stale?
49
- Open3.stub :capture3, [:sterr, :stdout, status] do
50
- Webpacker.compiler.compile
37
+ with_stubs(latest_timestamp: latest_timestamp.to_i) do
38
+ assert Webpacker.compiler.stale?
39
+ end
40
+ end
41
+
42
+ def test_freshness_when_manifest_newer
43
+ latest_timestamp = @manifest_timestamp - 3600
44
+
45
+ with_stubs(latest_timestamp: latest_timestamp.to_i) do
51
46
  assert Webpacker.compiler.fresh?
52
47
  end
53
48
  end
54
49
 
55
- def test_compilation_digest_path
56
- assert_equal Webpacker.compiler.send(:compilation_digest_path).basename.to_s, "last-compilation-digest-#{Webpacker.env}"
50
+ def test_compile
51
+ assert !Webpacker.compiler.compile
57
52
  end
58
53
 
59
54
  def test_external_env_variables
@@ -28,14 +28,14 @@ class ConfigurationTest < Webpacker::Test
28
28
  public_output_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs").to_s
29
29
  assert_equal @config.public_output_path.to_s, public_output_path
30
30
 
31
- @config = Webpacker::Configuration.new(
31
+ @public_root_config = Webpacker::Configuration.new(
32
32
  root_path: @config.root_path,
33
33
  config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_public_root.yml", __dir__)),
34
34
  env: "production"
35
35
  )
36
36
 
37
37
  public_output_path = File.expand_path File.join(File.dirname(__FILE__), "public/packs").to_s
38
- assert_equal @config.public_output_path.to_s, public_output_path
38
+ assert_equal @public_root_config.public_output_path.to_s, public_output_path
39
39
  end
40
40
 
41
41
  def test_public_manifest_path
@@ -47,14 +47,14 @@ class ConfigurationTest < Webpacker::Test
47
47
  manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
48
48
  assert_equal @config.manifest_path.to_s, manifest_path
49
49
 
50
- @config = Webpacker::Configuration.new(
50
+ @manifest_config = Webpacker::Configuration.new(
51
51
  root_path: @config.root_path,
52
52
  config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_manifest_path.yml", __dir__)),
53
53
  env: "production"
54
54
  )
55
55
 
56
56
  manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs", "manifest.json").to_s
57
- assert_equal @config.manifest_path.to_s, manifest_path
57
+ assert_equal @manifest_config.manifest_path.to_s, manifest_path
58
58
  end
59
59
 
60
60
  def test_cache_path
@@ -100,5 +100,25 @@ class ConfigurationTest < Webpacker::Test
100
100
  with_rails_env("test") do
101
101
  refute Webpacker.config.ensure_consistent_versioning?
102
102
  end
103
+
104
+ def test_webpacker_precompile
105
+ assert @config.webpacker_precompile
106
+
107
+ ENV["WEBPACKER_PRECOMPILE"] = "false"
108
+
109
+ refute Webpacker.config.webpacker_precompile?
110
+
111
+ ENV["WEBPACKER_PRECOMPILE"] = "yes"
112
+
113
+ assert Webpacker.config.webpacker_precompile?
114
+
115
+ @no_precompile_config = Webpacker::Configuration.new(
116
+ root_path: @config.root_path,
117
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_no_precompile.yml", __dir__)),
118
+ env: "production"
119
+ )
120
+
121
+ refute @no_precompile_config.webpacker_precompile
122
+ end
103
123
  end
104
124
  end