shakapacker 6.1.0.beta.0 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  3. data/.github/ISSUE_TEMPLATE/feature-request.md +1 -1
  4. data/.github/workflows/jest.yml +1 -4
  5. data/.github/workflows/js-lint.yml +3 -7
  6. data/.github/workflows/rubocop.yml +3 -20
  7. data/.github/workflows/ruby.yml +12 -19
  8. data/.node-version +1 -1
  9. data/.rubocop.yml +0 -1
  10. data/CHANGELOG.md +34 -3
  11. data/Gemfile.lock +1 -1
  12. data/README.md +50 -17
  13. data/docs/customizing_babel_config.md +2 -0
  14. data/docs/style_loader_vs_mini_css.md +48 -0
  15. data/docs/using_esbuild_loader.md +128 -0
  16. data/docs/using_swc_loader.md +6 -4
  17. data/docs/v6_upgrade.md +95 -79
  18. data/gemfiles/Gemfile-rails.7.0.x +12 -0
  19. data/lib/install/config/webpacker.yml +15 -1
  20. data/lib/install/template.rb +2 -2
  21. data/lib/webpacker/commands.rb +2 -2
  22. data/lib/webpacker/compiler.rb +1 -1
  23. data/lib/webpacker/configuration.rb +12 -4
  24. data/lib/webpacker/dev_server.rb +11 -2
  25. data/lib/webpacker/helper.rb +0 -7
  26. data/lib/webpacker/instance.rb +1 -1
  27. data/lib/webpacker/manifest.rb +3 -3
  28. data/lib/webpacker/railtie.rb +7 -0
  29. data/lib/webpacker/version.rb +1 -1
  30. data/lib/webpacker/version_checker.rb +152 -0
  31. data/package/__tests__/config.js +11 -0
  32. data/package/config.js +6 -0
  33. data/package/environments/base.js +1 -1
  34. data/package/esbuild/index.js +40 -0
  35. data/package/inliningCss.js +1 -1
  36. data/package/rules/__tests__/file.js +35 -0
  37. data/package/rules/__tests__/index.js +11 -0
  38. data/package/rules/__tests__/raw.js +18 -0
  39. data/package/rules/esbuild.js +23 -0
  40. data/package/rules/file.js +14 -18
  41. data/package/rules/index.js +1 -0
  42. data/package/rules/raw.js +2 -2
  43. data/package/swc/index.js +3 -3
  44. data/package.json +2 -1
  45. data/test/configuration_test.rb +24 -3
  46. data/test/fixtures/beta_package.json +13 -0
  47. data/test/fixtures/git_url_package.json +13 -0
  48. data/test/fixtures/github_url_package.json +13 -0
  49. data/test/fixtures/normal_package.json +13 -0
  50. data/test/fixtures/relative_path_package.json +13 -0
  51. data/test/fixtures/semver_caret_package.json +13 -0
  52. data/test/fixtures/semver_tilde_package.json +13 -0
  53. data/test/fixtures/without_package.json +13 -0
  54. data/test/helper_test.rb +12 -12
  55. data/test/test_app/config/webpacker.yml +4 -0
  56. data/test/test_app/config/webpacker_manifest_path.yml +80 -0
  57. data/test/version_checker_test.rb +271 -0
  58. data/test/webpacker_test.rb +15 -0
  59. data/webpacker.gemspec +1 -1
  60. data/yarn.lock +145 -1
  61. metadata +35 -6
data/docs/v6_upgrade.md CHANGED
@@ -1,48 +1,69 @@
1
- # Upgrading from Webpacker 5 to 6
1
+ # Upgrading from Webpacker v5 to Shakapacker v6
2
2
 
3
- There are several substantial changes in Webpacker 6 that you need to manually account for when coming from Webpacker 5. This guide will help you through it.
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
- ## Webpacker has become a slimmer wrapper around Webpack
5
+ ## Webpacker/Shakapacker has become a slimmer wrapper around Webpack
6
6
 
7
7
  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.
8
8
 
9
- Webpacker used to configure Webpack indirectly, which lead to a [complicated secondary configuration process](https://github.com/rails/webpacker/blob/5-x-stable/docs/webpack.md). This was done in order to provide default configurations for the most popular frameworks, but ended up creating more complexity than it cured. So now Webpacker delegates all configuration directly to Webpack's default configuration setup.
9
+ Webpacker used to configure Webpack indirectly, which lead to a [complicated secondary configuration process](https://github.com/rails/webpacker/blob/5-x-stable/docs/webpack.md). This was done in order to provide default configurations for the most popular frameworks, but ended up creating more complexity than it cured. So now Webpacker delegates all configuration directly to Webpack's default configuration setup. Additionally, all major dependencies, like `webpack` and `babel` are now **peer** dependencies, so you are free to upgrade those.
10
10
 
11
- This means you have to configure integration with frameworks yourself, but 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).
11
+ 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
12
 
13
- ## webpacker v6.0.0.rc.6 to shakapacker
13
+ ## webpacker v6.0.0.rc.6 to shakapacker v6.0.0
14
14
  See an example migration here: [PR 27](https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/pull/27).
15
-
16
- ### Update
17
- 1. 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`
15
+
16
+ ### Update Steps to v6.0.0 from v6.0.0.rc.6
17
+ _If you're on webpacker v5, follow below steps to get to v6.0.0.rc.6 first._
18
+
19
+ 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`
18
21
  1. Update any scripts that called `bin/webpack` or `bin/webpack-dev-server` to `bin/webpacker` or `bin/webpacker-dev-server`
19
- 1. Update your webpack config for a single config file, `config/webpack/webpack.config.js`.
20
- 1. Update `babel.config.js` if you need JSX support.
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`. 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
+ ```js
24
+ const { env, webpackConfig } = require('shakapacker')
25
+ const { existsSync } = require('fs')
26
+ const { resolve } = require('path')
27
+
28
+ const envSpecificConfig = () => {
29
+ const path = resolve(__dirname, `${env.nodeEnv}.js`)
30
+ if (existsSync(path)) {
31
+ console.log(`Loading ENV specific webpack configuration file ${path}`)
32
+ return require(path)
33
+ } else {
34
+ // Probably an error if the file for the NODE_ENV does not exist
35
+ throw new Error(`Got Error with NODE_ENV = ${env.nodeEnv}`);
36
+ }
37
+ }
38
+
39
+ module.exports = envSpecificConfig()
40
+ ```
41
+ 1. Update `babel.config.js` if you need JSX support. See [Customizing Babel Config](./customizing_babel_config.md)
21
42
 
22
- ## How to upgrade to Webpacker v6 from v5
43
+ ## How to upgrade to Webpacker v6.0.0.rc.6 from v5
23
44
  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.
24
45
 
25
46
  1. Consider changing from the v5 default for `source_entry_path` in `webpacker.yml`.
26
- ```yml
27
- source_path: app/javascript
28
- source_entry_path: packs
29
- ```
30
- consider changing to the v6 default:
31
- ```yml
32
- source_path: app/javascript
33
- source_entry_path: /
34
- ```
35
- Then consider moving your `app/javascript/packs/*` (including `application.js`) to `app/javascript/` and updating the configuration file.
36
-
37
- 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.
47
+ ```yml
48
+ source_path: app/javascript
49
+ source_entry_path: packs
50
+ ```
51
+ consider changing to the v6 default:
52
+ ```yml
53
+ source_path: app/javascript
54
+ source_entry_path: /
55
+ ```
56
+ Then consider moving your `app/javascript/packs/*` (including `application.js`) to `app/javascript/` and updating the configuration file.
57
+
58
+ 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.
38
59
 
39
60
  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.
40
61
 
41
- 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
+ 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).
42
63
 
43
64
  1. Upgrade the Webpacker Ruby gem and the NPM package
44
65
 
45
- 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.)
66
+ 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.)
46
67
 
47
68
  Example going to a specific version:
48
69
 
@@ -59,35 +80,15 @@ See an example migration here: [PR 27](https://github.com/shakacode/react_on_rai
59
80
  yarn add shakapacker@6.0.0-rc.13 --exact
60
81
  ```
61
82
 
62
- ```bash
63
- bundle exec rails webpacker:install
64
- ```
65
-
66
- Overwrite all files and check what changed.
67
-
68
- Note, the webpacker:install will install the peer dependencies:
69
- ```bash
70
- 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
71
- ```
72
-
73
- 1. There is now a single default configuration file of `config/webpack/webpack.config.js`. Previously, the config file was set
74
- 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:
75
- ```js
76
- const { env, webpackConfig } = require('shakapacker')
77
- const { existsSync } = require('fs')
78
- const { resolve } = require('path')
83
+ ```bash
84
+ bundle exec rails webpacker:install
85
+ ```
79
86
 
80
- const envSpecificConfig = () => {
81
- const path = resolve(__dirname, `${env.nodeEnv}.js`)
82
- if (existsSync(path)) {
83
- console.log(`Loading ENV specific webpack configuration file ${path}`)
84
- return require(path)
85
- } else {
86
- return webpackConfig
87
- }
88
- }
87
+ Overwrite all files and check what changed.
89
88
 
90
- module.exports = envSpecificConfig()
89
+ Note, the webpacker:install will install the peer dependencies:
90
+ ```bash
91
+ 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
92
  ```
92
93
 
93
94
  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`.
@@ -115,51 +116,66 @@ See an example migration here: [PR 27](https://github.com/shakacode/react_on_rai
115
116
 
116
117
  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.
117
118
 
118
- 1. Import `environment` changed to `webpackConfig`. For example, the new code looks like:
119
+ 1. `config/webpack/environment.js` was changed to `config/webpack/base.js` and exports a native webpack config so no need to call `toWebpackConfig`.
120
+ Use `merge` to make changes:
121
+
119
122
  ```js
120
- // config/webpack/webpack.config.js
121
- const { webpackConfig, merge } = require('shakapacker')
122
- const customConfig = require('./custom')
123
-
124
- module.exports = merge(webpackConfig, customConfig)
123
+ // config/webpack/base.js
124
+ const { webpackConfig, merge } = require('@rails/webpacker');
125
+ const customConfig = {
126
+ module: {
127
+ rules: [
128
+ {
129
+ test: require.resolve('jquery'),
130
+ loader: 'expose-loader',
131
+ options: {
132
+ exposes: ['$', 'jQuery']
133
+ }
134
+ }
135
+ ]
136
+ }
137
+ };
138
+
139
+ module.exports = merge(webpackConfig, customConfig);
125
140
  ```
126
-
141
+
127
142
  1. Copy over custom browserlist config from `.browserslistrc` if it exists into the `"browserslist"` key in `package.json` and remove `.browserslistrc`.
128
143
 
129
144
  1. Remove `babel.config.js` if you never changed it. Configure your `package.json` to use the default:
130
- ```json
131
- "babel": {
132
- "presets": [
133
- "./node_modules/shakapacker/package/babel/preset.js"
134
- ]
135
- }
136
- ```
137
- See customization example the [Customizing Babel Config](./docs/customizing_babel_config.md) for React configuration.
145
+ ```json
146
+ "babel": {
147
+ "presets": [
148
+ "./node_modules/@rails/webpacker/package/babel/preset.js"
149
+ ]
150
+ }
151
+ ```
152
+ See customization example the [Customizing Babel Config](./docs/customizing_babel_config.md) for React configuration.
138
153
 
139
154
  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)
140
155
 
141
- ```js
142
- {
143
- resolve: {
144
- extensions: ['.ts', '.tsx', '.vue', '.css']
145
- }
146
- }
147
- ```
148
- 1. In `webpacker.yml`, check if you had `watched_paths`. That is not `additional_paths`.
156
+ ```js
157
+ {
158
+ resolve: {
159
+ extensions: ['.ts', '.tsx', '.vue', '.css']
160
+ }
161
+ }
162
+ ```
163
+ 1. In `webpacker.yml`, check if you had `watched_paths`. That is now `additional_paths`.
149
164
 
150
165
  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.
151
166
 
152
167
  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`.
153
168
 
154
- 1. Make sure that you can run `bin/webpacker` without errors.
169
+ 1. Make sure that you can run `bin/webpack` without errors.
155
170
 
156
171
  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`.
157
172
 
158
173
  1. Run `yarn add webpack-dev-server` if those are not already in your dev dependencies. Make sure you're using v4+.
159
174
 
160
- 1. Update any scripts that called `/bin/webpack` or `bin/webpack-dev-server` to `/bin/webpacker` or `bin/webpacker-dev-server`
175
+ 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`.
176
+
177
+ 1. Now, follow the steps above to get to shakapacker v6 from webpacker v6.0.0.rc.6
161
178
 
162
- 1. Try your app!
163
179
 
164
180
  ## Examples of v5 to v6
165
181
 
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
4
+
5
+ gemspec path: "../"
6
+
7
+ gem "rails", '~>7.0.0'
8
+ gem "arel", github: "rails/arel"
9
+ gem "rake", ">= 11.1"
10
+ gem "rack-proxy", require: false
11
+ gem "minitest", "~> 5.0"
12
+ gem "byebug"
@@ -8,6 +8,9 @@ default: &default
8
8
  cache_path: tmp/webpacker
9
9
  webpack_compile_output: true
10
10
 
11
+ # Location for manifest.json, defaults to {public_output_path}/manifest.json if unset
12
+ # manifest_path: public/packs/manifest.json
13
+
11
14
  # Additional paths webpack should look up modules
12
15
  # ['app/assets', 'engine/foo/app/assets']
13
16
  additional_paths: []
@@ -15,9 +18,12 @@ default: &default
15
18
  # Reload manifest.json on all requests so we reload latest compiled packs
16
19
  cache_manifest: false
17
20
 
18
- # Select loader to use, available options are 'babel' (default) or 'swc'
21
+ # Select loader to use, available options are 'babel' (default), 'swc' or 'esbuild'
19
22
  webpack_loader: 'babel'
20
23
 
24
+ # 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
25
+ ensure_consistent_versioning: false
26
+
21
27
  development:
22
28
  <<: *default
23
29
  compile: true
@@ -29,6 +35,14 @@ development:
29
35
  port: 3035
30
36
  # Hot Module Replacement updates modules while the application is running without a full reload
31
37
  hmr: false
38
+ # If HMR is on, CSS will by inlined by delivering it as part of the script payload via style-loader. Be sure
39
+ # that you add style-loader to your project dependencies.
40
+ #
41
+ # If you want to instead deliver CSS via <link> with the mini-extract-css-plugin, set inline_css to false.
42
+ # In that case, style-loader is not needed as a dependency.
43
+ #
44
+ # mini-extract-css-plugin is a required dependency in both cases.
45
+ inline_css: true
32
46
  # Defaults to the inverse of hmr. Uncomment to manually set this.
33
47
  # live_reload: true
34
48
  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")
@@ -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|
@@ -47,7 +47,7 @@ class Webpacker::Compiler
47
47
  attr_reader :webpacker
48
48
 
49
49
  def last_compilation_digest
50
- compilation_digest_path.read if compilation_digest_path.exist? && config.public_manifest_path.exist?
50
+ compilation_digest_path.read if compilation_digest_path.exist? && config.manifest_path.exist?
51
51
  rescue Errno::ENOENT, Errno::ENOTDIR
52
52
  end
53
53
 
@@ -23,6 +23,10 @@ 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
+
26
30
  def source_path
27
31
  root_path.join(fetch(:source_path))
28
32
  end
@@ -35,6 +39,14 @@ class Webpacker::Configuration
35
39
  source_path.join(fetch(:source_entry_path))
36
40
  end
37
41
 
42
+ def manifest_path
43
+ if data.has_key?(:manifest_path)
44
+ root_path.join(fetch(:manifest_path))
45
+ else
46
+ public_output_path.join("manifest.json")
47
+ end
48
+ end
49
+
38
50
  def public_path
39
51
  root_path.join(fetch(:public_root_path))
40
52
  end
@@ -43,10 +55,6 @@ class Webpacker::Configuration
43
55
  public_path.join(fetch(:public_output_path))
44
56
  end
45
57
 
46
- def public_manifest_path
47
- public_output_path.join("manifest.json")
48
- end
49
-
50
58
  def cache_manifest?
51
59
  fetch(:cache_manifest)
52
60
  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
@@ -148,13 +148,6 @@ module Webpacker::Helper
148
148
  # <%= stylesheet_pack_tag 'calendar' %>
149
149
  # <%= stylesheet_pack_tag 'map' %>
150
150
  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
151
  return "" if Webpacker.inlining_css?
159
152
 
160
153
  stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
@@ -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,7 +104,7 @@ 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
+ Webpacker 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
@@ -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.0.beta.0".freeze
3
+ VERSION = "6.2.0".freeze
4
4
  end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+ require "webpacker/version"
3
+
4
+ module Webpacker
5
+ class VersionChecker
6
+ attr_reader :node_package_version
7
+
8
+ MAJOR_MINOR_PATCH_VERSION_REGEX = /(\d+)\.(\d+)\.(\d+)/.freeze
9
+
10
+ def self.build
11
+ new(NodePackageVersion.build)
12
+ end
13
+
14
+ def initialize(node_package_version)
15
+ @node_package_version = node_package_version
16
+ end
17
+
18
+ def raise_if_gem_and_node_package_versions_differ
19
+ # Skip check if package is not in package.json or listed from relative path, git repo or github URL
20
+ return if node_package_version.skip_processing?
21
+
22
+ node_major_minor_patch = node_package_version.major_minor_patch
23
+ gem_major_minor_patch = gem_major_minor_patch_version
24
+ versions_match = node_major_minor_patch[0] == gem_major_minor_patch[0] &&
25
+ node_major_minor_patch[1] == gem_major_minor_patch[1] &&
26
+ node_major_minor_patch[2] == gem_major_minor_patch[2]
27
+
28
+ uses_wildcard = node_package_version.semver_wildcard?
29
+
30
+ if !Webpacker.config.ensure_consistent_versioning? && (uses_wildcard || !versions_match)
31
+ check_failed = if uses_wildcard
32
+ "Semver wildcard detected"
33
+ else
34
+ "Version mismatch detected"
35
+ end
36
+
37
+ warn <<-MSG.strip_heredoc
38
+ Webpacker::VersionChecker - #{check_failed}
39
+
40
+ You are currently not checking for consistent versions of shakapacker gem and npm package. A version mismatch or usage of semantic versioning wildcard (~ or ^) has been detected.
41
+
42
+ Version mismatch can lead to incorrect behavior and bugs. You should ensure that both the gem and npm package dependencies are locked to the same version.
43
+
44
+ You can enable the version check by setting `ensure_consistent_versioning: true` in your `webpacker.yml` file.
45
+
46
+ Checking for gem and npm package versions mismatch or wildcard will be enabled by default in the next major version of shakapacker.
47
+ MSG
48
+
49
+ return
50
+ end
51
+
52
+ raise_differing_versions_warning unless versions_match
53
+
54
+ raise_node_semver_version_warning if uses_wildcard
55
+ end
56
+
57
+ private
58
+
59
+ def common_error_msg
60
+ <<-MSG.strip_heredoc
61
+ Detected: #{node_package_version.raw}
62
+ gem: #{gem_version}
63
+ Ensure the installed version of the gem is the same as the version of
64
+ your installed node package. Do not use >= or ~> in your Gemfile for shakapacker.
65
+ Do not use ^ or ~ in your package.json for shakapacker.
66
+ Run `yarn add shakapacker --exact` in the directory containing folder node_modules.
67
+ MSG
68
+ end
69
+
70
+ def raise_differing_versions_warning
71
+ msg = "**ERROR** Webpacker: Webpacker gem and node package versions do not match\n#{common_error_msg}"
72
+ raise msg
73
+ end
74
+
75
+ def raise_node_semver_version_warning
76
+ msg = "**ERROR** Webpacker: Your node package version for shakapacker contains a "\
77
+ "^ or ~\n#{common_error_msg}"
78
+ raise msg
79
+ end
80
+
81
+ def gem_version
82
+ Webpacker::VERSION
83
+ end
84
+
85
+ def gem_major_minor_patch_version
86
+ match = gem_version.match(MAJOR_MINOR_PATCH_VERSION_REGEX)
87
+ [match[1], match[2], match[3]]
88
+ end
89
+
90
+ class NodePackageVersion
91
+ attr_reader :package_json
92
+
93
+ def self.build
94
+ new(package_json_path)
95
+ end
96
+
97
+ def self.package_json_path
98
+ Rails.root.join("package.json")
99
+ end
100
+
101
+ def initialize(package_json)
102
+ @package_json = package_json
103
+ end
104
+
105
+ def raw
106
+ parsed_package_contents = JSON.parse(package_json_contents)
107
+ parsed_package_contents.dig("dependencies", "shakapacker").to_s
108
+ end
109
+
110
+ def semver_wildcard?
111
+ raw.match(/[~^]/).present?
112
+ end
113
+
114
+ def skip_processing?
115
+ !package_specified? || relative_path? || git_url? || github_url?
116
+ end
117
+
118
+ def major_minor_patch
119
+ return if skip_processing?
120
+
121
+ match = raw.match(MAJOR_MINOR_PATCH_VERSION_REGEX)
122
+ unless match
123
+ raise "Cannot parse version number '#{raw}' (wildcard versions are not supported)"
124
+ end
125
+
126
+ [match[1], match[2], match[3]]
127
+ end
128
+
129
+ private
130
+
131
+ def package_specified?
132
+ raw.present?
133
+ end
134
+
135
+ def relative_path?
136
+ raw.match(%r{(\.\.|\Afile:///)}).present?
137
+ end
138
+
139
+ def git_url?
140
+ raw.match(%r{^git}).present?
141
+ end
142
+
143
+ def github_url?
144
+ raw.match(%r{^([\w-]+\/[\w-]+)}).present?
145
+ end
146
+
147
+ def package_json_contents
148
+ @package_json_contents ||= File.read(package_json)
149
+ end
150
+ end
151
+ end
152
+ end
@@ -1,6 +1,7 @@
1
1
  /* global test expect, describe */
2
2
 
3
3
  const { chdirCwd, chdirTestApp, resetEnv } = require('../utils/helpers')
4
+ const { resolve } = require('path')
4
5
 
5
6
  chdirTestApp()
6
7
 
@@ -31,4 +32,14 @@ describe('Config', () => {
31
32
  'app/elm'
32
33
  ])
33
34
  })
35
+
36
+ test('should default manifestPath to the public dir', () => {
37
+ expect(config.manifestPath).toEqual(resolve('public/packs/manifest.json'))
38
+ })
39
+
40
+ test('should allow overriding manifestPath', () => {
41
+ process.env.WEBPACKER_CONFIG = 'config/webpacker_manifest_path.yml'
42
+ const config = require('../config')
43
+ expect(config.manifestPath).toEqual(resolve('app/packs/manifest.json'))
44
+ })
34
45
  })
data/package/config.js CHANGED
@@ -29,4 +29,10 @@ const getPublicPath = () => {
29
29
  config.publicPath = getPublicPath()
30
30
  config.publicPathWithoutCDN = `/${config.public_output_path}/`
31
31
 
32
+ if (config.manifest_path) {
33
+ config.manifestPath = resolve(config.manifest_path)
34
+ } else {
35
+ config.manifestPath = resolve(config.outputPath, 'manifest.json')
36
+ }
37
+
32
38
  module.exports = config