js-routes 2.2.5 → 2.2.7

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: d0fd81f6f8575bb26353c7e485f0551cc62420a266e22d5503739332b5762037
4
- data.tar.gz: b84d4ad0f70f8e1f454bdd2c6fb8b77a316376b3407a3fd0b6c681d87b87ada9
3
+ metadata.gz: cc558c858345b705d2ca048eaab529acf4d4ffe20299e152f1c23fcbeb31388e
4
+ data.tar.gz: 70dc5ab9c6f629d3236d45a5cf202c6bb8f00893041857f137b9569a3467d48c
5
5
  SHA512:
6
- metadata.gz: 23db2ecfc872d470727b60d7c63148aa15d9d5b76d6eaedbf7bbe5ee964ae5ca5abfb09f69199dd813fcd0b09b12d0920fcb0abf9b09a1bb2a6dbfbaf7884e75
7
- data.tar.gz: faf0d713243b705277604493bdf2f5d9f61c5cd953ef9bcfbcd1f2d88fdfd850d27ed48e0740f0fa4c0f4492a310bec13d6a76fc070113703ab7e7750e812b0c
6
+ metadata.gz: 0536cff5b25734ae0c0399cba8d65fb48503e7038c6e5f7396acb69497505ab8849b109e3348bc2c7a010b073cb3cd4aebed1798c538e8bd0e0270f8949dd53c
7
+ data.tar.gz: 99e9d0487c9062cf3789a8018beba7bcc0b9f985251921cb6f042c20c571d74fab8a4c79f82ad0a6530dde42ee8a678fb5dbfae184dd64e8756ef47d06805b0b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## master
2
2
 
3
+ ## v2.2.7
4
+
5
+ * Fix ESM Tree Shaking [#306](https://github.com/railsware/js-routes/issues/306)
6
+
7
+ ## v2.2.6
8
+
9
+ * Prefer to extend `javascript:build` instead of `assets:precompile`. [#305](https://github.com/railsware/js-routes/issues/305)
10
+ * Add stimulus framework application.js location to generators
3
11
 
4
12
  ## v2.2.5
5
13
 
data/Readme.md CHANGED
@@ -18,7 +18,7 @@ There are several possible ways to setup JsRoutes:
18
18
 
19
19
  * [Quick and easy](#quick-start)
20
20
  * Uses Rack Middleware to automatically update routes locally
21
- * Automatically generates routes files on `assets:precompile` in production
21
+ * Automatically generates routes files on javascript build
22
22
  * Works great for a simple Rails application
23
23
  * [Webpacker ERB Loader](#webpacker)
24
24
  * Requires ESM module system (the default)
@@ -60,12 +60,13 @@ import {post_path} from '../routes';
60
60
  alert(post_path(1))
61
61
  ```
62
62
 
63
- Upgrade `rake assets:precompile` to update js-routes files in `Rakefile`:
63
+ Upgrade js building process to update js-routes files in `Rakefile`:
64
64
 
65
65
  ``` ruby
66
- namespace :assets do
67
- task :precompile => "js:routes:typescript"
68
- end
66
+ task "javascript:build" => "js:routes:typescript"
67
+ # For setups without jsbundling-rails
68
+ task "assets:precompile" => "js:routes:typescript"
69
+
69
70
  ```
70
71
 
71
72
  Add js-routes files to `.gitignore`:
@@ -413,9 +414,14 @@ JsRoutes itself does not have security holes.
413
414
  It makes URLs without access protection more reachable by potential attacker.
414
415
  If that is an issue for you, you may use one of the following solutions:
415
416
 
416
- ### Explicit Import + ESM Tree shaking
417
+ ### ESM Tree shaking
417
418
 
418
- Make sure `module_type` is set to `ESM` (the default) and JS files import only required routes into the file like:
419
+ Make sure `module_type` is set to `ESM` (the default). Modern JS bundlers like
420
+ [Webpack](https://webpack.js.org) can statically determine which ESM exports are used, and remove
421
+ the unused exports to reduce bundle size. This is known as [Tree
422
+ Shaking](https://webpack.js.org/guides/tree-shaking/).
423
+
424
+ JS files can use named imports to import only required routes into the file, like:
419
425
 
420
426
  ``` javascript
421
427
  import {
@@ -427,8 +433,15 @@ import {
427
433
  } from '../routes'
428
434
  ```
429
435
 
430
- Such import structure allows for moddern JS bundlers like [Webpack](https://webpack.js.org/) to only include explicitly imported routes into JS bundle file.
431
- See [Tree Shaking](https://webpack.js.org/guides/tree-shaking/) for more information.
436
+ JS files can also use star imports (`import * as`) for tree shaking, as long as only explicit property accesses are used.
437
+
438
+ ``` javascript
439
+ import * as routes from '../routes';
440
+
441
+ console.log(routes.inbox_path); // OK, only `inbox_path` is included in the bundle
442
+
443
+ console.log(Object.keys(routes)); // forces bundler to include all exports, breaking tree shaking
444
+ ```
432
445
 
433
446
  ### Exclude option
434
447
 
@@ -0,0 +1,16 @@
1
+
2
+ require "rails/generators"
3
+
4
+ class JsRoutes::Generators::Base < Rails::Generators::Base
5
+
6
+ protected
7
+
8
+ def application_js_path
9
+ [
10
+ "app/javascript/packs/application.js",
11
+ "app/javascript/controllers/application.js",
12
+ ].find do |path|
13
+ File.exists?(Rails.root.join(path))
14
+ end
15
+ end
16
+ end
@@ -1,15 +1,17 @@
1
- require "rails/generators"
1
+ require "js_routes/generators/base"
2
2
 
3
- class JsRoutes::Generators::Middleware < Rails::Generators::Base
3
+ class JsRoutes::Generators::Middleware < JsRoutes::Generators::Base
4
4
 
5
5
  source_root File.expand_path(__FILE__ + "/../../../templates")
6
6
 
7
7
  def create_middleware
8
8
  copy_file "initializer.rb", "config/initializers/js_routes.rb"
9
- inject_into_file "app/javascript/packs/application.js", pack_content
10
9
  inject_into_file "config/environments/development.rb", middleware_content, before: /^end\n\z/
11
10
  inject_into_file "Rakefile", rakefile_content
12
11
  inject_into_file ".gitignore", gitignore_content
12
+ if path = application_js_path
13
+ inject_into_file path, pack_content
14
+ end
13
15
  JsRoutes.generate!
14
16
  JsRoutes.definitions!
15
17
  end
@@ -33,12 +35,11 @@ window.Routes = Routes;
33
35
  end
34
36
 
35
37
  def rakefile_content
38
+ enhanced_task = Bundler.load.gems.find {|g| g.name = 'jsbundling-rails'} ?
39
+ "javascript:build" : "assets:precompile"
36
40
  <<-RB
37
-
38
- # Update js-routes file before assets precompile
39
- namespace :assets do
40
- task :precompile => "js:routes:typescript"
41
- end
41
+ # Update js-routes file before javascript build
42
+ task "#{enhanced_task}" => "js:routes:typescript"
42
43
  RB
43
44
  end
44
45
 
@@ -9,7 +9,9 @@ class JsRoutes::Generators::Webpacker < Rails::Generators::Base
9
9
  copy_file "erb.js", "config/webpack/loaders/erb.js"
10
10
  copy_file "routes.js.erb", "app/javascript/routes.js.erb"
11
11
  inject_into_file "config/webpack/environment.js", loader_content
12
- inject_into_file "app/javascript/packs/application.js", pack_content
12
+ if path = application_js_path
13
+ inject_into_file path, pack_content
14
+ end
13
15
  command = Rails.root.join("./bin/yarn add rails-erb-loader")
14
16
  run command
15
17
  end
@@ -33,8 +33,15 @@ module JsRoutes
33
33
  end
34
34
 
35
35
  def body(absolute)
36
- @configuration.dts? ?
37
- definition_body : "__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
36
+ if @configuration.dts?
37
+ definition_body
38
+ else
39
+ # For tree-shaking ESM, add a #__PURE__ comment informing Webpack/minifiers that the call to `__jsr.r`
40
+ # has no side-effects (e.g. modifying global variables) and is safe to remove when unused.
41
+ # https://webpack.js.org/guides/tree-shaking/#clarifying-tree-shaking-and-sideeffects
42
+ pure_comment = @configuration.esm? ? '/*#__PURE__*/ ' : ''
43
+ "#{pure_comment}__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
44
+ end
38
45
  end
39
46
 
40
47
  def definition_body
@@ -1,3 +1,3 @@
1
1
  module JsRoutes
2
- VERSION = "2.2.5"
2
+ VERSION = "2.2.7"
3
3
  end
data/lib/routes.d.ts CHANGED
@@ -32,8 +32,8 @@ declare type RequiredParameters<T extends number> = T extends 1 ? [RequiredRoute
32
32
  RequiredRouteParameter,
33
33
  RequiredRouteParameter
34
34
  ] : RequiredRouteParameter[];
35
- declare type RouteHelperOptions<T extends string> = RouteOptions & Optional<Record<T, OptionalRouteParameter>>;
36
- declare type RouteHelper<T extends number = number, U extends string = string> = ((...args: [...RequiredParameters<T>, RouteHelperOptions<U>]) => string) & RouteHelperExtras;
35
+ declare type RouteHelperOptions = RouteOptions & Record<string, OptionalRouteParameter>;
36
+ declare type RouteHelper<T extends number = number> = ((...args: [...RequiredParameters<T>, RouteHelperOptions]) => string) & RouteHelperExtras;
37
37
  declare type RouteHelpers = Record<string, RouteHelper>;
38
38
  declare type Configuration = {
39
39
  prefix: string;
data/lib/routes.ts CHANGED
@@ -40,11 +40,10 @@ type RequiredParameters<T extends number> = T extends 1
40
40
  ]
41
41
  : RequiredRouteParameter[];
42
42
 
43
- type RouteHelperOptions<T extends string> = RouteOptions &
44
- Optional<Record<T, OptionalRouteParameter>>;
43
+ type RouteHelperOptions = RouteOptions & Record<string, OptionalRouteParameter>;
45
44
 
46
- type RouteHelper<T extends number = number, U extends string = string> = ((
47
- ...args: [...RequiredParameters<T>, RouteHelperOptions<U>]
45
+ type RouteHelper<T extends number = number> = ((
46
+ ...args: [...RequiredParameters<T>, RouteHelperOptions]
48
47
  ) => string) &
49
48
  RouteHelperExtras;
50
49
 
@@ -539,7 +538,7 @@ RubyVariables.WRAPPER(
539
538
  let key: string;
540
539
  switch (route[0]) {
541
540
  case NodeTypes.GROUP:
542
- return "(" + this.build_path_spec(route[1]) + ")";
541
+ return `(${this.build_path_spec(route[1])})`;
543
542
  case NodeTypes.CAT:
544
543
  return (
545
544
  this.build_path_spec(route[1]) + this.build_path_spec(route[2])
@@ -32,8 +32,8 @@ declare type RequiredParameters<T extends number> = T extends 1 ? [RequiredRoute
32
32
  RequiredRouteParameter,
33
33
  RequiredRouteParameter
34
34
  ] : RequiredRouteParameter[];
35
- declare type RouteHelperOptions<T extends string> = RouteOptions & Optional<Record<T, OptionalRouteParameter>>;
36
- declare type RouteHelper<T extends number = number, U extends string = string> = ((...args: [...RequiredParameters<T>, RouteHelperOptions<U>]) => string) & RouteHelperExtras;
35
+ declare type RouteHelperOptions = RouteOptions & Record<string, OptionalRouteParameter>;
36
+ declare type RouteHelper<T extends number = number> = ((...args: [...RequiredParameters<T>, RouteHelperOptions]) => string) & RouteHelperExtras;
37
37
  declare type RouteHelpers = Record<string, RouteHelper>;
38
38
  declare type Configuration = {
39
39
  prefix: string;
@@ -105,7 +105,7 @@ DOC
105
105
  describe "compiled javascript asset" do
106
106
  subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
107
107
  it "should have js routes code" do
108
- is_expected.to include("export const inbox_message_path = __jsr.r(")
108
+ is_expected.to include("export const inbox_message_path = /*#__PURE__*/ __jsr.r(")
109
109
  end
110
110
  end
111
111
  end
@@ -24,7 +24,7 @@ describe JsRoutes, "compatibility with ESM" do
24
24
  * @param {object | undefined} options
25
25
  * @returns {string} route path
26
26
  */
27
- export const inboxes_path = __jsr.r
27
+ export const inboxes_path = /*#__PURE__*/ __jsr.r(
28
28
  DOC
29
29
  end
30
30
 
@@ -39,7 +39,7 @@ DOC
39
39
  describe "compiled javascript asset" do
40
40
  subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
41
41
  it "should have js routes code" do
42
- is_expected.to include("export const inbox_message_path = __jsr.r(")
42
+ is_expected.to include("export const inbox_message_path = /*#__PURE__*/ __jsr.r(")
43
43
  end
44
44
  end
45
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js-routes
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.5
4
+ version: 2.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-08 00:00:00.000000000 Z
11
+ date: 2023-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -167,6 +167,7 @@ files:
167
167
  - lib/js_routes.rb
168
168
  - lib/js_routes/configuration.rb
169
169
  - lib/js_routes/engine.rb
170
+ - lib/js_routes/generators/base.rb
170
171
  - lib/js_routes/generators/middleware.rb
171
172
  - lib/js_routes/generators/webpacker.rb
172
173
  - lib/js_routes/instance.rb
@@ -221,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
222
  - !ruby/object:Gem::Version
222
223
  version: '0'
223
224
  requirements: []
224
- rubygems_version: 3.3.7
225
+ rubygems_version: 3.4.15
225
226
  signing_key:
226
227
  specification_version: 4
227
228
  summary: Brings Rails named routes to javascript