proscenium 0.14.0-x86_64-darwin → 0.15.0.beta.1-x86_64-darwin

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: 7266323f1f1f5120430ed43f1169343d711e61694986e08033c26bb2c50ca61e
4
- data.tar.gz: 32974f861da0870f1a38d5b7e5777988592372447c8a6a48b3a4d954a2765983
3
+ metadata.gz: 7929040e00f84812706b3c5b644cef6b850e2be1a6305a02c4b85e1926e00a67
4
+ data.tar.gz: '067892643a5fdb9fccddf8312146f8c1c900ef308153fb74bd25277457f2b29c'
5
5
  SHA512:
6
- metadata.gz: 6e84a7553307fc8dc133c2afb4b2d3996166159e5c4aee783bb87a45d0ecb09af314f1fde21a356155ad2fa172a10d05f7b47d5581f740dd9466a57497a53ca4
7
- data.tar.gz: 6d0ceac47b5adf44e3f0072f76b2184697329d5aaa9a95ee2fcb306514f8f009bf0838c9931937209039cb72c9ae4f65fb937e3ab1780bcdbebc5ec57db4a332
6
+ metadata.gz: fc3f3b4b1ee7e052f0bd15a5fb4cf3321ad7cb3ab19d694778a67c38ba851543dc03b0599e47f1690382eac3fedf6c4cce76c7e8244f320f38dcd9015a5b2eb4
7
+ data.tar.gz: 1f8892a2bc18ed763437e0981eb0ef43ffdb0fe03d415acbdd2598881bc635c4db603792a9aecfc31fbcd6bf05dd2a4a5e998b5f8eec2338cd7f8e816820d4cb
data/README.md CHANGED
@@ -58,8 +58,8 @@ Getting started obviously depends on whether you are adding Proscenium to an exi
58
58
  - [Getting Started with a new Rails app](https://github.com/joelmoss/proscenium/blob/master/docs/guides/new_rails_app.md)
59
59
  - Getting Started with an existing Rails app
60
60
  - [Migrate from Sprockets](docs/guides/migrate_from_sprockets.md)
61
- - Migrate from Propshaft *[Coming soon]*
62
- - Migrate from Webpacker *[Coming soon]*
61
+ - Migrate from Propshaft _[Coming soon]_
62
+ - Migrate from Webpacker _[Coming soon]_
63
63
  - [Render a React component with Proscenium](docs/guides/basic_react.md)
64
64
 
65
65
  ## Installation
@@ -162,29 +162,34 @@ Your application layout is at `/app/views/layouts/application.hml.erb`, and the
162
162
  - `/app/views/users/index.js`
163
163
  - `/app/views/users/_user.js` (partial)
164
164
 
165
- Now, in your layout and view, replace the `javascript_include_tag` and `stylesheet_link_tag` helpers with the `include_stylesheets` and `include_javascripts` helpers from Proscenium. Something like this:
165
+ Now, in your layout and view, replace the `javascript_include_tag` and `stylesheet_link_tag` helpers with the `include_asset` helper from Proscenium. Something like this:
166
166
 
167
167
  ```erb
168
168
  <!DOCTYPE html>
169
169
  <html>
170
170
  <head>
171
171
  <title>Hello World</title>
172
- <%= include_stylesheets %>
172
+ <%= include_assets # <-- %>
173
173
  </head>
174
174
  <body>
175
175
  <%= yield %>
176
- <%= include_javascripts type: 'module', defer: true %>
177
176
  </body>
178
177
  </html>
179
178
  ```
180
179
 
181
- > NOTE that Proscenium is desiged to work with modern JavaAscript, and assumes [ESModules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) are used everywhere. This is why the `type` attribute is set to `module` in the example above. If you are not using ESModules, then you can omit the `type` attribute.
180
+ On each page request, Proscenium will check if any of your views, layouts and partials have a
181
+ JS/TS/CSS file of the same name, and then include them wherever your placed the `include_assets`
182
+ helper.
182
183
 
183
- On each page request, Proscenium will check if your views, layouts and partials have a JS/TS/CSS file of the same name, and then include them wherever your placed the `include_stylesheets` and `include_javascripts` helpers.
184
+ Now you never have to remember to include your assets again. Just create them alongside your views,
185
+ partials and layouts, and Proscenium will take care of the rest.
184
186
 
185
- Now you never have to remember to include your assets again. Just create them alongside your views, partials and layouts, and Proscenium will take care of the rest.
187
+ Side loading is enabled by default, but you can disable it by setting `config.proscenium.side_load`
188
+ to `false` in your `/config/application.rb`.
186
189
 
187
- Side loading is enabled by default, but you can disable it by setting `config.proscenium.side_load` to `false` in your `/config/application.rb`.
190
+ There are also `include_stylesheets` and `include_javascripts` helpers to allow you to control where
191
+ the CSS and JS assets are included in the HTML. These helpers should be used instead of
192
+ `include_assets` if you want to control exactly where the assets are included.
188
193
 
189
194
  ## Importing Assets
190
195
 
@@ -199,11 +204,11 @@ Imports are assumed to be JS files, so there is no need to specify the file exte
199
204
  Any import beginning with `http://` or `https://` will be fetched from the URL provided. For example:
200
205
 
201
206
  ```js
202
- import React from 'https://esm.sh/react'
207
+ import React from "https://esm.sh/react";
203
208
  ```
204
209
 
205
210
  ```css
206
- @import 'https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css';
211
+ @import "https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css";
207
212
  ```
208
213
 
209
214
  URL imports are cached, so that each import is only fetched once per server restart.
@@ -213,7 +218,7 @@ URL imports are cached, so that each import is only fetched once per server rest
213
218
  Bare imports (imports not beginning with `./`, `/`, `https://`, `http://`) are fully supported, and will use your package manager of choice (eg, NPM, Yarn, pnpm) via the `package.json` file:
214
219
 
215
220
  ```js
216
- import React from 'react'
221
+ import React from "react";
217
222
  ```
218
223
 
219
224
  ### Local Imports
@@ -221,15 +226,15 @@ import React from 'react'
221
226
  And of course you can import your own code, using relative or absolute paths (file extension is optional):
222
227
 
223
228
  ```js /app/views/layouts/application.js
224
- import utils from '/lib/utils'
229
+ import utils from "/lib/utils";
225
230
  ```
226
231
 
227
232
  ```js /lib/utils.js
228
- import constants from './constants'
233
+ import constants from "./constants";
229
234
  ```
230
235
 
231
236
  ```css /app/views/layouts/application.css
232
- @import '/lib/reset';
237
+ @import "/lib/reset";
233
238
  ```
234
239
 
235
240
  ```css /lib/reset.css
@@ -243,7 +248,7 @@ body {
243
248
  Sometimes you don't want to bundle an import. For example, you want to ensure that only one instance of React is loaded. In this cases, you can use the `unbundle` prefix
244
249
 
245
250
  ```js
246
- import React from 'unbundle:react'
251
+ import React from "unbundle:react";
247
252
  ```
248
253
 
249
254
  This only works any bare and local imports.
@@ -261,7 +266,7 @@ You can also use the `unbundle` prefix in your import map, which ensures that al
261
266
  Then just import as normal:
262
267
 
263
268
  ```js
264
- import React from 'react'
269
+ import React from "react";
265
270
  ```
266
271
 
267
272
  ## Import Maps
@@ -280,7 +285,7 @@ Just create `config/import_map.json` and specify the imports you want to use. Fo
280
285
  "react": "https://esm.sh/react@18.2.0",
281
286
  "start": "/lib/start.js",
282
287
  "common": "/lib/common.css",
283
- "@radix-ui/colors/": "https://esm.sh/@radix-ui/colors@0.1.8/",
288
+ "@radix-ui/colors/": "https://esm.sh/@radix-ui/colors@0.1.8/"
284
289
  }
285
290
  }
286
291
  ```
@@ -288,26 +293,29 @@ Just create `config/import_map.json` and specify the imports you want to use. Fo
288
293
  Using the above import map, we can do...
289
294
 
290
295
  ```js
291
- import { useCallback } from 'react'
292
- import startHere from 'start'
293
- import styles from 'common'
296
+ import { useCallback } from "react";
297
+ import startHere from "start";
298
+ import styles from "common";
294
299
  ```
295
300
 
296
301
  and for CSS...
297
302
 
298
303
  ```css
299
- @import 'common';
300
- @import '@radix-ui/colors/blue.css';
304
+ @import "common";
305
+ @import "@radix-ui/colors/blue.css";
301
306
  ```
302
307
 
303
308
  You can also write your import map in JavaScript instead of JSON. So instead of `config/import_map.json`, create `config/import_map.js`, and define an anonymous function. This function accepts a single `environment` argument.
304
309
 
305
310
  ```js
306
- env => ({
311
+ (env) => ({
307
312
  imports: {
308
- react: env === 'development' ? 'https://esm.sh/react@18.2.0?dev' : 'https://esm.sh/react@18.2.0'
309
- }
310
- })
313
+ react:
314
+ env === "development"
315
+ ? "https://esm.sh/react@18.2.0?dev"
316
+ : "https://esm.sh/react@18.2.0",
317
+ },
318
+ });
311
319
  ```
312
320
 
313
321
  ## Source Maps
@@ -344,8 +352,8 @@ This assumes that the environment variable of the same name has already been def
344
352
  These declared environment variables will be replaced with constant expressions, allowing you to use this like this:
345
353
 
346
354
  ```js
347
- console.log(proscenium.env.RAILS_ENV) // console.log("development")
348
- console.log(proscenium.env.RAILS_ENV === 'development') // console.log(true)
355
+ console.log(proscenium.env.RAILS_ENV); // console.log("development")
356
+ console.log(proscenium.env.RAILS_ENV === "development"); // console.log(true)
349
357
  ```
350
358
 
351
359
  The `RAILS_ENV` and `NODE_ENV` environment variables will always automatically be declared for you.
@@ -356,24 +364,24 @@ Environment variables are particularly powerful in aiding [tree shaking](#tree-s
356
364
 
357
365
  ```js
358
366
  function start() {
359
- console.log("start")
367
+ console.log("start");
360
368
  }
361
369
  function doSomethingDangerous() {
362
- console.log("resetDatabase")
370
+ console.log("resetDatabase");
363
371
  }
364
372
 
365
- proscenium.env.RAILS_ENV === "development" && doSomethingDangerous()
373
+ proscenium.env.RAILS_ENV === "development" && doSomethingDangerous();
366
374
 
367
- start()
375
+ start();
368
376
  ```
369
377
 
370
378
  In development the above code will be transformed into the following code, discarding the definition, and call to`doSomethingDangerous()`.
371
379
 
372
380
  ```js
373
381
  function start() {
374
- console.log("start")
382
+ console.log("start");
375
383
  }
376
- start()
384
+ start();
377
385
  ```
378
386
 
379
387
  Please note that for security reasons environment variables are not replaced in URL imports.
@@ -381,7 +389,7 @@ Please note that for security reasons environment variables are not replaced in
381
389
  An undefined environment variable will be replaced with `undefined`.
382
390
 
383
391
  ```js
384
- console.log(proscenium.env.UNKNOWN) // console.log((void 0).UNKNOWN)
392
+ console.log(proscenium.env.UNKNOWN); // console.log((void 0).UNKNOWN)
385
393
  ```
386
394
 
387
395
  This means that code that relies on this will not be tree shaken. You can work around this by using the [optional chaining operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining):
@@ -397,7 +405,7 @@ if (typeof proscenium.env?.UNKNOWN !== "undefined") {
397
405
  Basic support is provided for importing your Rails locale files from `config/locales/*.yml`, exporting them as JSON.
398
406
 
399
407
  ```js
400
- import translations from '@proscenium/i18n'
408
+ import translations from "@proscenium/i18n";
401
409
  // translations.en.*
402
410
  ```
403
411
 
@@ -411,12 +419,12 @@ Tree shaking is the term the JavaScript community uses for dead code elimination
411
419
 
412
420
  ```javascript
413
421
  function one() {
414
- console.log('one')
422
+ console.log("one");
415
423
  }
416
424
  function two() {
417
- console.log('two')
425
+ console.log("two");
418
426
  }
419
- one()
427
+ one();
420
428
  ```
421
429
 
422
430
  The above code will be transformed to the following code, discarding `two()`, as it is never called.
@@ -466,6 +474,7 @@ If these files are side loaded, then `father.js` will be split off into a separa
466
474
  - Without code splitting, an import() expression becomes `Promise.resolve().then(() => require())` instead. This still preserves the asynchronous semantics of the expression but it means the imported code is included in the same bundle instead of being split off into a separate file.
467
475
 
468
476
  Code splitting is enabled by default. You can disable it by setting the `code_splitting` configuration option to `false` in your application's `/config/application.rb`:
477
+
469
478
  ```ruby
470
479
  config.proscenium.code_splitting = false
471
480
  ```
@@ -487,11 +496,11 @@ The new CSS nesting syntax is supported, and transformed into non-nested CSS for
487
496
  You can also import CSS from JavaScript. When you do this, Proscenium will automatically append each stylesheet to the document's head as a `<link>` element.
488
497
 
489
498
  ```jsx
490
- import './button.css'
499
+ import "./button.css";
491
500
 
492
501
  export let Button = ({ text }) => {
493
- return <div className="button">{text}</div>
494
- }
502
+ return <div className="button">{text}</div>;
503
+ };
495
504
  ```
496
505
 
497
506
  ### CSS Modules
@@ -564,7 +573,7 @@ css_module :my_module_name, path: Rails.root.join('app/components/button.css')
564
573
  Importing a CSS module from JS will automatically append the stylesheet to the document's head. And the result of the import will be an object of CSS class to module names.
565
574
 
566
575
  ```js
567
- import styles from './styles.module.css'
576
+ import styles from "./styles.module.css";
568
577
  // styles == { header: 'header-5564cdbb' }
569
578
  ```
570
579
 
@@ -592,7 +601,7 @@ Use a mixin using the `@mixin` at-rule. Pass it the name of the mixin you want t
592
601
  ```css
593
602
  // /app/views/layouts/application.css
594
603
  p {
595
- @mixin bigText from url('/lib/mixins.css');
604
+ @mixin bigText from url("/lib/mixins.css");
596
605
  color: red;
597
606
  }
598
607
  ```
@@ -640,8 +649,8 @@ There are a few important caveats as far as Typescript is concerned. These are [
640
649
  Using JSX syntax usually requires you to manually import the JSX library you are using. For example, if you are using React, by default you will need to import React into each JSX file like this:
641
650
 
642
651
  ```javascript
643
- import * as React from 'react'
644
- render(<div/>)
652
+ import * as React from "react";
653
+ render(<div />);
645
654
  ```
646
655
 
647
656
  This is because the JSX transform turns JSX syntax into a call to `React.createElement` but it does not itself import anything, so the React variable is not automatically present.
@@ -655,15 +664,15 @@ In the [not too distant] future, you will be able to configure Proscenium to use
655
664
  Importing .json files parses the JSON file into a JavaScript object, and exports the object as the default export. Using it looks something like this:
656
665
 
657
666
  ```javascript
658
- import object from './example.json'
659
- console.log(object)
667
+ import object from "./example.json";
668
+ console.log(object);
660
669
  ```
661
670
 
662
671
  In addition to the default export, there are also named exports for each top-level property in the JSON object. Importing a named export directly means Proscenium can automatically remove unused parts of the JSON file from the bundle, leaving only the named exports that you actually used. For example, this code will only include the version field when bundled:
663
672
 
664
673
  ```javascript
665
- import { version } from './package.json'
666
- console.log(version)
674
+ import { version } from "./package.json";
675
+ console.log(version);
667
676
  ```
668
677
 
669
678
  ## Phlex Support
@@ -682,14 +691,14 @@ In your layouts, include `Proscenium::Phlex::AssetInclusions`, and call the `inc
682
691
 
683
692
  ```ruby
684
693
  class ApplicationLayout < Proscenium::Phlex
685
- include Proscenium::Phlex::AssetInclusions
694
+ include Proscenium::Phlex::AssetInclusions # <--
686
695
 
687
696
  def template(&)
688
697
  doctype
689
698
  html do
690
699
  head do
691
700
  title { 'My Awesome App' }
692
- include_assets
701
+ include_assets # <--
693
702
  end
694
703
  body(&)
695
704
  end
@@ -798,7 +807,7 @@ The view above will be rendered something like this:
798
807
 
799
808
  ## Cache Busting
800
809
 
801
- > *COMING SOON*
810
+ > _COMING SOON_
802
811
 
803
812
  By default, all assets are not cached by the browser. But if in production, you populate the `REVISION` env variable, all CSS and JS URL's will be appended with its value as a query string, and the `Cache-Control` response header will be set to `public` and a max-age of 30 days.
804
813
 
@@ -18,19 +18,34 @@ module Proscenium
18
18
 
19
19
  enum :environment, [:development, 1, :test, :production]
20
20
 
21
- attach_function :build, [
22
- :string, # path or entry point. multiple can be given by separating with a semi-colon
23
- :string, # base URL of the Rails app. eg. https://example.com
24
- :string, # path to import map, relative to root
21
+ attach_function :build_to_string, [
22
+ :string, # Path or entry point.
23
+ :string, # Base URL of the Rails app. eg. https://example.com
24
+ :string, # Path to import map, relative to root
25
25
  :string, # ENV variables as a JSON string
26
26
 
27
27
  # Config
28
28
  :string, # Rails application root
29
29
  :string, # Proscenium gem root
30
30
  :environment, # Rails environment as a Symbol
31
- :bool, # code splitting enabled?
32
- :string, # engine names and paths as a JSON string
33
- :bool # debugging enabled?
31
+ :bool, # Code splitting enabled?
32
+ :string, # Engine names and paths as a JSON string
33
+ :bool # Debugging enabled?
34
+ ], Result.by_value
35
+
36
+ attach_function :build_to_path, [
37
+ :string, # Path or entry point. Multiple can be given by separating with a semi-colon
38
+ :string, # Base URL of the Rails app. eg. https://example.com
39
+ :string, # Path to import map, relative to root
40
+ :string, # ENV variables as a JSON string
41
+
42
+ # Config
43
+ :string, # Rails application root
44
+ :string, # Proscenium gem root
45
+ :environment, # Rails environment as a Symbol
46
+ :bool, # Code splitting enabled?
47
+ :string, # Engine names and paths as a JSON string
48
+ :bool # Debugging enabled?
34
49
  ], Result.by_value
35
50
 
36
51
  attach_function :resolve, [
@@ -68,8 +83,12 @@ module Proscenium
68
83
  end
69
84
  end
70
85
 
71
- def self.build(path, root: nil, base_url: nil)
72
- new(root: root, base_url: base_url).build(path)
86
+ def self.build_to_path(path, root: nil, base_url: nil)
87
+ new(root: root, base_url: base_url).build_to_path(path)
88
+ end
89
+
90
+ def self.build_to_string(path, root: nil, base_url: nil)
91
+ new(root: root, base_url: base_url).build_to_string(path)
73
92
  end
74
93
 
75
94
  def self.resolve(path, root: nil)
@@ -81,15 +100,35 @@ module Proscenium
81
100
  @base_url = base_url
82
101
  end
83
102
 
84
- def build(path) # rubocop:disable Metrics/AbcSize
85
- ActiveSupport::Notifications.instrument('build.proscenium', identifier: path) do
86
- result = Request.build(path, @base_url, import_map, env_vars.to_json,
87
- @root.to_s,
88
- Pathname.new(__dir__).join('..', '..').to_s,
89
- Rails.env.to_sym,
90
- Proscenium.config.code_splitting,
91
- engines.to_json,
92
- Proscenium.config.debug)
103
+ def build_to_path(path) # rubocop:disable Metrics/AbcSize
104
+ ActiveSupport::Notifications.instrument('build_to_path.proscenium',
105
+ identifier: path,
106
+ cached: Proscenium.cache.exist?(path)) do
107
+ Proscenium.cache.fetch path do
108
+ result = Request.build_to_path(path, @base_url, import_map, env_vars.to_json,
109
+ @root.to_s,
110
+ gem_root,
111
+ Rails.env.to_sym,
112
+ Proscenium.config.code_splitting,
113
+ engines.to_json,
114
+ Proscenium.config.debug)
115
+
116
+ raise BuildError, result[:response] unless result[:success]
117
+
118
+ result[:response]
119
+ end
120
+ end
121
+ end
122
+
123
+ def build_to_string(path)
124
+ ActiveSupport::Notifications.instrument('build_to_string.proscenium', identifier: path) do
125
+ result = Request.build_to_string(path, @base_url, import_map, env_vars.to_json,
126
+ @root.to_s,
127
+ gem_root,
128
+ Rails.env.to_sym,
129
+ Proscenium.config.code_splitting,
130
+ engines.to_json,
131
+ Proscenium.config.debug)
93
132
 
94
133
  raise BuildError, result[:response] unless result[:success]
95
134
 
@@ -100,7 +139,7 @@ module Proscenium
100
139
  def resolve(path)
101
140
  ActiveSupport::Notifications.instrument('resolve.proscenium', identifier: path) do
102
141
  result = Request.resolve(path, import_map, @root.to_s,
103
- Pathname.new(__dir__).join('..', '..').to_s,
142
+ gem_root,
104
143
  Rails.env.to_sym,
105
144
  Proscenium.config.debug)
106
145
  raise ResolveError.new(path, result[:response]) unless result[:success]
@@ -140,5 +179,9 @@ module Proscenium
140
179
 
141
180
  nil
142
181
  end
182
+
183
+ def gem_root
184
+ Pathname.new(__dir__).join('..', '..').to_s
185
+ end
143
186
  end
144
187
  end
@@ -9,15 +9,15 @@ module Proscenium
9
9
  append_after_action do
10
10
  if request.format.html? && Importer.imported?
11
11
  if Importer.js_imported?
12
- raise NotIncludedError, 'There are javascripts to be included, but they have ' \
13
- 'not been included in the page. Did you forget to add the ' \
14
- '`#include_javascripts` helper in your views?'
12
+ raise NotIncludedError, 'There are side loaded javascripts to be included, but ' \
13
+ 'they have not been included in the page. Did you forget ' \
14
+ 'to add the `#include_assets` helper in your views?'
15
15
  end
16
16
 
17
17
  if Importer.css_imported?
18
- raise NotIncludedError, 'There are stylesheets to be included, but they have ' \
19
- 'not been included in the page. Did you forget to add the ' \
20
- '`#include_stylesheets` helper in your views?'
18
+ raise NotIncludedError, 'There are side loaded stylesheets to be included, but ' \
19
+ 'they have not been included in the page. Did you forget ' \
20
+ 'to add the `#include_assets` helper in your views?'
21
21
  end
22
22
  end
23
23
  end
Binary file
@@ -83,6 +83,21 @@ extern "C" {
83
83
  #endif
84
84
 
85
85
 
86
+ // Build the given `path` in the `root`.
87
+ //
88
+ // BuildOptions
89
+ // - path - The path to build relative to `root`.
90
+ // - baseUrl - base URL of the Rails app. eg. https://example.com
91
+ // - importMap - Path to the import map relative to `root`.
92
+ // - envVars - JSON string of environment variables.
93
+ // Config:
94
+ // - root - The working directory.
95
+ // - env - The environment (1 = development, 2 = test, 3 = production)
96
+ // - codeSpitting?
97
+ // - debug?
98
+ //
99
+ extern struct Result build_to_string(char* filepath, char* baseUrl, char* importMap, char* envVars, char* appRoot, char* gemPath, unsigned int env, GoUint8 codeSplitting, char* engines, GoUint8 debug);
100
+
86
101
  // Build the given `path` in the `root`.
87
102
  //
88
103
  // BuildOptions
@@ -97,7 +112,7 @@ extern "C" {
97
112
  // - codeSpitting?
98
113
  // - debug?
99
114
  //
100
- extern struct Result build(char* filepath, char* baseUrl, char* importMap, char* envVars, char* appRoot, char* gemPath, unsigned int env, GoUint8 codeSplitting, char* engines, GoUint8 debug);
115
+ extern struct Result build_to_path(char* filepath, char* baseUrl, char* importMap, char* envVars, char* appRoot, char* gemPath, unsigned int env, GoUint8 codeSplitting, char* engines, GoUint8 debug);
101
116
 
102
117
  // Resolve the given `path` relative to the `root`.
103
118
  //
@@ -2,15 +2,23 @@
2
2
 
3
3
  module Proscenium
4
4
  module Helper
5
+ def sideload_assets(value)
6
+ if value.nil?
7
+ @current_template.instance_variable_defined?(:@sideload_assets_options) &&
8
+ @current_template.remove_instance_variable(:@sideload_assets_options)
9
+ else
10
+ @current_template.instance_variable_set :@sideload_assets_options, value
11
+ end
12
+ end
13
+
14
+ # Overriden to allow regular use of javascript_include_tag and stylesheet_link_tag, while still
15
+ # building with Proscenium. It's important to note that `include_assets` will not call this, as
16
+ # those asset paths all begin with a slash, which the Rails asset helpers do not pass through to
17
+ # here.
5
18
  def compute_asset_path(path, options = {})
6
19
  if %i[javascript stylesheet].include?(options[:type])
7
- result = "/#{path}"
8
-
9
- if (qs = Proscenium.config.cache_query_string)
10
- result << "?#{qs}"
11
- end
12
-
13
- return result
20
+ result = Proscenium::Builder.build_to_path(path, base_url: request.base_url)
21
+ return result.split('::').last.delete_prefix 'public'
14
22
  end
15
23
 
16
24
  super
@@ -40,78 +48,23 @@ module Proscenium
40
48
  CssModule::Transformer.new(path).class_names(*names).map { |name, _| name }.join(' ')
41
49
  end
42
50
 
43
- def include_stylesheets(**options)
44
- out = []
45
- Importer.each_stylesheet(delete: true) do |path, _path_options|
46
- out << stylesheet_link_tag(path, extname: false, **options)
47
- end
48
- out.join("\n").html_safe
51
+ def include_assets
52
+ include_stylesheets + include_javascripts
53
+ end
54
+
55
+ def include_stylesheets
56
+ '<!-- [PROSCENIUM_STYLESHEETS] -->'.html_safe
49
57
  end
50
58
  alias side_load_stylesheets include_stylesheets
51
59
  deprecate side_load_stylesheets: 'Use `include_stylesheets` instead', deprecator: Deprecator.new
52
60
 
53
61
  # Includes all javascripts that have been imported and side loaded.
54
62
  #
55
- # @param extract_lazy_scripts [Boolean] if true, any lazy scripts will be extracted using
56
- # `content_for` to `:proscenium_lazy_scripts` for later use. Be sure to include this in your
57
- # page with the `declare_lazy_scripts` helper, or simply
58
- # `content_for :proscenium_lazy_scripts`.
59
63
  # @return [String] the HTML tags for the javascripts.
60
- def include_javascripts(extract_lazy_scripts: false, **options) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
61
- out = []
62
-
63
- if Rails.application.config.proscenium.code_splitting && Importer.multiple_js_imported?
64
- imports = Importer.imported.dup
65
-
66
- paths_to_build = []
67
- Importer.each_javascript(delete: true) do |x, _|
68
- paths_to_build << x.delete_prefix('/')
69
- end
70
-
71
- result = Builder.build(paths_to_build.join(';'), base_url: request.base_url)
72
-
73
- # Remove the react components from the results, so they are not side loaded. Instead they
74
- # are lazy loaded by the component manager.
75
-
76
- scripts = {}
77
- result.split(';').each do |x|
78
- inpath, outpath = x.split('::')
79
- inpath.prepend '/'
80
- outpath.delete_prefix! 'public'
81
-
82
- next unless imports.key?(inpath)
83
-
84
- if (import = imports[inpath]).delete(:lazy)
85
- scripts[inpath] = import.merge(outpath: outpath)
86
- else
87
- out << javascript_include_tag(outpath, extname: false, **options)
88
- end
89
- end
90
-
91
- if extract_lazy_scripts
92
- content_for :proscenium_lazy_scripts do
93
- tag.script type: 'application/json', id: 'prosceniumLazyScripts' do
94
- raw scripts.to_json
95
- end
96
- end
97
- else
98
- out << tag.script(type: 'application/json', id: 'prosceniumLazyScripts') do
99
- raw scripts.to_json
100
- end
101
- end
102
- else
103
- Importer.each_javascript(delete: true) do |path, _|
104
- out << javascript_include_tag(path, extname: false, **options)
105
- end
106
- end
107
-
108
- out.join("\n").html_safe
64
+ def include_javascripts
65
+ '<!-- [PROSCENIUM_LAZY_SCRIPTS] --><!-- [PROSCENIUM_JAVASCRIPTS] -->'.html_safe
109
66
  end
110
67
  alias side_load_javascripts include_javascripts
111
68
  deprecate side_load_javascripts: 'Use `include_javascripts` instead', deprecator: Deprecator.new
112
-
113
- def declare_lazy_scripts
114
- content_for :proscenium_lazy_scripts
115
- end
116
69
  end
117
70
  end
@@ -72,8 +72,8 @@ module Proscenium
72
72
  end
73
73
  end
74
74
 
75
- JS_EXTENSIONS.find(&import_if_exists)
76
- CSS_EXTENSIONS.find(&import_if_exists)
75
+ JS_EXTENSIONS.find(&import_if_exists) unless options[:js] == false
76
+ CSS_EXTENSIONS.find(&import_if_exists) unless options[:css] == false
77
77
  end
78
78
 
79
79
  def each_stylesheet(delete: false)
@@ -109,10 +109,6 @@ module Proscenium
109
109
  imported&.keys&.any? { |x| x.end_with?(*JS_EXTENSIONS) }
110
110
  end
111
111
 
112
- def multiple_js_imported?
113
- imported&.keys&.many? { |x| x.end_with?(*JS_EXTENSIONS) }
114
- end
115
-
116
112
  def imported?(filepath = nil)
117
113
  filepath ? imported&.key?(filepath) : !imported.blank?
118
114
  end