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 +4 -4
- data/README.md +63 -54
- data/lib/proscenium/builder.rb +62 -19
- data/lib/proscenium/ensure_loaded.rb +6 -6
- data/lib/proscenium/ext/proscenium +0 -0
- data/lib/proscenium/ext/proscenium.h +16 -1
- data/lib/proscenium/helper.rb +23 -70
- data/lib/proscenium/importer.rb +2 -6
- data/lib/proscenium/libs/react-manager/index.jsx +56 -36
- data/lib/proscenium/log_subscriber.rb +14 -2
- data/lib/proscenium/middleware/esbuild.rb +2 -2
- data/lib/proscenium/monkey.rb +67 -32
- data/lib/proscenium/phlex/asset_inclusions.rb +4 -83
- data/lib/proscenium/phlex.rb +9 -1
- data/lib/proscenium/railtie.rb +21 -16
- data/lib/proscenium/react_componentable.rb +3 -3
- data/lib/proscenium/side_load.rb +120 -6
- data/lib/proscenium/version.rb +1 -1
- data/lib/proscenium/view_component.rb +7 -1
- data/lib/proscenium.rb +10 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7929040e00f84812706b3c5b644cef6b850e2be1a6305a02c4b85e1926e00a67
|
4
|
+
data.tar.gz: '067892643a5fdb9fccddf8312146f8c1c900ef308153fb74bd25277457f2b29c'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
62
|
-
- Migrate from Webpacker
|
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 `
|
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
|
-
<%=
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
207
|
+
import React from "https://esm.sh/react";
|
203
208
|
```
|
204
209
|
|
205
210
|
```css
|
206
|
-
@import
|
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
|
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
|
229
|
+
import utils from "/lib/utils";
|
225
230
|
```
|
226
231
|
|
227
232
|
```js /lib/utils.js
|
228
|
-
import constants from
|
233
|
+
import constants from "./constants";
|
229
234
|
```
|
230
235
|
|
231
236
|
```css /app/views/layouts/application.css
|
232
|
-
@import
|
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
|
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
|
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
|
292
|
-
import startHere from
|
293
|
-
import styles from
|
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
|
300
|
-
@import
|
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:
|
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 ===
|
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
|
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(
|
422
|
+
console.log("one");
|
415
423
|
}
|
416
424
|
function two() {
|
417
|
-
console.log(
|
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
|
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
|
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(
|
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
|
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
|
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
|
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
|
-
>
|
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
|
|
data/lib/proscenium/builder.rb
CHANGED
@@ -18,19 +18,34 @@ module Proscenium
|
|
18
18
|
|
19
19
|
enum :environment, [:development, 1, :test, :production]
|
20
20
|
|
21
|
-
attach_function :
|
22
|
-
:string, #
|
23
|
-
:string, #
|
24
|
-
:string, #
|
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, #
|
32
|
-
:string, #
|
33
|
-
:bool #
|
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.
|
72
|
-
new(root: root, base_url: base_url).
|
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
|
85
|
-
ActiveSupport::Notifications.instrument('
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
-
|
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
|
13
|
-
'not been included in the page. Did you forget
|
14
|
-
'`#
|
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
|
19
|
-
'not been included in the page. Did you forget
|
20
|
-
'`#
|
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
|
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
|
//
|
data/lib/proscenium/helper.rb
CHANGED
@@ -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 =
|
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
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
61
|
-
|
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
|
data/lib/proscenium/importer.rb
CHANGED
@@ -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
|