shakapacker 6.1.1 → 6.3.0.pre.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.node-version +1 -1
  3. data/CHANGELOG.md +48 -4
  4. data/CONTRIBUTING.md +2 -2
  5. data/Gemfile.lock +1 -1
  6. data/README.md +60 -26
  7. data/docs/customizing_babel_config.md +2 -0
  8. data/docs/deployment.md +2 -2
  9. data/docs/style_loader_vs_mini_css.md +48 -0
  10. data/docs/troubleshooting.md +18 -0
  11. data/docs/using_esbuild_loader.md +1 -1
  12. data/docs/using_swc_loader.md +2 -2
  13. data/docs/v6_upgrade.md +72 -74
  14. data/lib/install/config/webpacker.yml +16 -0
  15. data/lib/install/template.rb +2 -2
  16. data/lib/tasks/webpacker/clean.rake +1 -3
  17. data/lib/tasks/webpacker/clobber.rake +1 -3
  18. data/lib/tasks/webpacker/compile.rake +1 -4
  19. data/lib/webpacker/commands.rb +2 -2
  20. data/lib/webpacker/compiler.rb +12 -30
  21. data/lib/webpacker/configuration.rb +22 -4
  22. data/lib/webpacker/dev_server.rb +11 -2
  23. data/lib/webpacker/helper.rb +26 -8
  24. data/lib/webpacker/instance.rb +1 -1
  25. data/lib/webpacker/manifest.rb +4 -4
  26. data/lib/webpacker/railtie.rb +7 -0
  27. data/lib/webpacker/version.rb +1 -1
  28. data/lib/webpacker/version_checker.rb +152 -0
  29. data/package/__tests__/config.js +11 -0
  30. data/package/babel/preset.js +0 -1
  31. data/package/config.js +6 -0
  32. data/package/environments/base.js +1 -1
  33. data/package/inliningCss.js +1 -1
  34. data/package/rules/__tests__/file.js +35 -0
  35. data/package/rules/__tests__/index.js +11 -0
  36. data/package/rules/__tests__/raw.js +18 -0
  37. data/package/rules/file.js +2 -17
  38. data/package/rules/raw.js +2 -2
  39. data/package/swc/index.js +3 -3
  40. data/package.json +12 -11
  41. data/test/compiler_test.rb +27 -32
  42. data/test/configuration_test.rb +48 -2
  43. data/test/fixtures/beta_package.json +13 -0
  44. data/test/fixtures/git_url_package.json +13 -0
  45. data/test/fixtures/github_url_package.json +13 -0
  46. data/test/fixtures/normal_package.json +13 -0
  47. data/test/fixtures/relative_path_package.json +13 -0
  48. data/test/fixtures/semver_caret_package.json +13 -0
  49. data/test/fixtures/semver_tilde_package.json +13 -0
  50. data/test/fixtures/without_package.json +13 -0
  51. data/test/helper_test.rb +34 -12
  52. data/test/manifest_test.rb +3 -3
  53. data/test/test_app/config/webpacker.yml +4 -0
  54. data/test/test_app/config/webpacker_manifest_path.yml +80 -0
  55. data/test/test_app/config/webpacker_no_precompile.yml +7 -0
  56. data/test/version_checker_test.rb +271 -0
  57. data/test/webpacker_test.rb +15 -0
  58. data/yarn.lock +917 -884
  59. metadata +32 -5
data/docs/v6_upgrade.md CHANGED
@@ -2,6 +2,8 @@
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 support for upgrading from webpacker or using Shakapacker. If interested, contact [justin@shakacode.com](mailto:justin@shakacode.com).
6
+
5
7
  ## Webpacker/Shakapacker has become a slimmer wrapper around Webpack
6
8
 
7
9
  By default, Webpacker 6 is focused on compiling and bundling JavaScript. This pairs with the existing asset pipeline in Rails that's setup to transpile CSS and static images using [Sprockets](https://github.com/rails/sprockets). For most developers, that's the recommended combination. But if you'd like to use Webpacker for CSS and static assets as well, please see [integrations](https://github.com/shakacode/shakapacker#integrations) for more information.
@@ -10,16 +12,16 @@ Webpacker used to configure Webpack indirectly, which lead to a [complicated sec
10
12
 
11
13
  While you have to configure integration with frameworks yourself, [`webpack-merge`](https://github.com/survivejs/webpack-merge) helps with this. See this example for [Vue](https://github.com/shakacode/shakapacker#other-frameworks) and scroll to the bottom for [more examples](#examples-of-v5-to-v6).
12
14
 
13
- ## webpacker v6.0.0.rc.6 to shakapacker v6.0.0
15
+ ## webpacker v6.0.0.rc.6 to shakapacker v6.0.0
14
16
  See an example migration here: [PR 27](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/pull/27).
15
-
17
+
16
18
  ### Update Steps to v6.0.0 from v6.0.0.rc.6
17
19
  _If you're on webpacker v5, follow below steps to get to v6.0.0.rc.6 first._
18
20
 
19
21
  1. Change the gem name from `webpacker` to `shakapacker` and the NPM package from `@rails/webpacker` to `shakapacker`.
20
- 1. Install the peer dependencies. Run `yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader compression-webpack-plugin terser-webpack-plugin webpack webpack-assets-manifest webpack-cli webpack-merge webpack-sources webpack-dev-server`
22
+ 1. Install the peer dependencies. Run `yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader compression-webpack-plugin terser-webpack-plugin webpack webpack-assets-manifest webpack-cli webpack-merge webpack-sources webpack-dev-server`. You may have old versions of libraries. Run `yarn install` and check for warnings like `warning " > shakapacker@6.1.1" has incorrect peer dependency "compression-webpack-plugin@^9.0.0"` and `file-loader@1.1.11" has incorrect peer dependency "webpack@^2.0.0 || ^3.0.0 || ^4.0.0"`. In other words, warnings like these are **serious** and will cause considerable confusion if not respected.
21
23
  1. Update any scripts that called `bin/webpack` or `bin/webpack-dev-server` to `bin/webpacker` or `bin/webpacker-dev-server`
22
- 1. Update your webpack config for a single config file, `config/webpack/webpack.config.js`. If you want to use the prior style of having a separate file for each NODE_ENV, you can use this shim for `config/webpack/webpack.config.js`:
24
+ 1. Update your webpack config for a single config file, `config/webpack/webpack.config.js`. If you want to use the prior style of having a separate file for each NODE_ENV, you can use this shim for `config/webpack/webpack.config.js`. WARNING, previously, if you did not set `NODE_ENV`, `NODE_ENV` defaulted to `development`. Thus, you might expect `config/webpack/development.js` to run, but you'll instead be using the `config/webpack/RAILS_ENV.js`
23
25
  ```js
24
26
  const { env, webpackConfig } = require('shakapacker')
25
27
  const { existsSync } = require('fs')
@@ -30,11 +32,12 @@ _If you're on webpacker v5, follow below steps to get to v6.0.0.rc.6 first._
30
32
  if (existsSync(path)) {
31
33
  console.log(`Loading ENV specific webpack configuration file ${path}`)
32
34
  return require(path)
33
- } else {
34
- return webpackConfig
35
+ } else {
36
+ // Probably an error if the file for the NODE_ENV does not exist
37
+ throw new Error(`Got Error with NODE_ENV = ${env.nodeEnv}`);
35
38
  }
36
39
  }
37
-
40
+
38
41
  module.exports = envSpecificConfig()
39
42
  ```
40
43
  1. Update `babel.config.js` if you need JSX support. See [Customizing Babel Config](./customizing_babel_config.md)
@@ -43,26 +46,26 @@ _If you're on webpacker v5, follow below steps to get to v6.0.0.rc.6 first._
43
46
  1. Ensure you have a clean working git branch. You will be overwriting all your files and reverting the changes that you don't want.
44
47
 
45
48
  1. Consider changing from the v5 default for `source_entry_path` in `webpacker.yml`.
46
- ```yml
47
- source_path: app/javascript
48
- source_entry_path: packs
49
- ```
50
- consider changing to the v6 default:
51
- ```yml
52
- source_path: app/javascript
53
- source_entry_path: /
54
- ```
55
- Then consider moving your `app/javascript/packs/*` (including `application.js`) to `app/javascript/` and updating the configuration file.
56
-
57
- Note, moving your files is optional, as you can stil keep your entries in a separate directory, called something like `packs`, or `entries`. This directory is defined within the source_path.
49
+ ```yml
50
+ source_path: app/javascript
51
+ source_entry_path: packs
52
+ ```
53
+ consider changing to the v6 default:
54
+ ```yml
55
+ source_path: app/javascript
56
+ source_entry_path: /
57
+ ```
58
+ Then consider moving your `app/javascript/packs/*` (including `application.js`) to `app/javascript/` and updating the configuration file.
59
+
60
+ Note, moving your files is optional, as you can stil keep your entries in a separate directory, called something like `packs`, or `entries`. This directory is defined within the source_path.
58
61
 
59
62
  1. **Ensure no nested directories in your `source_entry_path`.** Check if you had any entry point files in child directories of your `source_entry_path`. Files for entry points in child directories are not supported by shakacode/shakapacker v6. Move those files to the top level, adjusting any imports in those files.
60
63
 
61
- The new v6 configuration does not allow nesting, so as to allow placing the entry points at in the root directory of JavaScript. You can find this change [here](https://github.com/rails/webpacker/commit/5de0fbc1e16d3db0c93202fb39f5b4d80582c682#diff-7af8667a3e36201db57c02b68dd8651883d7bfc00dc9653661be11cd31feeccdL19).
64
+ The new v6 configuration does not allow nesting, so as to allow placing the entry points at in the root directory of JavaScript. You can find this change [here](https://github.com/rails/webpacker/commit/5de0fbc1e16d3db0c93202fb39f5b4d80582c682#diff-7af8667a3e36201db57c02b68dd8651883d7bfc00dc9653661be11cd31feeccdL19).
62
65
 
63
66
  1. Upgrade the Webpacker Ruby gem and the NPM package
64
67
 
65
- Note: [Check the gem page to verify the latest version](https://rubygems.org/gems/shakapacker), and make sure to install identical version numbers of `shakapacker` gem and package. (Gems use a period and packages use a dot between the main version number and the beta version.)
68
+ Note: [Check the gem page to verify the latest version](https://rubygems.org/gems/shakapacker), and make sure to install identical version numbers of `shakapacker` gem and package. (Gems use a hyphen and packages use a dot between the main version number and the beta version.)
66
69
 
67
70
  Example going to a specific version:
68
71
 
@@ -79,35 +82,15 @@ _If you're on webpacker v5, follow below steps to get to v6.0.0.rc.6 first._
79
82
  yarn add shakapacker@6.0.0-rc.13 --exact
80
83
  ```
81
84
 
82
- ```bash
83
- bundle exec rails webpacker:install
84
- ```
85
-
86
- Overwrite all files and check what changed.
85
+ ```bash
86
+ bundle exec rails webpacker:install
87
+ ```
87
88
 
88
- Note, the webpacker:install will install the peer dependencies:
89
- ```bash
90
- yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader compression-webpack-plugin terser-webpack-plugin webpack webpack-assets-manifest webpack-cli webpack-merge webpack-sources webpack-dev-server
91
- ```
89
+ Overwrite all files and check what changed.
92
90
 
93
- 1. There is now a single default configuration file of `config/webpack/webpack.config.js`. Previously, the config file was set
94
- to `config/webpack/#{NODE_ENV}.js`. In the `config/webpack/` directory, you can either refactor your code in `test.js`, `development.js`, and `production.js` to a single file, `webpack.config.js` or you can replace the contents of `config/webpack/config.webpack.js` to conditionally load the old file based on the NODE_ENV with this snippet:
95
- ```js
96
- const { env, webpackConfig } = require('shakapacker')
97
- const { existsSync } = require('fs')
98
- const { resolve } = require('path')
99
-
100
- const envSpecificConfig = () => {
101
- const path = resolve(__dirname, `${env.nodeEnv}.js`)
102
- if (existsSync(path)) {
103
- console.log(`Loading ENV specific webpack configuration file ${path}`)
104
- return require(path)
105
- } else {
106
- return webpackConfig
107
- }
108
- }
109
-
110
- module.exports = envSpecificConfig()
91
+ Note, the webpacker:install will install the peer dependencies:
92
+ ```bash
93
+ yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader compression-webpack-plugin terser-webpack-plugin webpack webpack-assets-manifest webpack-cli webpack-merge webpack-sources webpack-dev-server
111
94
  ```
112
95
 
113
96
  1. Review the new default's changes to `webpacker.yml`. Consider each suggested change carefully, especially the change to have your `source_entry_path` be at the top level of your `source_path`.
@@ -135,51 +118,66 @@ _If you're on webpacker v5, follow below steps to get to v6.0.0.rc.6 first._
135
118
 
136
119
  1. If you are using any integrations like `css`, `postcss`, `React` or `TypeScript`. Please see https://github.com/shakacode/shakapacker#integrations section on how they work in v6.
137
120
 
138
- 1. Import `environment` changed to `webpackConfig`. For example, the new code looks like:
121
+ 1. `config/webpack/environment.js` was changed to `config/webpack/base.js` and exports a native webpack config so no need to call `toWebpackConfig`.
122
+ Use `merge` to make changes:
123
+
139
124
  ```js
140
- // config/webpack/webpack.config.js
141
- const { webpackConfig, merge } = require('shakapacker')
142
- const customConfig = require('./custom')
143
-
144
- module.exports = merge(webpackConfig, customConfig)
125
+ // config/webpack/base.js
126
+ const { webpackConfig, merge } = require('@rails/webpacker');
127
+ const customConfig = {
128
+ module: {
129
+ rules: [
130
+ {
131
+ test: require.resolve('jquery'),
132
+ loader: 'expose-loader',
133
+ options: {
134
+ exposes: ['$', 'jQuery']
135
+ }
136
+ }
137
+ ]
138
+ }
139
+ };
140
+
141
+ module.exports = merge(webpackConfig, customConfig);
145
142
  ```
146
-
143
+
147
144
  1. Copy over custom browserlist config from `.browserslistrc` if it exists into the `"browserslist"` key in `package.json` and remove `.browserslistrc`.
148
145
 
149
146
  1. Remove `babel.config.js` if you never changed it. Configure your `package.json` to use the default:
150
- ```json
151
- "babel": {
152
- "presets": [
153
- "./node_modules/shakapacker/package/babel/preset.js"
154
- ]
155
- }
156
- ```
157
- See customization example the [Customizing Babel Config](./docs/customizing_babel_config.md) for React configuration.
147
+ ```json
148
+ "babel": {
149
+ "presets": [
150
+ "./node_modules/@rails/webpacker/package/babel/preset.js"
151
+ ]
152
+ }
153
+ ```
154
+ See customization example the [Customizing Babel Config](./docs/customizing_babel_config.md) for React configuration.
158
155
 
159
156
  1. `extensions` was removed from the `webpacker.yml` file. Move custom extensions to your configuration by merging an object like this. For more details, see docs for [Webpack Configuration](https://github.com/shakacode/shakapacker/blob/master/README.md#webpack-configuration)
160
157
 
161
- ```js
162
- {
163
- resolve: {
164
- extensions: ['.ts', '.tsx', '.vue', '.css']
165
- }
166
- }
167
- ```
168
- 1. In `webpacker.yml`, check if you had `watched_paths`. That is not `additional_paths`.
158
+ ```js
159
+ {
160
+ resolve: {
161
+ extensions: ['.ts', '.tsx', '.vue', '.css']
162
+ }
163
+ }
164
+ ```
165
+ 1. In `webpacker.yml`, check if you had `watched_paths`. That is now `additional_paths`.
169
166
 
170
167
  1. Some dependencies were removed in [PR 3056](https://github.com/rails/webpacker/pull/3056). If you see the error: `Error: Cannot find module 'babel-plugin-macros'`, or similar, then you need to `yarn add <dependency>` where <dependency> might include: `babel-plugin-macros`, `case-sensitive-paths-webpack-plugin`, `core-js`, `regenerator-runtime`. Or you might want to remove your dependency on those.
171
168
 
172
169
  1. Review the new default's changes to `webpacker.yml` and `config/webpack`. Consider each suggested change carefully, especially the change to have your `source_entry_path` be at the top level of your `source_path`.
173
170
 
174
- 1. Make sure that you can run `bin/webpacker` without errors.
171
+ 1. Make sure that you can run `bin/webpack` without errors.
175
172
 
176
173
  1. Try running `RAILS_ENV=production bin/rails assets:precompile`. If all goes well, don't forget to clean the generated assets with `bin/rails assets:clobber`.
177
174
 
178
175
  1. Run `yarn add webpack-dev-server` if those are not already in your dev dependencies. Make sure you're using v4+.
179
176
 
180
- 1. Update any scripts that called `/bin/webpack` or `bin/webpack-dev-server` to `/bin/webpacker` or `bin/webpacker-dev-server`
177
+ 1. In `bin/webpack` and `bin/webpack-dev-server`, The default NODE_ENV, if not set, will be the RAILS_ENV. Previously, NODE_ENV would default to development if not set. Thus, the old bin stubs would use the webpack config corresponding to `config/webpack/development.js`. After the change, if `RAILS_ENV` is `test`, then `NODE_ENV` is `test`. The final 6.0 release changes to using a single `webpack.config.js`.
178
+
179
+ 1. Now, follow the steps above to get to shakapacker v6 from webpacker v6.0.0.rc.6
181
180
 
182
- 1. Now, follow the steps above to get to shakapacker v6 from webpacker v6.0.0.rc.6[
183
181
 
184
182
  ## Examples of v5 to v6
185
183
 
@@ -7,6 +7,11 @@ 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
12
+
13
+ # Location for manifest.json, defaults to {public_output_path}/manifest.json if unset
14
+ # manifest_path: public/packs/manifest.json
10
15
 
11
16
  # Additional paths webpack should look up modules
12
17
  # ['app/assets', 'engine/foo/app/assets']
@@ -18,6 +23,9 @@ default: &default
18
23
  # Select loader to use, available options are 'babel' (default), 'swc' or 'esbuild'
19
24
  webpack_loader: 'babel'
20
25
 
26
+ # Set to true to enable check for matching versions of shakapacker gem and NPM package - will raise an error if there is a mismatch or wildcard versioning is used
27
+ ensure_consistent_versioning: false
28
+
21
29
  development:
22
30
  <<: *default
23
31
  compile: true
@@ -29,6 +37,14 @@ development:
29
37
  port: 3035
30
38
  # Hot Module Replacement updates modules while the application is running without a full reload
31
39
  hmr: false
40
+ # If HMR is on, CSS will by inlined by delivering it as part of the script payload via style-loader. Be sure
41
+ # that you add style-loader to your project dependencies.
42
+ #
43
+ # If you want to instead deliver CSS via <link> with the mini-extract-css-plugin, set inline_css to false.
44
+ # In that case, style-loader is not needed as a dependency.
45
+ #
46
+ # mini-extract-css-plugin is a required dependency in both cases.
47
+ inline_css: true
32
48
  # Defaults to the inverse of hmr. Uncomment to manually set this.
33
49
  # live_reload: true
34
50
  client:
@@ -58,10 +58,10 @@ results = []
58
58
  Dir.chdir(Rails.root) do
59
59
  if Webpacker::VERSION.match?(/^[0-9]+\.[0-9]+\.[0-9]+$/)
60
60
  say "Installing shakapacker@#{Webpacker::VERSION}"
61
- results << run("yarn add shakapacker@#{Webpacker::VERSION}")
61
+ results << run("yarn add shakapacker@#{Webpacker::VERSION} --exact")
62
62
  else
63
63
  say "Installing shakapacker@next"
64
- results << run("yarn add shakapacker@next")
64
+ results << run("yarn add shakapacker@next --exact")
65
65
  end
66
66
 
67
67
  package_json = File.read("#{__dir__}/../../package.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
@@ -16,7 +16,7 @@ class Webpacker::Commands
16
16
  # age=600.
17
17
  #
18
18
  def clean(count = 2, age = 3600)
19
- if config.public_output_path.exist? && config.public_manifest_path.exist?
19
+ if config.public_output_path.exist? && config.manifest_path.exist?
20
20
  packs
21
21
  .map do |paths|
22
22
  paths.map { |path| [Time.now - File.mtime(path), path] }
@@ -57,7 +57,7 @@ class Webpacker::Commands
57
57
  private
58
58
  def packs
59
59
  all_files = Dir.glob("#{config.public_output_path}/**/*")
60
- manifest_config = Dir.glob("#{config.public_manifest_path}*")
60
+ manifest_config = Dir.glob("#{config.manifest_path}*")
61
61
 
62
62
  packs = all_files - manifest_config - current_version
63
63
  packs.reject { |file| File.directory?(file) }.group_by do |path|
@@ -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.public_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,
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
 
@@ -23,6 +23,16 @@ class Webpacker::Configuration
23
23
  fetch(:compile)
24
24
  end
25
25
 
26
+ def ensure_consistent_versioning?
27
+ fetch(:ensure_consistent_versioning)
28
+ end
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
+
26
36
  def source_path
27
37
  root_path.join(fetch(:source_path))
28
38
  end
@@ -35,6 +45,18 @@ class Webpacker::Configuration
35
45
  source_path.join(fetch(:source_entry_path))
36
46
  end
37
47
 
48
+ def manifest_path
49
+ if data.has_key?(:manifest_path)
50
+ root_path.join(fetch(:manifest_path))
51
+ else
52
+ public_output_path.join("manifest.json")
53
+ end
54
+ end
55
+
56
+ def public_manifest_path
57
+ manifest_path
58
+ end
59
+
38
60
  def public_path
39
61
  root_path.join(fetch(:public_root_path))
40
62
  end
@@ -43,10 +65,6 @@ class Webpacker::Configuration
43
65
  public_path.join(fetch(:public_output_path))
44
66
  end
45
67
 
46
- def public_manifest_path
47
- public_output_path.join("manifest.json")
48
- end
49
-
50
68
  def cache_manifest?
51
69
  fetch(:cache_manifest)
52
70
  end
@@ -1,9 +1,9 @@
1
1
  class Webpacker::DevServer
2
2
  DEFAULT_ENV_PREFIX = "WEBPACKER_DEV_SERVER".freeze
3
3
 
4
- # Configure dev server connection timeout (in seconds), default: 0.01
4
+ # Configure dev server connection timeout (in seconds), default: 0.1
5
5
  # Webpacker.dev_server.connect_timeout = 1
6
- cattr_accessor(:connect_timeout) { 0.01 }
6
+ cattr_accessor(:connect_timeout) { 0.1 }
7
7
 
8
8
  attr_reader :config
9
9
 
@@ -55,6 +55,15 @@ class Webpacker::DevServer
55
55
  fetch(:hmr)
56
56
  end
57
57
 
58
+ def inline_css?
59
+ case fetch(:inline_css)
60
+ when false, "false"
61
+ false
62
+ else
63
+ true
64
+ end
65
+ end
66
+
58
67
  def env_prefix
59
68
  config.dev_server.fetch(:env_prefix, DEFAULT_ENV_PREFIX)
60
69
  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.
@@ -148,20 +156,30 @@ module Webpacker::Helper
148
156
  # <%= stylesheet_pack_tag 'calendar' %>
149
157
  # <%= stylesheet_pack_tag 'map' %>
150
158
  def stylesheet_pack_tag(*names, **options)
151
- if @stylesheet_pack_tag_loaded
152
- raise "To prevent duplicated chunks on the page, you should call stylesheet_pack_tag only once on the page. " \
153
- "Please refer to https://github.com/shakacode/shakapacker/blob/master/README.md#usage for the usage guide"
154
- end
155
-
156
- @stylesheet_pack_tag_loaded = true
157
-
158
159
  return "" if Webpacker.inlining_css?
159
160
 
160
161
  stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
161
162
  end
162
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
+
163
174
  private
164
175
 
176
+ def javascript_pack_tag_queue
177
+ @javascript_pack_tag_queue ||= {
178
+ deferred: [],
179
+ non_deferred: []
180
+ }
181
+ end
182
+
165
183
  def sources_from_manifest_entrypoints(names, type:)
166
184
  names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks!(name.to_s, type: type) }.flatten.uniq
167
185
  end
@@ -36,6 +36,6 @@ class Webpacker::Instance
36
36
  end
37
37
 
38
38
  def inlining_css?
39
- dev_server.hmr? && dev_server.running?
39
+ dev_server.inline_css? && dev_server.hmr? && dev_server.running?
40
40
  end
41
41
  end
@@ -80,8 +80,8 @@ class Webpacker::Manifest
80
80
  end
81
81
 
82
82
  def load
83
- if config.public_manifest_path.exist?
84
- JSON.parse config.public_manifest_path.read
83
+ if config.manifest_path.exist?
84
+ JSON.parse config.manifest_path.read
85
85
  else
86
86
  {}
87
87
  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.public_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
 
@@ -2,11 +2,18 @@ require "rails/railtie"
2
2
 
3
3
  require "webpacker/helper"
4
4
  require "webpacker/dev_server_proxy"
5
+ require "webpacker/version_checker"
5
6
 
6
7
  class Webpacker::Engine < ::Rails::Engine
7
8
  # Allows Webpacker config values to be set via Rails env config files
8
9
  config.webpacker = ActiveSupport::OrderedOptions.new
9
10
 
11
+ initializer "webpacker.version_checker" do
12
+ if File.exist?(Webpacker::VersionChecker::NodePackageVersion.package_json_path)
13
+ Webpacker::VersionChecker.build.raise_if_gem_and_node_package_versions_differ
14
+ end
15
+ end
16
+
10
17
  initializer "webpacker.proxy" do |app|
11
18
  if (Webpacker.config.dev_server.present? rescue nil)
12
19
  app.middleware.insert_before 0,
@@ -1,4 +1,4 @@
1
1
  module Webpacker
2
2
  # Change the version in package.json too, please!
3
- VERSION = "6.1.1".freeze
3
+ VERSION = "6.3.0-rc.1".freeze
4
4
  end