shakapacker 6.1.0 → 6.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) 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/.node-version +1 -1
  5. data/CHANGELOG.md +26 -2
  6. data/Gemfile.lock +1 -1
  7. data/README.md +42 -16
  8. data/docs/customizing_babel_config.md +2 -0
  9. data/docs/deployment.md +2 -2
  10. data/docs/style_loader_vs_mini_css.md +48 -0
  11. data/docs/troubleshooting.md +18 -0
  12. data/docs/using_esbuild_loader.md +128 -0
  13. data/docs/using_swc_loader.md +2 -2
  14. data/docs/v6_upgrade.md +72 -74
  15. data/lib/install/config/webpacker.yml +15 -1
  16. data/lib/install/template.rb +2 -2
  17. data/lib/webpacker/commands.rb +2 -2
  18. data/lib/webpacker/compiler.rb +2 -2
  19. data/lib/webpacker/configuration.rb +16 -4
  20. data/lib/webpacker/dev_server.rb +11 -2
  21. data/lib/webpacker/helper.rb +0 -7
  22. data/lib/webpacker/instance.rb +1 -1
  23. data/lib/webpacker/manifest.rb +3 -3
  24. data/lib/webpacker/railtie.rb +7 -0
  25. data/lib/webpacker/version.rb +1 -1
  26. data/lib/webpacker/version_checker.rb +152 -0
  27. data/package/__tests__/config.js +11 -0
  28. data/package/config.js +6 -0
  29. data/package/environments/base.js +1 -1
  30. data/package/esbuild/index.js +40 -0
  31. data/package/inliningCss.js +1 -1
  32. data/package/rules/__tests__/file.js +35 -0
  33. data/package/rules/__tests__/index.js +11 -0
  34. data/package/rules/__tests__/raw.js +18 -0
  35. data/package/rules/esbuild.js +23 -0
  36. data/package/rules/file.js +2 -17
  37. data/package/rules/index.js +1 -0
  38. data/package/rules/raw.js +2 -2
  39. data/package/swc/index.js +3 -3
  40. data/package.json +2 -1
  41. data/test/configuration_test.rb +26 -0
  42. data/test/fixtures/beta_package.json +13 -0
  43. data/test/fixtures/git_url_package.json +13 -0
  44. data/test/fixtures/github_url_package.json +13 -0
  45. data/test/fixtures/normal_package.json +13 -0
  46. data/test/fixtures/relative_path_package.json +13 -0
  47. data/test/fixtures/semver_caret_package.json +13 -0
  48. data/test/fixtures/semver_tilde_package.json +13 -0
  49. data/test/fixtures/without_package.json +13 -0
  50. data/test/helper_test.rb +12 -12
  51. data/test/test_app/config/webpacker.yml +4 -0
  52. data/test/test_app/config/webpacker_manifest_path.yml +80 -0
  53. data/test/version_checker_test.rb +271 -0
  54. data/test/webpacker_test.rb +15 -0
  55. data/yarn.lock +145 -1
  56. metadata +31 -3
@@ -0,0 +1,40 @@
1
+ /* eslint global-require: 0 */
2
+ /* eslint import/no-dynamic-require: 0 */
3
+
4
+ const { resolve } = require('path')
5
+ const { existsSync } = require('fs')
6
+ const { merge } = require('webpack-merge')
7
+
8
+ const getLoaderExtension = (filename) => {
9
+ const matchData = filename.match(/\.([jt]sx?)?(\.erb)?$/)
10
+
11
+ if (!matchData) {
12
+ return 'js'
13
+ }
14
+
15
+ return matchData[1]
16
+ }
17
+
18
+ const getCustomConfig = () => {
19
+ const path = resolve('config', 'esbuild.config.js')
20
+ if (existsSync(path)) {
21
+ return require(path)
22
+ }
23
+ return {}
24
+ }
25
+
26
+ const getEsbuildLoaderConfig = (filenameToProcess) => {
27
+ const customConfig = getCustomConfig()
28
+ const defaultConfig = {
29
+ loader: require.resolve('esbuild-loader'),
30
+ options: {
31
+ loader: getLoaderExtension(filenameToProcess)
32
+ }
33
+ }
34
+
35
+ return merge(defaultConfig, customConfig)
36
+ }
37
+
38
+ module.exports = {
39
+ getEsbuildLoaderConfig
40
+ }
@@ -2,6 +2,6 @@ const { runningWebpackDevServer } = require('./env')
2
2
  const devServer = require('./dev_server')
3
3
 
4
4
  // This logic is tied to lib/webpacker/instance.rb
5
- const inliningCss = runningWebpackDevServer && devServer.hmr
5
+ const inliningCss = runningWebpackDevServer && devServer.hmr && devServer.inline_css !== false
6
6
 
7
7
  module.exports = inliningCss
@@ -0,0 +1,35 @@
1
+ const file = require('../file')
2
+
3
+ describe('file', () => {
4
+ test('test expected file types', () => {
5
+ const types = [
6
+ '.bmp',
7
+ '.gif',
8
+ '.jpg',
9
+ '.jpeg',
10
+ '.png',
11
+ '.tiff',
12
+ '.ico',
13
+ '.avif',
14
+ '.webp',
15
+ '.eot',
16
+ '.otf',
17
+ '.ttf',
18
+ '.woff',
19
+ '.woff2',
20
+ '.svg',
21
+ ]
22
+ types.forEach(type => expect(file.test.test(type)).toBe(true))
23
+ })
24
+
25
+ test('exclude expected file types', () => {
26
+ const types = [
27
+ '.js',
28
+ '.mjs',
29
+ '.jsx',
30
+ '.ts',
31
+ '.tsx',
32
+ ]
33
+ types.forEach(type => expect(file.exclude.test(type)).toBe(true))
34
+ })
35
+ })
@@ -0,0 +1,11 @@
1
+ const rules = require('../index')
2
+
3
+ describe('index', () => {
4
+ test('rule tests are regexes', () => {
5
+ rules.forEach(rule => expect(rule.test instanceof RegExp).toBe(true))
6
+ })
7
+
8
+ test('rule excludes are regexes', () => {
9
+ rules.forEach(rule => expect(rule.exclude instanceof RegExp).toBe(true))
10
+ })
11
+ })
@@ -0,0 +1,18 @@
1
+ const raw = require('../raw')
2
+
3
+ describe('raw', () => {
4
+ test('test expected file types', () => {
5
+ expect(raw.test.test('.html')).toBe(true)
6
+ })
7
+
8
+ test('exclude expected file types', () => {
9
+ const types = [
10
+ '.js',
11
+ '.mjs',
12
+ '.jsx',
13
+ '.ts',
14
+ '.tsx',
15
+ ]
16
+ types.forEach(type => expect(raw.exclude.test(type)).toBe(true))
17
+ })
18
+ })
@@ -0,0 +1,23 @@
1
+ const { resolve } = require('path')
2
+ const { realpathSync } = require('fs')
3
+ const { loaderMatches } = require('../utils/helpers')
4
+ const { getEsbuildLoaderConfig } = require('../esbuild')
5
+
6
+ const {
7
+ source_path: sourcePath,
8
+ additional_paths: additionalPaths,
9
+ webpack_loader: webpackLoader
10
+ } = require('../config')
11
+
12
+ module.exports = loaderMatches(webpackLoader, 'esbuild', () => ({
13
+ test: /\.(ts|tsx|js|jsx|mjs|coffee)?(\.erb)?$/,
14
+ include: [sourcePath, ...additionalPaths].map((p) => {
15
+ try {
16
+ return realpathSync(p)
17
+ } catch (e) {
18
+ return resolve(p)
19
+ }
20
+ }),
21
+ exclude: /node_modules/,
22
+ use: ({ resource }) => getEsbuildLoaderConfig(resource)
23
+ }))
@@ -2,23 +2,8 @@ const { dirname, join } = require('path')
2
2
  const { source_path: sourcePath } = require('../config')
3
3
 
4
4
  module.exports = {
5
- test: [
6
- /\.bmp$/,
7
- /\.gif$/,
8
- /\.jpe?g$/,
9
- /\.png$/,
10
- /\.tiff$/,
11
- /\.ico$/,
12
- /\.avif$/,
13
- /\.webp$/,
14
- /\.eot$/,
15
- /\.otf$/,
16
- /\.ttf$/,
17
- /\.woff$/,
18
- /\.woff2$/,
19
- /\.svg$/
20
- ],
21
- exclude: [/\.(js|mjs|jsx|ts|tsx)$/],
5
+ test: /\.(bmp|gif|jpe?g|png|tiff|ico|avif|webp|eot|otf|ttf|woff|woff2|svg)$/,
6
+ exclude: /\.(js|mjs|jsx|ts|tsx)$/,
22
7
  type: 'asset/resource',
23
8
  generator: {
24
9
  filename: (pathData) => {
@@ -8,6 +8,7 @@ const rules = {
8
8
  sass: require('./sass'),
9
9
  babel: require('./babel'),
10
10
  swc: require('./swc'),
11
+ esbuild: require('./esbuild'),
11
12
  erb: require('./erb'),
12
13
  coffee: require('./coffee'),
13
14
  less: require('./less'),
data/package/rules/raw.js CHANGED
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
- test: [/\.html$/],
3
- exclude: [/\.(js|mjs|jsx|ts|tsx)$/],
2
+ test: /\.html$/,
3
+ exclude: /\.(js|mjs|jsx|ts|tsx)$/,
4
4
  type: 'asset/source'
5
5
  }
data/package/swc/index.js CHANGED
@@ -30,12 +30,12 @@ const getSwcLoaderConfig = (filenameToProcess) => {
30
30
  : 'ecmascript',
31
31
  [isTypescriptFile(filenameToProcess) ? 'tsx' : 'jsx']:
32
32
  isJsxFile(filenameToProcess)
33
- }
33
+ },
34
+ loose: true
34
35
  },
35
36
  sourceMaps: true,
36
37
  env: {
37
- coreJs: '3.8',
38
- loose: true,
38
+ coreJs: 3,
39
39
  exclude: ['transform-typeof-symbol'],
40
40
  mode: 'entry'
41
41
  }
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shakapacker",
3
- "version": "6.1.0",
3
+ "version": "6.2.1",
4
4
  "description": "Use webpack to manage app-like JavaScript modules in Rails",
5
5
  "main": "package/index.js",
6
6
  "files": [
@@ -32,6 +32,7 @@
32
32
  "devDependencies": {
33
33
  "babel-loader": "^8.2.2",
34
34
  "compression-webpack-plugin": "^9.0.0",
35
+ "esbuild-loader": "^2.18.0",
35
36
  "eslint": "^7.32.0",
36
37
  "eslint-config-airbnb": "^18.2.1",
37
38
  "eslint-config-prettier": "^8.3.0",
@@ -43,6 +43,20 @@ class ConfigurationTest < Webpacker::Test
43
43
  assert_equal @config.public_manifest_path.to_s, public_manifest_path
44
44
  end
45
45
 
46
+ def test_manifest_path
47
+ manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
48
+ assert_equal @config.manifest_path.to_s, manifest_path
49
+
50
+ @config = Webpacker::Configuration.new(
51
+ root_path: @config.root_path,
52
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_manifest_path.yml", __dir__)),
53
+ env: "production"
54
+ )
55
+
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
58
+ end
59
+
46
60
  def test_cache_path
47
61
  cache_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/tmp/webpacker").to_s
48
62
  assert_equal @config.cache_path.to_s, cache_path
@@ -75,4 +89,16 @@ class ConfigurationTest < Webpacker::Test
75
89
  assert Webpacker.config.compile?
76
90
  end
77
91
  end
92
+
93
+ def test_ensure_consistent_versioning?
94
+ refute @config.ensure_consistent_versioning?
95
+
96
+ with_rails_env("development") do
97
+ assert Webpacker.config.ensure_consistent_versioning?
98
+ end
99
+
100
+ with_rails_env("test") do
101
+ refute Webpacker.config.ensure_consistent_versioning?
102
+ end
103
+ end
78
104
  end
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "shakapacker": "6.0.0-beta.1"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "shakapacker": "git://github.com/shakapacker/shakapacker.git"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "shakapacker": "shakapacker/shakapacker#feature\/branch"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "shakapacker": "6.0.0"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "shakapacker": "../shakapacker"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "shakapacker": "^6.0.0"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "shakapacker": "~6.0.0"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "test_app",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "license": "MIT",
6
+ "private": true,
7
+ "dependencies": {
8
+ "left-pad": "1.0.2"
9
+ },
10
+ "devDependencies": {
11
+ "right-pad": "^1.0.1"
12
+ }
13
+ }
data/test/helper_test.rb CHANGED
@@ -14,7 +14,6 @@ class HelperTest < ActionView::TestCase
14
14
  end.new
15
15
 
16
16
  @javascript_pack_tag_loaded = nil
17
- @stylesheet_pack_tag_loaded = nil
18
17
  end
19
18
 
20
19
  def test_asset_pack_path
@@ -149,19 +148,19 @@ class HelperTest < ActionView::TestCase
149
148
  end
150
149
 
151
150
  def hello_stimulus_stylesheet_chunks
152
- %w[/packs/hello_stimulus-k344a6d59eef8632c9d1.chunk.css]
151
+ %w[/packs/1-c20632e7baf2c81200d3.chunk.css /packs/hello_stimulus-k344a6d59eef8632c9d1.chunk.css]
153
152
  end
154
153
 
155
154
  def test_stylesheet_pack_tag
156
155
  assert_equal \
157
- (application_stylesheet_chunks + hello_stimulus_stylesheet_chunks)
156
+ (application_stylesheet_chunks + hello_stimulus_stylesheet_chunks).uniq
158
157
  .map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
159
158
  stylesheet_pack_tag("application", "hello_stimulus")
160
159
  end
161
160
 
162
161
  def test_stylesheet_pack_tag_symbol
163
162
  assert_equal \
164
- (application_stylesheet_chunks + hello_stimulus_stylesheet_chunks)
163
+ (application_stylesheet_chunks + hello_stimulus_stylesheet_chunks).uniq
165
164
  .map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
166
165
  stylesheet_pack_tag(:application, :hello_stimulus)
167
166
  end
@@ -172,15 +171,16 @@ class HelperTest < ActionView::TestCase
172
171
  stylesheet_pack_tag("application", media: "all")
173
172
  end
174
173
 
175
- def test_stylesheet_pack_tag_multiple_invocations
176
- error = assert_raises do
177
- stylesheet_pack_tag(:application)
178
- stylesheet_pack_tag(:hello_stimulus)
179
- end
174
+ def test_stylesheet_pack_tag_multiple_invocations_are_allowed
175
+ app_style = stylesheet_pack_tag(:application)
176
+ stimulus_style = stylesheet_pack_tag(:hello_stimulus)
180
177
 
181
178
  assert_equal \
182
- "To prevent duplicated chunks on the page, you should call stylesheet_pack_tag only once on the page. " +
183
- "Please refer to https://github.com/shakacode/shakapacker/blob/master/README.md#usage for the usage guide",
184
- error.message
179
+ application_stylesheet_chunks.map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
180
+ app_style
181
+
182
+ assert_equal \
183
+ hello_stimulus_stylesheet_chunks.map { |chunk| stylesheet_link_tag(chunk) }.join("\n"),
184
+ stimulus_style
185
185
  end
186
186
  end
@@ -9,6 +9,9 @@ default: &default
9
9
  webpack_compile_output: false
10
10
  webpack_loader: babel
11
11
 
12
+ # Location for manifest.json, defaults to {public_output_path}/manifest.json if unset
13
+ # manifest_path: public/packs/manifest.json
14
+
12
15
  # Additional paths webpack should look up modules
13
16
  # ['app/assets', 'engine/foo/app/assets']
14
17
  additional_paths:
@@ -36,6 +39,7 @@ default: &default
36
39
  development:
37
40
  <<: *default
38
41
  compile: true
42
+ ensure_consistent_versioning: true
39
43
 
40
44
  # Reference: https://webpack.js.org/configuration/dev-server/
41
45
  dev_server:
@@ -0,0 +1,80 @@
1
+ # Note: You must restart bin/webpack-dev-server for changes to take effect
2
+
3
+ default: &default
4
+ source_path: app/packs
5
+ source_entry_path: entrypoints
6
+ public_root_path: public
7
+ public_output_path: packs
8
+ cache_path: tmp/webpacker
9
+ webpack_compile_output: false
10
+
11
+ # Location for manifest.json, defaults to {public_output_path}/manifest.json if unset
12
+ manifest_path: app/packs/manifest.json
13
+
14
+ # Additional paths webpack should look up modules
15
+ # ['app/assets', 'engine/foo/app/assets']
16
+ additional_paths:
17
+ - app/assets
18
+ - /etc/yarn
19
+ - some.config.js
20
+ - app/elm
21
+
22
+ # Reload manifest.json on all requests so we reload latest compiled packs
23
+ cache_manifest: false
24
+
25
+ static_assets_extensions:
26
+ - .jpg
27
+ - .jpeg
28
+ - .png
29
+ - .gif
30
+ - .tiff
31
+ - .ico
32
+ - .svg
33
+
34
+ extensions:
35
+ - .mjs
36
+ - .js
37
+
38
+ development:
39
+ <<: *default
40
+ compile: true
41
+
42
+ # Reference: https://webpack.js.org/configuration/dev-server/
43
+ dev_server:
44
+ https: false
45
+ host: localhost
46
+ port: 3035
47
+ public: localhost:3035
48
+ hmr: false
49
+ overlay: true
50
+ disable_host_check: true
51
+ use_local_ip: false
52
+ pretty: false
53
+
54
+ test:
55
+ <<: *default
56
+ compile: true
57
+
58
+ # Compile test packs to a separate directory
59
+ public_output_path: packs-test
60
+
61
+ production:
62
+ <<: *default
63
+
64
+ # Production depends on precompilation of packs prior to booting for performance.
65
+ compile: false
66
+
67
+ # Cache manifest.json for performance
68
+ cache_manifest: true
69
+
70
+ staging:
71
+ <<: *default
72
+
73
+ # Production depends on precompilation of packs prior to booting for performance.
74
+ compile: false
75
+
76
+ # Cache manifest.json for performance
77
+ cache_manifest: true
78
+
79
+ # Compile staging packs to a separate directory
80
+ public_output_path: packs-staging