humid 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +85 -58
- data/lib/humid/version.rb +1 -1
- data/lib/humid.rb +22 -35
- metadata +6 -82
- data/spec/controller_runtime_spec.rb +0 -79
- data/spec/log_subscriber_spec.rb +0 -54
- data/spec/render_spec.rb +0 -162
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8422854ba8184e3afc75af501ec45002304538e9f756ea3ee3bdd58b15d98de
|
4
|
+
data.tar.gz: 8e8025cba53a2ed0e54aecb85701bcb65a7d39798f241ef4e5d3aeea391367aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 404f369b35a24b2b313bf2a5d572746b1d4262df0b5ee4988f69540a878502045d046279714432d77b367366e98031818f6c3f3c26747f67e916581335b4004f
|
7
|
+
data.tar.gz: 38feb90293fd0340155314e6300e5a3ff70a8ee5f2d2e7fb081c0bf89ea8b7826a7297d52b15888d05f447ff64738da454cc4ede07ff9a152236ae7318fd5380
|
data/README.md
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# Humid
|
2
|
-
[](https://circleci.com/gh/thoughtbot/humid)
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+

|
4
|
+
|
5
|
+
Humid is a lightweight wrapper around [mini_racer] used to generate Server
|
6
|
+
Side Rendered (SSR) pages from your js-bundling builds. While it was built
|
7
|
+
for React, it can work with any JS function that returns a HTML string.
|
9
8
|
|
10
9
|
## Caution
|
11
10
|
|
@@ -34,20 +33,31 @@ Add an initializer to configure
|
|
34
33
|
|
35
34
|
```ruby
|
36
35
|
Humid.configure do |config|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
#
|
36
|
+
# Path to your build file located in `app/assets/build/`. You should use a
|
37
|
+
# separate build apart from your `application.js`.
|
38
|
+
# Required
|
39
|
+
config.application_path = "app/assets/build/server_rendering.js"
|
40
|
+
|
41
|
+
# Path to your source map file
|
42
|
+
# Optional
|
43
|
+
config.source_map_path = "app/assets/build/server_rendering.js.map"
|
44
|
+
|
45
|
+
# Raise errors if JS rendering failed. If false, the error will be
|
46
|
+
# logged out to Rails log and Humid.render will return an empty string
|
47
|
+
#
|
48
|
+
# Defaults to true.
|
49
|
+
config.raise_render_errors = Rails.env.development? || Rails.env.test?
|
50
|
+
|
51
|
+
# The logger instance.
|
44
52
|
# `console.log` and friends (`warn`, `error`) are delegated to
|
45
53
|
# the respective logger levels on the ruby side.
|
54
|
+
#
|
55
|
+
# Defaults to `Logger.new(STDOUT)`
|
46
56
|
config.logger = Rails.logger
|
47
57
|
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
58
|
+
# Options passed to mini_racer.
|
59
|
+
#
|
60
|
+
# Defaults to empty `{}`.
|
51
61
|
config.context_options = {
|
52
62
|
timeout: 1000,
|
53
63
|
ensure_gc_after_idle: 2000
|
@@ -55,16 +65,18 @@ Humid.configure do |config|
|
|
55
65
|
end
|
56
66
|
|
57
67
|
# Common development options
|
58
|
-
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
#
|
68
|
+
if Rails.env.development? || Rails.env.test?
|
69
|
+
# Use single_threaded mode for Spring and other forked envs.
|
70
|
+
MiniRacer::Platform.set_flags! :single_threaded
|
71
|
+
|
72
|
+
# If you're using Puma in single mode:
|
73
|
+
Humid.create_context
|
74
|
+
end
|
63
75
|
```
|
64
76
|
|
65
77
|
If you'd like support for source map support, you will need to
|
66
|
-
1.
|
67
|
-
2.
|
78
|
+
1. Add the following to your entry file, e.g, `server_rendering.js`.
|
79
|
+
2. set `config.source_map_path`.
|
68
80
|
|
69
81
|
```javascript
|
70
82
|
require("source-map-support").install({
|
@@ -76,6 +88,7 @@ require("source-map-support").install({
|
|
76
88
|
}
|
77
89
|
});
|
78
90
|
```
|
91
|
+
A [sample] webpack.config is available for reference.
|
79
92
|
|
80
93
|
## The mini_racer environment.
|
81
94
|
|
@@ -95,46 +108,17 @@ The following functions are **not** available in the mini_racer environment
|
|
95
108
|
`console.log` and friends (`info`, `error`, `warn`) are delegated to the
|
96
109
|
respective methods on the configured logger.
|
97
110
|
|
98
|
-
### Webpacker
|
99
|
-
You may need webpacker to create aliases for server friendly libraries that can
|
100
|
-
not detect the `mini_racer` environment.
|
101
|
-
|
102
|
-
```diff
|
103
|
-
// config/webpack/development.js
|
104
|
-
|
105
|
-
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
|
106
|
-
|
107
|
-
const environment = require('./environment')
|
108
|
-
+const path = require('path')
|
109
|
-
+const ConfigObject = require('@rails/webpacker/package/config_types/config
|
110
|
-
|
111
|
-
-module.exports = environment.toWebpackConfig()
|
112
|
-
+const webConfig = environment.toWebpackConfig()
|
113
|
-
+const ssrConfig = new ConfigObject(webConfig.toObject())
|
114
|
-
+
|
115
|
-
+ssrConfig.delete('entry')
|
116
|
-
+ssrConfig.merge({
|
117
|
-
+ entry: {
|
118
|
-
+ server_rendering: webConfig.entry.server_rendering
|
119
|
-
+ },
|
120
|
-
+ resolve: {
|
121
|
-
+ alias: {
|
122
|
-
+ 'html-dom-parser': path.resolve(__dirname, '../../node_modules/html-dom-parser/lib/html-to-dom-server')
|
123
|
-
+ }
|
124
|
-
+ }
|
125
|
-
+})
|
126
|
-
+
|
127
|
-
+delete webConfig.entry.server_rendering
|
128
|
-
+module.exports = [ssrConfig, webConfig]
|
129
|
-
```
|
130
|
-
|
131
111
|
## Usage
|
132
112
|
|
133
|
-
|
113
|
+
In your entry file, e.g, `server_rendering.js`, pass your HTML render function
|
114
|
+
to `setHumidRenderer`. There is no need to require the function.
|
134
115
|
|
135
116
|
```javascript
|
117
|
+
// Set a factory function that will create a new instance of our app
|
118
|
+
// for each request.
|
136
119
|
setHumidRenderer((json) => {
|
137
120
|
const initialState = JSON.parse(json)
|
121
|
+
|
138
122
|
return ReactDOMServer.renderToString(
|
139
123
|
<Application initialPage={initialState}/>
|
140
124
|
)
|
@@ -169,6 +153,48 @@ on_worker_shutdown do
|
|
169
153
|
end
|
170
154
|
```
|
171
155
|
|
156
|
+
### Server-side libraries that detect node.js envs.
|
157
|
+
You may need webpacker to create aliases for server friendly libraries that can
|
158
|
+
not detect the `mini_racer` environment. For example, in your `webpack.config.js`.
|
159
|
+
|
160
|
+
```diff
|
161
|
+
...
|
162
|
+
resolve: {
|
163
|
+
alias: {
|
164
|
+
'html-dom-parser': path.resolve(__dirname, '../../node_modules/html-dom-parser/lib/html-to-dom-server')
|
165
|
+
}
|
166
|
+
}
|
167
|
+
...
|
168
|
+
```
|
169
|
+
|
170
|
+
## Writing universal code
|
171
|
+
[Vue has a resource][vue_ssr] on how to write universal code. Below
|
172
|
+
are a few highlights that are important to keep in mind.
|
173
|
+
|
174
|
+
### State
|
175
|
+
|
176
|
+
Humid uses a single context across multiple request. To avoid state pollution, we
|
177
|
+
provide a factory function to `setHumidRenderer` that builds a new app instance on
|
178
|
+
every call.
|
179
|
+
|
180
|
+
This provides better isolation, but as it is still a shared context, polluting
|
181
|
+
`global` is still possible. Be careful of modifying `global` in your code.
|
182
|
+
|
183
|
+
### Polyfills
|
184
|
+
|
185
|
+
Polyfills will fail when using in the `mini_racer` environment because of missing
|
186
|
+
browser APIs. Account for this by moving the `require` to `componentDidMount`
|
187
|
+
in your component.
|
188
|
+
|
189
|
+
```
|
190
|
+
componentDidMount() {
|
191
|
+
const dialogPolyfill = require('dialog-polyfill').default
|
192
|
+
dialogPolyfill.registerDialog(this.dialog.current)
|
193
|
+
this.dialog.current.open = this.props.open
|
194
|
+
this.dialog.current.showModal()
|
195
|
+
}
|
196
|
+
```
|
197
|
+
|
172
198
|
## Contributing
|
173
199
|
|
174
200
|
Please see [CONTRIBUTING.md](/CONTRIBUTING.md).
|
@@ -193,4 +219,5 @@ See [our other projects][community] or
|
|
193
219
|
[community]: https://thoughtbot.com/community?utm_source=github
|
194
220
|
[hire]: https://thoughtbot.com?utm_source=github
|
195
221
|
[mini_racer]: https://github.com/rubyjs/mini_racer
|
196
|
-
[
|
222
|
+
[vue_ssr]: https://ssr.vuejs.org/
|
223
|
+
[sample]: ./webpack.config.js
|
data/lib/humid/version.rb
CHANGED
data/lib/humid.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "mini_racer"
|
2
2
|
require "logger"
|
3
|
-
require "webpacker"
|
4
3
|
require "active_support"
|
5
4
|
require "active_support/core_ext"
|
6
5
|
require "humid/log_subscriber"
|
@@ -14,16 +13,20 @@ module Humid
|
|
14
13
|
class RenderError < StandardError
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
"server_rendering.js"
|
16
|
+
class FileNotFound < StandardError
|
19
17
|
end
|
20
18
|
|
21
|
-
|
22
|
-
|
19
|
+
@@context = nil
|
20
|
+
|
21
|
+
config_accessor :application_path
|
22
|
+
config_accessor :source_map_path
|
23
|
+
|
24
|
+
config_accessor :raise_render_errors do
|
25
|
+
true
|
23
26
|
end
|
24
27
|
|
25
28
|
config_accessor :logger do
|
26
|
-
Logger.new(
|
29
|
+
Logger.new($stdout)
|
27
30
|
end
|
28
31
|
|
29
32
|
config_accessor :context_options do
|
@@ -54,27 +57,7 @@ module Humid
|
|
54
57
|
JS
|
55
58
|
end
|
56
59
|
|
57
|
-
def handle_stale_files
|
58
|
-
if Webpacker.compiler.stale?
|
59
|
-
Webpacker.compiler.compile
|
60
|
-
end
|
61
|
-
|
62
|
-
public_path = Webpacker.config.public_path
|
63
|
-
server_rendering_file = config.server_rendering_file
|
64
|
-
source_path = public_path.join(Webpacker.manifest.lookup(server_rendering_file)[1..-1])
|
65
|
-
filename = File.basename(source_path.to_s)
|
66
|
-
|
67
|
-
if @@current_filename != filename
|
68
|
-
dispose
|
69
|
-
create_context
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
60
|
def context
|
74
|
-
if @@context && Webpacker.env.development?
|
75
|
-
handle_stale_files
|
76
|
-
end
|
77
|
-
|
78
61
|
@@context
|
79
62
|
end
|
80
63
|
|
@@ -86,7 +69,7 @@ module Humid
|
|
86
69
|
end
|
87
70
|
|
88
71
|
def create_context
|
89
|
-
ctx = MiniRacer::Context.new(config.context_options)
|
72
|
+
ctx = MiniRacer::Context.new(**config.context_options)
|
90
73
|
ctx.attach("console.log", proc { |err| logger.debug(err.to_s) })
|
91
74
|
ctx.attach("console.info", proc { |err| logger.info(err.to_s) })
|
92
75
|
ctx.attach("console.error", proc { |err| logger.error(err.to_s) })
|
@@ -97,13 +80,10 @@ module Humid
|
|
97
80
|
js << renderer
|
98
81
|
ctx.eval(js)
|
99
82
|
|
100
|
-
|
101
|
-
|
102
|
-
server_rendering_map = "#{config.server_rendering_file}.map"
|
83
|
+
source_path = config.application_path
|
84
|
+
map_path = config.source_map_path
|
103
85
|
|
104
|
-
|
105
|
-
map_path = public_path.join(Webpacker.manifest.lookup(server_rendering_map)[1..-1])
|
106
|
-
if config.use_source_map
|
86
|
+
if map_path
|
107
87
|
ctx.attach("readSourceMap", proc { File.read(map_path) })
|
108
88
|
end
|
109
89
|
|
@@ -118,8 +98,15 @@ module Humid
|
|
118
98
|
ActiveSupport::Notifications.instrument("render.humid") do
|
119
99
|
context.call("__renderer", *args)
|
120
100
|
rescue MiniRacer::RuntimeError => e
|
121
|
-
message = ([e.message] + e.backtrace.filter {|x| x.starts_with? "JavaScript"}).join("\n")
|
122
|
-
|
101
|
+
message = ([e.message] + e.backtrace.filter { |x| x.starts_with? "JavaScript" }).join("\n")
|
102
|
+
render_error = Humid::RenderError.new(message)
|
103
|
+
|
104
|
+
if config.raise_render_errors
|
105
|
+
raise render_error
|
106
|
+
else
|
107
|
+
config.logger.error(render_error.inspect)
|
108
|
+
""
|
109
|
+
end
|
123
110
|
end
|
124
111
|
end
|
125
112
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: humid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johny Ho
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: webpacker
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '4.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '4.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: mini_racer
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,70 +30,14 @@ dependencies:
|
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
33
|
+
version: '7.0'
|
48
34
|
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
38
|
- - ">="
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rake
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '12.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '12.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '3.8'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '3.8'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: byebug
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '9.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '9.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rails
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '6.0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '6.0'
|
40
|
+
version: '7.0'
|
111
41
|
description: Javascript SSR rendering for Rails
|
112
42
|
email: jho406@gmail.com
|
113
43
|
executables: []
|
@@ -119,9 +49,6 @@ files:
|
|
119
49
|
- lib/humid/controller_runtime.rb
|
120
50
|
- lib/humid/log_subscriber.rb
|
121
51
|
- lib/humid/version.rb
|
122
|
-
- spec/controller_runtime_spec.rb
|
123
|
-
- spec/log_subscriber_spec.rb
|
124
|
-
- spec/render_spec.rb
|
125
52
|
homepage: https://github.com/thoughtbot/humid/
|
126
53
|
licenses:
|
127
54
|
- MIT
|
@@ -141,11 +68,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
68
|
- !ruby/object:Gem::Version
|
142
69
|
version: '0'
|
143
70
|
requirements: []
|
144
|
-
rubygems_version: 3.
|
71
|
+
rubygems_version: 3.4.6
|
145
72
|
signing_key:
|
146
73
|
specification_version: 4
|
147
74
|
summary: Javascript SSR rendering for Rails
|
148
|
-
test_files:
|
149
|
-
- spec/render_spec.rb
|
150
|
-
- spec/log_subscriber_spec.rb
|
151
|
-
- spec/controller_runtime_spec.rb
|
75
|
+
test_files: []
|
@@ -1,79 +0,0 @@
|
|
1
|
-
require_relative "./support/helper"
|
2
|
-
|
3
|
-
describe Humid::ControllerRuntime do
|
4
|
-
controller_runtime = Humid::ControllerRuntime
|
5
|
-
|
6
|
-
def set_metric value
|
7
|
-
Humid::LogSubscriber.runtime = value
|
8
|
-
end
|
9
|
-
|
10
|
-
def clear_metric!
|
11
|
-
Humid::LogSubscriber.reset_runtime = 0
|
12
|
-
end
|
13
|
-
|
14
|
-
reference_controller_class = Class.new {
|
15
|
-
def process_action *_
|
16
|
-
@process_action = true
|
17
|
-
end
|
18
|
-
|
19
|
-
def cleanup_view_runtime *_
|
20
|
-
@cleanup_view_runtime.call
|
21
|
-
end
|
22
|
-
|
23
|
-
def append_info_to_payload *_
|
24
|
-
@append_info_to_payload = true
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.log_process_action *_
|
28
|
-
@log_process_action.call
|
29
|
-
end
|
30
|
-
}
|
31
|
-
|
32
|
-
controller_class = Class.new reference_controller_class do
|
33
|
-
include controller_runtime
|
34
|
-
|
35
|
-
def logger
|
36
|
-
Logger.new(STDOUT)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
let(:controller) { controller_class.new }
|
41
|
-
|
42
|
-
it "resets the metric before each action" do
|
43
|
-
set_metric 42
|
44
|
-
controller.send(:process_action, "foo")
|
45
|
-
expect(Humid::LogSubscriber.runtime).to be(0)
|
46
|
-
expect(controller.instance_variable_get("@process_action")).to be(true)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "strips the metric of other sources of the runtime" do
|
50
|
-
set_metric 1
|
51
|
-
controller.instance_variable_set "@cleanup_view_runtime", -> {
|
52
|
-
controller.instance_variable_set "@cleanup_view_runtime", true
|
53
|
-
set_metric 13
|
54
|
-
42
|
55
|
-
}
|
56
|
-
returned = controller.send :cleanup_view_runtime
|
57
|
-
expect(controller.instance_variable_get("@cleanup_view_runtime")).to be(true)
|
58
|
-
expect(controller.humid_runtime).to eq(14)
|
59
|
-
expect(returned).to be(29)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "appends the metric to payload" do
|
63
|
-
payload = {}
|
64
|
-
set_metric 42
|
65
|
-
controller.send :append_info_to_payload, payload
|
66
|
-
expect(controller.instance_variable_get("@append_info_to_payload")).to be(true)
|
67
|
-
expect(payload[:humid_runtime]).to eq(42)
|
68
|
-
end
|
69
|
-
|
70
|
-
it "adds metric to log message" do
|
71
|
-
controller_class.instance_variable_set "@log_process_action", -> {
|
72
|
-
controller_class.instance_variable_set "@log_process_action", true
|
73
|
-
[]
|
74
|
-
}
|
75
|
-
messages = controller_class.log_process_action humid_runtime: 42.101
|
76
|
-
expect(controller_class.instance_variable_get("@log_process_action")).to be(true)
|
77
|
-
expect(messages).to eq(["Humid SSR: 42.1ms"])
|
78
|
-
end
|
79
|
-
end
|
data/spec/log_subscriber_spec.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
require_relative "./support/helper"
|
2
|
-
require "active_support/log_subscriber/test_helper"
|
3
|
-
require "byebug"
|
4
|
-
|
5
|
-
RSpec.describe Humid::LogSubscriber do
|
6
|
-
around(:each) do |example|
|
7
|
-
app_path = File.expand_path("./testapp", File.dirname(__FILE__))
|
8
|
-
Dir.chdir(app_path) do
|
9
|
-
example.run
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
before(:each) do
|
14
|
-
Humid::LogSubscriber.reset_runtime
|
15
|
-
end
|
16
|
-
|
17
|
-
context ".runtime" do
|
18
|
-
it "is returns the runtime from the thread local" do
|
19
|
-
expect(Humid::LogSubscriber.runtime).to eql 0
|
20
|
-
key = "attr_Humid::LogSubscriber_humid_runtime"
|
21
|
-
Thread.current[key] = 3
|
22
|
-
expect(Humid::LogSubscriber.runtime).to eql 3
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context ".runtime=" do
|
27
|
-
it "sets the runtime in a thread-safe manner" do
|
28
|
-
expect(Humid::LogSubscriber.runtime).to eql 0
|
29
|
-
Humid::LogSubscriber.runtime = 3
|
30
|
-
key = "attr_Humid::LogSubscriber_humid_runtime"
|
31
|
-
expect(Thread.current[key]).to eql 3
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context ".reset_runtime" do
|
36
|
-
it "resets the runtime" do
|
37
|
-
Humid::LogSubscriber.runtime = 3
|
38
|
-
key = "attr_Humid::LogSubscriber_humid_runtime"
|
39
|
-
expect(Thread.current[key]).to eql 3
|
40
|
-
|
41
|
-
Humid::LogSubscriber.reset_runtime
|
42
|
-
expect(Thread.current[key]).to eql 0
|
43
|
-
expect(Humid::LogSubscriber.runtime).to eql 0
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
it "is attached" do
|
48
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
49
|
-
Humid.create_context
|
50
|
-
expect(Humid::LogSubscriber.runtime).to eql(0)
|
51
|
-
Humid.render
|
52
|
-
expect(Humid::LogSubscriber.runtime).to be > 0
|
53
|
-
end
|
54
|
-
end
|
data/spec/render_spec.rb
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
require_relative "./support/helper"
|
2
|
-
|
3
|
-
RSpec.describe "Humid" do
|
4
|
-
around(:each) do |example|
|
5
|
-
app_path = File.expand_path("./testapp", File.dirname(__FILE__))
|
6
|
-
Dir.chdir(app_path) do
|
7
|
-
example.run
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe "create_context" do
|
12
|
-
after(:each) do
|
13
|
-
Humid.dispose
|
14
|
-
end
|
15
|
-
|
16
|
-
it "creates a context with initial js" do
|
17
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
18
|
-
Humid.create_context
|
19
|
-
|
20
|
-
expect(Humid.context).to be_kind_of(MiniRacer::Context)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "does not have timeouts, immediates, and intervals" do
|
24
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
25
|
-
|
26
|
-
Humid.create_context
|
27
|
-
|
28
|
-
expect {
|
29
|
-
Humid.context.eval("setTimeout()")
|
30
|
-
}.to raise_error(MiniRacer::RuntimeError, "ReferenceError: setTimeout is not defined")
|
31
|
-
expect {
|
32
|
-
Humid.context.eval("setInterval()")
|
33
|
-
}.to raise_error(MiniRacer::RuntimeError, "ReferenceError: setInterval is not defined")
|
34
|
-
expect {
|
35
|
-
Humid.context.eval("clearTimeout()")
|
36
|
-
}.to raise_error(MiniRacer::RuntimeError, "ReferenceError: clearTimeout is not defined")
|
37
|
-
expect {
|
38
|
-
Humid.context.eval("setImmediate()")
|
39
|
-
}.to raise_error(MiniRacer::RuntimeError, "ReferenceError: setImmediate is not defined")
|
40
|
-
expect {
|
41
|
-
Humid.context.eval("clearImmediate()")
|
42
|
-
}.to raise_error(MiniRacer::RuntimeError, "ReferenceError: clearImmediate is not defined")
|
43
|
-
end
|
44
|
-
|
45
|
-
it "proxies to Rails logger" do
|
46
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
47
|
-
Humid.create_context
|
48
|
-
expect(Humid.logger).to receive(:info).with("hello")
|
49
|
-
|
50
|
-
Humid.context.eval("console.info('hello')")
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe "context" do
|
55
|
-
it "returns the created context" do
|
56
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
57
|
-
|
58
|
-
Humid.create_context
|
59
|
-
|
60
|
-
expect(Humid.context).to be_kind_of(MiniRacer::Context)
|
61
|
-
end
|
62
|
-
|
63
|
-
context "when the js is stale and env is NOT dev`" do
|
64
|
-
it "does not recompile the JS" do
|
65
|
-
allow(Webpacker).to receive_message_chain("env.development?") { false }
|
66
|
-
allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
|
67
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
68
|
-
|
69
|
-
Humid.create_context
|
70
|
-
prev_context = Humid.context
|
71
|
-
expect(prev_context).to be_kind_of(MiniRacer::Context)
|
72
|
-
|
73
|
-
allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
|
74
|
-
|
75
|
-
next_context = Humid.context
|
76
|
-
|
77
|
-
expect(prev_context).to eql(next_context)
|
78
|
-
expect(next_context).to be_kind_of(MiniRacer::Context)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context "when the env is development" do
|
83
|
-
it "compiles the JS when stale" do
|
84
|
-
allow(Webpacker).to receive_message_chain("env.development?") { true }
|
85
|
-
allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
|
86
|
-
allow(Webpacker).to receive_message_chain("compiler.compile")
|
87
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
88
|
-
|
89
|
-
Humid.create_context
|
90
|
-
prev_context = Humid.context
|
91
|
-
expect(prev_context).to be_kind_of(MiniRacer::Context)
|
92
|
-
|
93
|
-
allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
|
94
|
-
# This simulates a changing file
|
95
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple_changed.js" }
|
96
|
-
|
97
|
-
next_context = Humid.context
|
98
|
-
|
99
|
-
expect(prev_context).to_not eql(next_context)
|
100
|
-
expect(next_context).to be_kind_of(MiniRacer::Context)
|
101
|
-
end
|
102
|
-
|
103
|
-
it "creates a new context when webpack-devserver already handled JS staleness" do
|
104
|
-
allow(Webpacker).to receive_message_chain("env.development?") { true }
|
105
|
-
allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
|
106
|
-
allow(Webpacker).to receive_message_chain("compiler.compile")
|
107
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
108
|
-
|
109
|
-
Humid.create_context
|
110
|
-
prev_context = Humid.context
|
111
|
-
expect(Humid.render).to eql("hello")
|
112
|
-
expect(prev_context).to be_kind_of(MiniRacer::Context)
|
113
|
-
|
114
|
-
allow(Webpacker).to receive_message_chain("compiler.stale?") { false }
|
115
|
-
# This simulates a changing file
|
116
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple_changed.js" }
|
117
|
-
|
118
|
-
next_context = Humid.context
|
119
|
-
|
120
|
-
expect(prev_context).to_not eql(next_context)
|
121
|
-
expect(next_context).to be_kind_of(MiniRacer::Context)
|
122
|
-
expect(Humid.render).to eql("hello changed")
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe "render" do
|
128
|
-
it "returns a js output" do
|
129
|
-
allow(Humid.config).to receive("server_rendering_file") { "simple.js" }
|
130
|
-
Humid.create_context
|
131
|
-
|
132
|
-
expect(Humid.render).to eql("hello")
|
133
|
-
end
|
134
|
-
|
135
|
-
it "applys args to the func" do
|
136
|
-
allow(Humid.config).to receive("server_rendering_file") { "args.js" }
|
137
|
-
Humid.create_context
|
138
|
-
|
139
|
-
args = ["a", 1, 2, [], {}]
|
140
|
-
|
141
|
-
expect(Humid.render(*args)).to eql({"0" => "a", "1" => 1, "2" => 2, "3" => [], "4" => {}})
|
142
|
-
end
|
143
|
-
|
144
|
-
it "can use source maps to see errors" do
|
145
|
-
allow(Humid.config).to receive("server_rendering_file") { "reporting.js" }
|
146
|
-
allow(Humid.config).to receive("use_source_map") { true }
|
147
|
-
|
148
|
-
Humid.create_context
|
149
|
-
|
150
|
-
expect {
|
151
|
-
Humid.render
|
152
|
-
}.to raise_error { |error|
|
153
|
-
expect(error).to be_a(Humid::RenderError)
|
154
|
-
message = error.message.split("\n")
|
155
|
-
expect(message[0]).to eql("Error: ^^ Look! These stack traces map to the actual source code :)")
|
156
|
-
expect(message[1]).to eql("JavaScript at throwSomeError (/webpack:/app/javascript/packs/components/error-causing-component.js:2:1)")
|
157
|
-
expect(message[2]).to eql("JavaScript at ErrorCausingComponent (/webpack:/app/javascript/packs/components/error-causing-component.js:8:1)")
|
158
|
-
expect(message[3]).to eql("JavaScript at /webpack:/app/javascript/packs/reporting.js:18:1")
|
159
|
-
}
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|