opal-webpack-loader 0.11.2 → 0.13.0
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 +212 -216
- data/bin/opal-webpack-compile-server +0 -1
- data/bin/opal-webpack-windows-compile-server +7 -4
- data/bin/owl-compiler +7 -4
- data/lib/opal-webpack-loader/installer_cli.rb +415 -415
- data/lib/opal-webpack-loader/templates/application.css.erb +4 -4
- data/lib/opal-webpack-loader/templates/debug.js.erb +149 -150
- data/lib/opal-webpack-loader/templates/development.js.erb +134 -135
- data/lib/opal-webpack-loader/templates/opal_loader.rb.erb +7 -9
- data/lib/opal-webpack-loader/templates/opal_web_worker_loader.rb.erb +7 -9
- data/lib/opal-webpack-loader/templates/package.json.erb +25 -26
- data/lib/opal-webpack-loader/templates/production.js.erb +97 -99
- data/lib/opal-webpack-loader/version.rb +1 -1
- metadata +20 -34
data/bin/owl-compiler
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'digest'
|
3
3
|
require 'oj'
|
4
|
-
require 'c_lexer'
|
5
4
|
require 'optparse'
|
6
5
|
require 'opal/paths'
|
7
6
|
require 'opal/source_map'
|
@@ -73,19 +72,23 @@ compile_source_map = compile_server_options[:source_map]
|
|
73
72
|
filename = compile_server_options[:source_file]
|
74
73
|
source = File.read(filename)
|
75
74
|
compiler_options.merge!(es6_modules: true)
|
76
|
-
|
75
|
+
|
76
|
+
def compiler_options_digest(compiler_options)
|
77
|
+
@compiler_options_digest ||= Digest::SHA1.hexdigest(Oj.dump(compiler_options, mode: :strict))
|
78
|
+
end
|
77
79
|
|
78
80
|
begin
|
79
81
|
if compile_server_options[:cache]
|
80
82
|
source_digest = Digest::SHA1.hexdigest(source)
|
81
|
-
key = "owl_#{compiler_options_digest}_#{source_digest}_#{compile_source_map}"
|
83
|
+
key = "owl_#{compiler_options_digest(compiler_options)}_#{source_digest}_#{compile_source_map}"
|
82
84
|
result_json = compile_server_options[:cache].get(key)
|
83
85
|
if result_json
|
84
86
|
STDOUT.puts result_json
|
85
87
|
exit 0
|
86
88
|
end
|
87
89
|
end
|
88
|
-
|
90
|
+
|
91
|
+
c = Opal::Compiler.new(source, compiler_options.merge(file: filename))
|
89
92
|
result = { 'javascript' => c.compile }
|
90
93
|
if compile_source_map
|
91
94
|
result['source_map'] = c.source_map.as_json
|
@@ -1,415 +1,415 @@
|
|
1
|
-
module OpalWebpackLoader
|
2
|
-
module Installer
|
3
|
-
TARGETS = %w[development.js production.js test.js]
|
4
|
-
DEV_START_COMMAND = 'yarn run development'
|
5
|
-
DEV_SM_START_COMMAND = 'yarn run sourcemaps'
|
6
|
-
|
7
|
-
class CLI < Thor
|
8
|
-
desc "iso", "Install owl configuration into a existing isomorfeus project, meant to be called from the isomorfeus installer only."
|
9
|
-
# Showing directories and files relevant to iso owl:
|
10
|
-
# project_root
|
11
|
-
# +- config.ru # rack app starter
|
12
|
-
# +- config # webpack and other config
|
13
|
-
# +- owl.rb # owl.configuration
|
14
|
-
# +- isomorfeus
|
15
|
-
# +- components
|
16
|
-
# +- imports # javascript entrypoints, import other components etc.
|
17
|
-
# +- application.js
|
18
|
-
# +- application_common.js
|
19
|
-
# +- application_ssr.js
|
20
|
-
# +- isomorfeus_loader.rb
|
21
|
-
# +- models
|
22
|
-
# +- operations
|
23
|
-
# +- policies
|
24
|
-
# +- styles
|
25
|
-
# +- css
|
26
|
-
# +- log
|
27
|
-
# +- node_modules
|
28
|
-
# +- package.json
|
29
|
-
# +- Procfile
|
30
|
-
# +- public
|
31
|
-
# +- assets # compiled assets and other things
|
32
|
-
# +- spec
|
33
|
-
# +- tmp
|
34
|
-
def iso
|
35
|
-
@application_css = '../styles/application.css'
|
36
|
-
@asset_output_directory = File.join('public', 'assets')
|
37
|
-
@js_entrypoints_directory = File.join('isomorfeus', 'imports')
|
38
|
-
@conf_rel_prefix = '..'
|
39
|
-
@js_rel_prefix = '..'
|
40
|
-
@opal_directory = 'isomorfeus'
|
41
|
-
@styles_directory = File.join(@opal_directory, 'styles')
|
42
|
-
@webpack_config_directory = 'webpack'
|
43
|
-
@dev_default_targets = 'browser'
|
44
|
-
@pro_default_targets = 'browser, ssr'
|
45
|
-
@hmr_hook = 'Opal.Isomorfeus.$force_render()'
|
46
|
-
create_directory(@webpack_config_directory)
|
47
|
-
create_directory(@asset_output_directory)
|
48
|
-
FileUtils.touch(File.join(@asset_output_directory, '.keep'))
|
49
|
-
install_webpack_config
|
50
|
-
create_file_from_template('initializer.rb.erb', File.join('owl_init.rb'), { opal_load_path: '' })
|
51
|
-
# add_gem
|
52
|
-
end
|
53
|
-
|
54
|
-
desc "flat", "Install owl configuration into a existing project with a flat structure, execute from the projects root directory."
|
55
|
-
# <<~TEXT
|
56
|
-
# Showing directories and files relevant to owl:
|
57
|
-
# project_root
|
58
|
-
# +- owl_init.rb # initializer for owl
|
59
|
-
# +- javascripts # javascript entries directory
|
60
|
-
# +- node_modules # directory for node modules
|
61
|
-
# +- opal # directory for opal application files, can be changed with -o
|
62
|
-
# +- package.json # package config for npm/yarn and their scripts
|
63
|
-
# +- public
|
64
|
-
# +- assets # directory for compiled output files
|
65
|
-
# +- styles # directory for stylesheets
|
66
|
-
# +- webpack # directory for webpack configuration files
|
67
|
-
# +- Procfile # config file for foreman
|
68
|
-
#
|
69
|
-
# TEXT
|
70
|
-
option :opal_name, required: false, type: :string, default: 'opal', aliases: '-o', desc: <<~TEXT
|
71
|
-
Set directory name for Opal source files.
|
72
|
-
Example: owl-installer rails -o isomorfeus # will use project_root/app/isomorfeus for opal files
|
73
|
-
TEXT
|
74
|
-
|
75
|
-
def flat
|
76
|
-
@application_css = '../styles/application.css'
|
77
|
-
@asset_output_directory = File.join('public', 'assets')
|
78
|
-
@js_entrypoints_directory = File.join('javascripts')
|
79
|
-
@conf_rel_prefix = '..'
|
80
|
-
@js_rel_prefix = '..'
|
81
|
-
@opal_directory = options[:opal_name]
|
82
|
-
@styles_directory = 'styles'
|
83
|
-
@webpack_config_directory = 'webpack'
|
84
|
-
@dev_default_targets = 'browser'
|
85
|
-
@pro_default_targets = 'browser'
|
86
|
-
@hmr_hook = ''
|
87
|
-
create_common_directories
|
88
|
-
install_common_things
|
89
|
-
create_file_from_template('application.css.erb', File.join('styles', 'application.css'), {})
|
90
|
-
create_file_from_template('initializer.rb.erb', 'owl_init.rb', { opal_load_path: '' })
|
91
|
-
create_file_from_template('app_loader.rb.erb', 'app_loader.rb', { opal_directory: @opal_directory })
|
92
|
-
add_gem
|
93
|
-
print_message
|
94
|
-
end
|
95
|
-
|
96
|
-
desc "rails", "Install owl configuration into a existing rails project without webpacker, execute from the projects root directory."
|
97
|
-
# <<~TEXT
|
98
|
-
# Showing directories and files relevant to owl:
|
99
|
-
# project_root
|
100
|
-
# +- app
|
101
|
-
# +- assets
|
102
|
-
# +- javascripts # javascript entries directory
|
103
|
-
# +- styles # directory for stylesheets
|
104
|
-
# +- opal # directory for opal application files, can be changed with -o
|
105
|
-
# +- config
|
106
|
-
# +- webpack # directory for webpack configuration files
|
107
|
-
# +- initializers
|
108
|
-
# +- owl.rb # initializer for owl
|
109
|
-
# +- node_modules # directory for node modules
|
110
|
-
# +- package.json # package config for npm/yarn and their scripts
|
111
|
-
# +- public
|
112
|
-
# +- assets # directory for compiled output files
|
113
|
-
# +- Procfile # config file for foreman
|
114
|
-
#
|
115
|
-
# TEXT
|
116
|
-
option :opal_name, required: false, type: :string, default: 'opal', aliases: '-o', desc: <<~TEXT
|
117
|
-
Set directory name for Opal source files.
|
118
|
-
Example: owl-installer rails -o isomorfeus # will use project_root/app/isomorfeus for opal files
|
119
|
-
TEXT
|
120
|
-
|
121
|
-
def rails
|
122
|
-
@application_css = '../stylesheets/application.css'
|
123
|
-
@asset_output_directory = File.join('public', 'assets')
|
124
|
-
@js_entrypoints_directory = File.join('app', 'assets', 'javascripts')
|
125
|
-
@conf_rel_prefix = File.join('..', '..')
|
126
|
-
@js_rel_prefix = File.join('..', '..', '..')
|
127
|
-
@opal_directory = File.join('app', options[:opal_name])
|
128
|
-
@styles_directory = File.join('app', 'assets', 'stylesheets')
|
129
|
-
@webpack_config_directory = File.join('config', 'webpack')
|
130
|
-
@dev_default_targets = 'browser'
|
131
|
-
@pro_default_targets = 'browser'
|
132
|
-
@hmr_hook = ''
|
133
|
-
create_directory('app')
|
134
|
-
create_common_directories
|
135
|
-
install_common_things
|
136
|
-
create_file_from_template('initializer.rb.erb', File.join('config', 'initializers', 'opal_webpack_loader.rb'),
|
137
|
-
{ opal_load_path: "Opal.append_path(File.realdirpath('#{@opal_directory}'))" })
|
138
|
-
add_gem
|
139
|
-
print_message
|
140
|
-
end
|
141
|
-
|
142
|
-
desc "webpacker", "Install owl configuration into a existing rails project with webpacker, execute from the projects root directory."
|
143
|
-
# <<~TEXT
|
144
|
-
# Showing directories and files relevant to owl:
|
145
|
-
# project_root
|
146
|
-
# +- app
|
147
|
-
# +- assets
|
148
|
-
# +- javascripts # javascript entries directory
|
149
|
-
# +- styles # directory for stylesheets
|
150
|
-
# +- opal # directory for opal application files, can be changed with -o
|
151
|
-
# +- config
|
152
|
-
# +- webpack # directory for webpack configuration files
|
153
|
-
# +- initializers
|
154
|
-
# +- owl.rb # initializer for owl
|
155
|
-
# +- node_modules # directory for node modules
|
156
|
-
# +- package.json # package config for npm/yarn and their scripts
|
157
|
-
# +- public
|
158
|
-
# +- assets # directory for compiled output files
|
159
|
-
# +- Procfile # config file for foreman
|
160
|
-
#
|
161
|
-
# TEXT
|
162
|
-
option :opal_name, required: false, type: :string, default: 'opal', aliases: '-o', desc: <<~TEXT
|
163
|
-
Set directory name for Opal source files.
|
164
|
-
Example: owl-installer rails -o isomorfeus # will use project_root/app/isomorfeus for opal files
|
165
|
-
TEXT
|
166
|
-
|
167
|
-
def webpacker
|
168
|
-
@application_css = '../stylesheets/application.css'
|
169
|
-
@asset_output_directory = File.join('public', 'assets')
|
170
|
-
@js_entrypoints_directory = File.join('app', 'assets', 'javascripts')
|
171
|
-
@conf_rel_prefix = File.join('..', '..')
|
172
|
-
@js_rel_prefix = File.join('..', '..', '..')
|
173
|
-
@opal_directory = File.join('app', options[:opal_name])
|
174
|
-
@styles_directory = File.join('app', 'assets', 'stylesheets')
|
175
|
-
@webpack_config_directory = File.join('config', 'webpack')
|
176
|
-
@dev_default_targets = 'browser'
|
177
|
-
@pro_default_targets = 'browser'
|
178
|
-
@hmr_hook = ''
|
179
|
-
create_directory('app')
|
180
|
-
create_common_directories
|
181
|
-
install_webpacker_config
|
182
|
-
install_webpacker_package_json
|
183
|
-
install_webpacker_js_entry
|
184
|
-
install_opal_entries
|
185
|
-
create_file_from_template('initializer.rb.erb', File.join('config', 'initializers', 'opal_webpack_loader.rb'),
|
186
|
-
{ opal_load_path: "Opal.append_path(File.realdirpath('#{@opal_directory}'))" })
|
187
|
-
add_gem
|
188
|
-
print_message
|
189
|
-
end
|
190
|
-
|
191
|
-
private
|
192
|
-
|
193
|
-
def create_directory(directory)
|
194
|
-
unless Dir.exist?(directory)
|
195
|
-
puts "Creating directory #{directory}."
|
196
|
-
FileUtils.mkdir_p(directory)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def create_common_directories
|
201
|
-
create_directory(@webpack_config_directory)
|
202
|
-
create_directory(@js_entrypoints_directory)
|
203
|
-
create_directory(@opal_directory)
|
204
|
-
create_directory(@asset_output_directory)
|
205
|
-
FileUtils.touch(File.join(@asset_output_directory, '.gitkeep'))
|
206
|
-
create_directory(@styles_directory)
|
207
|
-
end
|
208
|
-
|
209
|
-
def install_common_things
|
210
|
-
install_webpack_config
|
211
|
-
install_package_json
|
212
|
-
install_js_entries
|
213
|
-
install_opal_entries
|
214
|
-
install_procfile
|
215
|
-
end
|
216
|
-
|
217
|
-
def install_js_entries
|
218
|
-
erb_hash = { opal_dir: File.join(@js_rel_prefix, @opal_directory), opal_name: options[:opal_name], application_css: @application_css }
|
219
|
-
create_file_from_template('application.js.erb', File.join(@js_entrypoints_directory, 'application.js'), erb_hash)
|
220
|
-
create_file_from_template('application_common.js.erb', File.join(@js_entrypoints_directory, 'application_common.js'),erb_hash)
|
221
|
-
create_file_from_template('application_ssr.js.erb', File.join(@js_entrypoints_directory, 'application_ssr.js'), erb_hash)
|
222
|
-
create_file_from_template('application_web_worker.js.erb', File.join(@js_entrypoints_directory, 'application_web_worker.js'), erb_hash)
|
223
|
-
end
|
224
|
-
|
225
|
-
def install_opal_entries
|
226
|
-
create_file_from_template('opal_loader.rb.erb', File.join(@opal_directory, "#{options[:opal_name]}_loader.rb"), {})
|
227
|
-
create_file_from_template('opal_web_worker_loader.rb.erb', File.join(@opal_directory, "#{options[:opal_name]}_web_worker_loader.rb"), {})
|
228
|
-
end
|
229
|
-
|
230
|
-
def install_package_json
|
231
|
-
if File.exist?('package.json')
|
232
|
-
gem_package_json_template = File.read(File.join(templates_path, 'package.json.erb'))
|
233
|
-
gem_package_json = Oj.load(gem_package_json_template, mode: :strict)
|
234
|
-
package_json_file = File.read('package.json')
|
235
|
-
package_json = Oj.load(package_json_file, mode: :strict)
|
236
|
-
package_json["scripts"] = {} unless package_json.has_key?("scripts")
|
237
|
-
package_json["scripts"]["debug"] = debug_script
|
238
|
-
package_json["scripts"]["development"] = development_script
|
239
|
-
package_json["scripts"]["production_build"] = production_script
|
240
|
-
package_json["devDependencies"] = {} unless package_json.has_key?("devDependencies")
|
241
|
-
package_json["devDependencies"].merge!(gem_package_json["devDependencies"])
|
242
|
-
package_json["dependencies"]["opal-webpack-loader"] = "^#{OpalWebpackLoader::VERSION}"
|
243
|
-
File.write('package.json', Oj.dump(package_json, mode: :strict, indent: 2))
|
244
|
-
puts "Updated package.json, updated scripts and owl dependencies"
|
245
|
-
else
|
246
|
-
erb_hash = {
|
247
|
-
debug_script: debug_script,
|
248
|
-
development_script: development_script,
|
249
|
-
production_script: production_script,
|
250
|
-
owl_version: OpalWebpackLoader::VERSION
|
251
|
-
}
|
252
|
-
create_file_from_template('package.json.erb', 'package.json', erb_hash)
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
def install_procfile
|
257
|
-
if File.exist?('Procfile')
|
258
|
-
procfile = File.read('Procfile')
|
259
|
-
has_webpack = false
|
260
|
-
lines = procfile.lines
|
261
|
-
lines.each do |line|
|
262
|
-
has_webpack = true if line.start_with?('webpack')
|
263
|
-
end
|
264
|
-
unless has_webpack
|
265
|
-
lines << 'webpack: yarn run development'
|
266
|
-
File.write('Procfile', lines.join("\n"))
|
267
|
-
end
|
268
|
-
else
|
269
|
-
erb_hash = { web_starter: '' }
|
270
|
-
if @js_entrypoints_directory.start_with?('app')
|
271
|
-
erb_hash[:web_starter] = 'web: bundle exec rails s'
|
272
|
-
end
|
273
|
-
create_file_from_template('Procfile.erb', 'Procfile',erb_hash)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
def debug_script
|
278
|
-
"webpack-dev-server --config #{File.join(@webpack_config_directory, 'debug.js')}"
|
279
|
-
end
|
280
|
-
|
281
|
-
def development_script
|
282
|
-
"webpack-dev-server --config #{File.join(@webpack_config_directory, 'development.js')}"
|
283
|
-
end
|
284
|
-
|
285
|
-
def production_script
|
286
|
-
"parallel-webpack --config=#{File.join(@webpack_config_directory, 'production.js')}"
|
287
|
-
end
|
288
|
-
|
289
|
-
def install_webpack_config
|
290
|
-
erb_hash = {
|
291
|
-
asset_output_directory: File.join(@conf_rel_prefix, @asset_output_directory),
|
292
|
-
default_targets: @dev_default_targets,
|
293
|
-
js_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application.js'),
|
294
|
-
js_common_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_common.js'),
|
295
|
-
js_ssr_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_ssr.js'),
|
296
|
-
js_web_worker_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_web_worker.js'),
|
297
|
-
opal_directory: File.join(@conf_rel_prefix, @opal_directory),
|
298
|
-
stylesheets_directory: File.join(@conf_rel_prefix, @styles_directory),
|
299
|
-
hmr_hook: @hmr_hook
|
300
|
-
}
|
301
|
-
if @js_entrypoints_directory.start_with?('app')
|
302
|
-
erb_hash[:dev_server_before] = <<~JAVASCRIPT
|
303
|
-
// enable page reload for updates within the app/views directory
|
304
|
-
before: function(app, server) {
|
305
|
-
chokidar.watch(path.resolve(__dirname, path.join('..', '..', 'app', 'views'))).on('all', function () {
|
306
|
-
server.sockWrite(server.sockets, 'content-changed');
|
307
|
-
})
|
308
|
-
},
|
309
|
-
JAVASCRIPT
|
310
|
-
else
|
311
|
-
erb_hash[:dev_server_before] = <<~JAVASCRIPT
|
312
|
-
// uncomment to enable page reload for updates within another directory, which may contain just html files,
|
313
|
-
// for example the 'views' directory:
|
314
|
-
// before: function(app, server) {
|
315
|
-
// chokidar.watch(path.resolve(__dirname, path.join('..', 'views')).on('all', function () {
|
316
|
-
// server.sockWrite(server.sockets, 'content-changed');
|
317
|
-
// })
|
318
|
-
// },
|
319
|
-
JAVASCRIPT
|
320
|
-
end
|
321
|
-
create_file_from_template('debug.js.erb', File.join(@webpack_config_directory, 'debug.js'), erb_hash)
|
322
|
-
create_file_from_template('development.js.erb', File.join(@webpack_config_directory, 'development.js'), erb_hash)
|
323
|
-
erb_hash[:default_targets] = @pro_default_targets
|
324
|
-
create_file_from_template('production.js.erb', File.join(@webpack_config_directory, 'production.js'), erb_hash)
|
325
|
-
end
|
326
|
-
|
327
|
-
def install_webpacker_config
|
328
|
-
environment_js = File.read(File.join('config', 'webpack', 'environment.js'), mode: 'r')
|
329
|
-
new_environment_js = ''
|
330
|
-
environment_js.lines.each do |line|
|
331
|
-
new_environment_js << line
|
332
|
-
if line.start_with?('const { environment }')
|
333
|
-
new_environment_js << "\n"
|
334
|
-
new_environment_js << File.read(File.join(templates_path, 'webpacker.js'), mode: 'r')
|
335
|
-
new_environment_js << "\n"
|
336
|
-
end
|
337
|
-
end
|
338
|
-
File.write(File.join('config', 'webpack', 'environment.js'), new_environment_js)
|
339
|
-
end
|
340
|
-
|
341
|
-
def install_webpacker_js_entry
|
342
|
-
application_js = File.read(File.join('app', 'javascript', 'packs', 'application.js'), mode: 'r')
|
343
|
-
application_js << <<~JAVASCRIPT
|
344
|
-
|
345
|
-
// import and load opal ruby files
|
346
|
-
import init_app from '#{options[:opal_name]}_loader.rb';
|
347
|
-
init_app();
|
348
|
-
Opal.load('#{options[:opal_name]}_loader');
|
349
|
-
|
350
|
-
JAVASCRIPT
|
351
|
-
File.write(File.join('app', 'javascript', 'packs', 'application.js'), application_js)
|
352
|
-
end
|
353
|
-
|
354
|
-
def install_webpacker_package_json
|
355
|
-
package_json_file = File.read('package.json')
|
356
|
-
package_json = Oj.load(package_json_file, mode: :strict)
|
357
|
-
package_json["dependencies"]["opal-webpack-loader"] = "^#{OpalWebpackLoader::VERSION}"
|
358
|
-
File.write('package.json', Oj.dump(package_json, mode: :strict, indent: 2))
|
359
|
-
puts "Updated package.json for opal-webpack-loader"
|
360
|
-
end
|
361
|
-
|
362
|
-
def templates_path
|
363
|
-
File.realpath(File.join(File.dirname(File.realpath(__FILE__)), 'templates'))
|
364
|
-
end
|
365
|
-
|
366
|
-
def create_file_from_template(template_path, target_file_path, data_hash)
|
367
|
-
template = ERB.new(File.read(File.join(templates_path, template_path), mode: 'r'))
|
368
|
-
result = template.result_with_hash(data_hash)
|
369
|
-
if File.exist?(target_file_path)
|
370
|
-
ext = '_owl_new'
|
371
|
-
puts "#{target_file_path} exists, not overwriting, creating #{target_file_path + ext} instead."
|
372
|
-
else
|
373
|
-
ext = ''
|
374
|
-
puts "Creating #{target_file_path}."
|
375
|
-
end
|
376
|
-
|
377
|
-
File.write(target_file_path + ext, result, mode: 'w')
|
378
|
-
end
|
379
|
-
|
380
|
-
def add_gem
|
381
|
-
# TODO specifying a version results in bundler printing a error and not adding the gem
|
382
|
-
# `bundle add opal-webpack-loader -v "#{OpalWebpackLoader::VERSION}" --skip-install`ß´
|
383
|
-
end
|
384
|
-
|
385
|
-
def print_message
|
386
|
-
puts <<~TEXT
|
387
|
-
|
388
|
-
Add the following lines to your Gemfile:
|
389
|
-
|
390
|
-
gem 'opal', github: 'janbiedermann/opal', branch: '
|
391
|
-
gem 'opal-webpack-loader', '~> #{OpalWebpackLoader::VERSION}'
|
392
|
-
|
393
|
-
owl currently works only with above opal branch. If you have a existing "gem 'opal'", please replace it with above line.
|
394
|
-
|
395
|
-
Also check above output for files ending in '_owl_new' and merge their contents with the existing files.
|
396
|
-
|
397
|
-
After that run according to your preference either:
|
398
|
-
|
399
|
-
yarn install
|
400
|
-
|
401
|
-
or:
|
402
|
-
|
403
|
-
npm install
|
404
|
-
|
405
|
-
and then:
|
406
|
-
|
407
|
-
bundle install
|
408
|
-
|
409
|
-
For further instructions see http://github.com/isomorfeus/opal-webpack-loader
|
410
|
-
|
411
|
-
TEXT
|
412
|
-
end
|
413
|
-
end
|
414
|
-
end
|
415
|
-
end
|
1
|
+
module OpalWebpackLoader
|
2
|
+
module Installer
|
3
|
+
TARGETS = %w[development.js production.js test.js]
|
4
|
+
DEV_START_COMMAND = 'yarn run development'
|
5
|
+
DEV_SM_START_COMMAND = 'yarn run sourcemaps'
|
6
|
+
|
7
|
+
class CLI < Thor
|
8
|
+
desc "iso", "Install owl configuration into a existing isomorfeus project, meant to be called from the isomorfeus installer only."
|
9
|
+
# Showing directories and files relevant to iso owl:
|
10
|
+
# project_root
|
11
|
+
# +- config.ru # rack app starter
|
12
|
+
# +- config # webpack and other config
|
13
|
+
# +- owl.rb # owl.configuration
|
14
|
+
# +- isomorfeus
|
15
|
+
# +- components
|
16
|
+
# +- imports # javascript entrypoints, import other components etc.
|
17
|
+
# +- application.js
|
18
|
+
# +- application_common.js
|
19
|
+
# +- application_ssr.js
|
20
|
+
# +- isomorfeus_loader.rb
|
21
|
+
# +- models
|
22
|
+
# +- operations
|
23
|
+
# +- policies
|
24
|
+
# +- styles
|
25
|
+
# +- css
|
26
|
+
# +- log
|
27
|
+
# +- node_modules
|
28
|
+
# +- package.json
|
29
|
+
# +- Procfile
|
30
|
+
# +- public
|
31
|
+
# +- assets # compiled assets and other things
|
32
|
+
# +- spec
|
33
|
+
# +- tmp
|
34
|
+
def iso
|
35
|
+
@application_css = '../styles/application.css'
|
36
|
+
@asset_output_directory = File.join('public', 'assets')
|
37
|
+
@js_entrypoints_directory = File.join('isomorfeus', 'imports')
|
38
|
+
@conf_rel_prefix = '..'
|
39
|
+
@js_rel_prefix = '..'
|
40
|
+
@opal_directory = 'isomorfeus'
|
41
|
+
@styles_directory = File.join(@opal_directory, 'styles')
|
42
|
+
@webpack_config_directory = 'webpack'
|
43
|
+
@dev_default_targets = 'browser'
|
44
|
+
@pro_default_targets = 'browser, ssr'
|
45
|
+
@hmr_hook = 'Opal.Isomorfeus.$force_render()'
|
46
|
+
create_directory(@webpack_config_directory)
|
47
|
+
create_directory(@asset_output_directory)
|
48
|
+
FileUtils.touch(File.join(@asset_output_directory, '.keep'))
|
49
|
+
install_webpack_config
|
50
|
+
create_file_from_template('initializer.rb.erb', File.join('owl_init.rb'), { opal_load_path: '' })
|
51
|
+
# add_gem
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "flat", "Install owl configuration into a existing project with a flat structure, execute from the projects root directory."
|
55
|
+
# <<~TEXT
|
56
|
+
# Showing directories and files relevant to owl:
|
57
|
+
# project_root
|
58
|
+
# +- owl_init.rb # initializer for owl
|
59
|
+
# +- javascripts # javascript entries directory
|
60
|
+
# +- node_modules # directory for node modules
|
61
|
+
# +- opal # directory for opal application files, can be changed with -o
|
62
|
+
# +- package.json # package config for npm/yarn and their scripts
|
63
|
+
# +- public
|
64
|
+
# +- assets # directory for compiled output files
|
65
|
+
# +- styles # directory for stylesheets
|
66
|
+
# +- webpack # directory for webpack configuration files
|
67
|
+
# +- Procfile # config file for foreman
|
68
|
+
#
|
69
|
+
# TEXT
|
70
|
+
option :opal_name, required: false, type: :string, default: 'opal', aliases: '-o', desc: <<~TEXT
|
71
|
+
Set directory name for Opal source files.
|
72
|
+
Example: owl-installer rails -o isomorfeus # will use project_root/app/isomorfeus for opal files
|
73
|
+
TEXT
|
74
|
+
|
75
|
+
def flat
|
76
|
+
@application_css = '../styles/application.css'
|
77
|
+
@asset_output_directory = File.join('public', 'assets')
|
78
|
+
@js_entrypoints_directory = File.join('javascripts')
|
79
|
+
@conf_rel_prefix = '..'
|
80
|
+
@js_rel_prefix = '..'
|
81
|
+
@opal_directory = options[:opal_name]
|
82
|
+
@styles_directory = 'styles'
|
83
|
+
@webpack_config_directory = 'webpack'
|
84
|
+
@dev_default_targets = 'browser'
|
85
|
+
@pro_default_targets = 'browser'
|
86
|
+
@hmr_hook = ''
|
87
|
+
create_common_directories
|
88
|
+
install_common_things
|
89
|
+
create_file_from_template('application.css.erb', File.join('styles', 'application.css'), {})
|
90
|
+
create_file_from_template('initializer.rb.erb', 'owl_init.rb', { opal_load_path: '' })
|
91
|
+
create_file_from_template('app_loader.rb.erb', 'app_loader.rb', { opal_directory: @opal_directory })
|
92
|
+
add_gem
|
93
|
+
print_message
|
94
|
+
end
|
95
|
+
|
96
|
+
desc "rails", "Install owl configuration into a existing rails project without webpacker, execute from the projects root directory."
|
97
|
+
# <<~TEXT
|
98
|
+
# Showing directories and files relevant to owl:
|
99
|
+
# project_root
|
100
|
+
# +- app
|
101
|
+
# +- assets
|
102
|
+
# +- javascripts # javascript entries directory
|
103
|
+
# +- styles # directory for stylesheets
|
104
|
+
# +- opal # directory for opal application files, can be changed with -o
|
105
|
+
# +- config
|
106
|
+
# +- webpack # directory for webpack configuration files
|
107
|
+
# +- initializers
|
108
|
+
# +- owl.rb # initializer for owl
|
109
|
+
# +- node_modules # directory for node modules
|
110
|
+
# +- package.json # package config for npm/yarn and their scripts
|
111
|
+
# +- public
|
112
|
+
# +- assets # directory for compiled output files
|
113
|
+
# +- Procfile # config file for foreman
|
114
|
+
#
|
115
|
+
# TEXT
|
116
|
+
option :opal_name, required: false, type: :string, default: 'opal', aliases: '-o', desc: <<~TEXT
|
117
|
+
Set directory name for Opal source files.
|
118
|
+
Example: owl-installer rails -o isomorfeus # will use project_root/app/isomorfeus for opal files
|
119
|
+
TEXT
|
120
|
+
|
121
|
+
def rails
|
122
|
+
@application_css = '../stylesheets/application.css'
|
123
|
+
@asset_output_directory = File.join('public', 'assets')
|
124
|
+
@js_entrypoints_directory = File.join('app', 'assets', 'javascripts')
|
125
|
+
@conf_rel_prefix = File.join('..', '..')
|
126
|
+
@js_rel_prefix = File.join('..', '..', '..')
|
127
|
+
@opal_directory = File.join('app', options[:opal_name])
|
128
|
+
@styles_directory = File.join('app', 'assets', 'stylesheets')
|
129
|
+
@webpack_config_directory = File.join('config', 'webpack')
|
130
|
+
@dev_default_targets = 'browser'
|
131
|
+
@pro_default_targets = 'browser'
|
132
|
+
@hmr_hook = ''
|
133
|
+
create_directory('app')
|
134
|
+
create_common_directories
|
135
|
+
install_common_things
|
136
|
+
create_file_from_template('initializer.rb.erb', File.join('config', 'initializers', 'opal_webpack_loader.rb'),
|
137
|
+
{ opal_load_path: "Opal.append_path(File.realdirpath('#{@opal_directory}'))" })
|
138
|
+
add_gem
|
139
|
+
print_message
|
140
|
+
end
|
141
|
+
|
142
|
+
desc "webpacker", "Install owl configuration into a existing rails project with webpacker, execute from the projects root directory."
|
143
|
+
# <<~TEXT
|
144
|
+
# Showing directories and files relevant to owl:
|
145
|
+
# project_root
|
146
|
+
# +- app
|
147
|
+
# +- assets
|
148
|
+
# +- javascripts # javascript entries directory
|
149
|
+
# +- styles # directory for stylesheets
|
150
|
+
# +- opal # directory for opal application files, can be changed with -o
|
151
|
+
# +- config
|
152
|
+
# +- webpack # directory for webpack configuration files
|
153
|
+
# +- initializers
|
154
|
+
# +- owl.rb # initializer for owl
|
155
|
+
# +- node_modules # directory for node modules
|
156
|
+
# +- package.json # package config for npm/yarn and their scripts
|
157
|
+
# +- public
|
158
|
+
# +- assets # directory for compiled output files
|
159
|
+
# +- Procfile # config file for foreman
|
160
|
+
#
|
161
|
+
# TEXT
|
162
|
+
option :opal_name, required: false, type: :string, default: 'opal', aliases: '-o', desc: <<~TEXT
|
163
|
+
Set directory name for Opal source files.
|
164
|
+
Example: owl-installer rails -o isomorfeus # will use project_root/app/isomorfeus for opal files
|
165
|
+
TEXT
|
166
|
+
|
167
|
+
def webpacker
|
168
|
+
@application_css = '../stylesheets/application.css'
|
169
|
+
@asset_output_directory = File.join('public', 'assets')
|
170
|
+
@js_entrypoints_directory = File.join('app', 'assets', 'javascripts')
|
171
|
+
@conf_rel_prefix = File.join('..', '..')
|
172
|
+
@js_rel_prefix = File.join('..', '..', '..')
|
173
|
+
@opal_directory = File.join('app', options[:opal_name])
|
174
|
+
@styles_directory = File.join('app', 'assets', 'stylesheets')
|
175
|
+
@webpack_config_directory = File.join('config', 'webpack')
|
176
|
+
@dev_default_targets = 'browser'
|
177
|
+
@pro_default_targets = 'browser'
|
178
|
+
@hmr_hook = ''
|
179
|
+
create_directory('app')
|
180
|
+
create_common_directories
|
181
|
+
install_webpacker_config
|
182
|
+
install_webpacker_package_json
|
183
|
+
install_webpacker_js_entry
|
184
|
+
install_opal_entries
|
185
|
+
create_file_from_template('initializer.rb.erb', File.join('config', 'initializers', 'opal_webpack_loader.rb'),
|
186
|
+
{ opal_load_path: "Opal.append_path(File.realdirpath('#{@opal_directory}'))" })
|
187
|
+
add_gem
|
188
|
+
print_message
|
189
|
+
end
|
190
|
+
|
191
|
+
private
|
192
|
+
|
193
|
+
def create_directory(directory)
|
194
|
+
unless Dir.exist?(directory)
|
195
|
+
puts "Creating directory #{directory}."
|
196
|
+
FileUtils.mkdir_p(directory)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def create_common_directories
|
201
|
+
create_directory(@webpack_config_directory)
|
202
|
+
create_directory(@js_entrypoints_directory)
|
203
|
+
create_directory(@opal_directory)
|
204
|
+
create_directory(@asset_output_directory)
|
205
|
+
FileUtils.touch(File.join(@asset_output_directory, '.gitkeep'))
|
206
|
+
create_directory(@styles_directory)
|
207
|
+
end
|
208
|
+
|
209
|
+
def install_common_things
|
210
|
+
install_webpack_config
|
211
|
+
install_package_json
|
212
|
+
install_js_entries
|
213
|
+
install_opal_entries
|
214
|
+
install_procfile
|
215
|
+
end
|
216
|
+
|
217
|
+
def install_js_entries
|
218
|
+
erb_hash = { opal_dir: File.join(@js_rel_prefix, @opal_directory), opal_name: options[:opal_name], application_css: @application_css }
|
219
|
+
create_file_from_template('application.js.erb', File.join(@js_entrypoints_directory, 'application.js'), erb_hash)
|
220
|
+
create_file_from_template('application_common.js.erb', File.join(@js_entrypoints_directory, 'application_common.js'),erb_hash)
|
221
|
+
create_file_from_template('application_ssr.js.erb', File.join(@js_entrypoints_directory, 'application_ssr.js'), erb_hash)
|
222
|
+
create_file_from_template('application_web_worker.js.erb', File.join(@js_entrypoints_directory, 'application_web_worker.js'), erb_hash)
|
223
|
+
end
|
224
|
+
|
225
|
+
def install_opal_entries
|
226
|
+
create_file_from_template('opal_loader.rb.erb', File.join(@opal_directory, "#{options[:opal_name]}_loader.rb"), {})
|
227
|
+
create_file_from_template('opal_web_worker_loader.rb.erb', File.join(@opal_directory, "#{options[:opal_name]}_web_worker_loader.rb"), {})
|
228
|
+
end
|
229
|
+
|
230
|
+
def install_package_json
|
231
|
+
if File.exist?('package.json')
|
232
|
+
gem_package_json_template = File.read(File.join(templates_path, 'package.json.erb'))
|
233
|
+
gem_package_json = Oj.load(gem_package_json_template, mode: :strict)
|
234
|
+
package_json_file = File.read('package.json')
|
235
|
+
package_json = Oj.load(package_json_file, mode: :strict)
|
236
|
+
package_json["scripts"] = {} unless package_json.has_key?("scripts")
|
237
|
+
package_json["scripts"]["debug"] = debug_script
|
238
|
+
package_json["scripts"]["development"] = development_script
|
239
|
+
package_json["scripts"]["production_build"] = production_script
|
240
|
+
package_json["devDependencies"] = {} unless package_json.has_key?("devDependencies")
|
241
|
+
package_json["devDependencies"].merge!(gem_package_json["devDependencies"])
|
242
|
+
package_json["dependencies"]["opal-webpack-loader"] = "^#{OpalWebpackLoader::VERSION}"
|
243
|
+
File.write('package.json', Oj.dump(package_json, mode: :strict, indent: 2))
|
244
|
+
puts "Updated package.json, updated scripts and owl dependencies"
|
245
|
+
else
|
246
|
+
erb_hash = {
|
247
|
+
debug_script: debug_script,
|
248
|
+
development_script: development_script,
|
249
|
+
production_script: production_script,
|
250
|
+
owl_version: OpalWebpackLoader::VERSION
|
251
|
+
}
|
252
|
+
create_file_from_template('package.json.erb', 'package.json', erb_hash)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def install_procfile
|
257
|
+
if File.exist?('Procfile')
|
258
|
+
procfile = File.read('Procfile')
|
259
|
+
has_webpack = false
|
260
|
+
lines = procfile.lines
|
261
|
+
lines.each do |line|
|
262
|
+
has_webpack = true if line.start_with?('webpack')
|
263
|
+
end
|
264
|
+
unless has_webpack
|
265
|
+
lines << 'webpack: yarn run development'
|
266
|
+
File.write('Procfile', lines.join("\n"))
|
267
|
+
end
|
268
|
+
else
|
269
|
+
erb_hash = { web_starter: '' }
|
270
|
+
if @js_entrypoints_directory.start_with?('app')
|
271
|
+
erb_hash[:web_starter] = 'web: bundle exec rails s'
|
272
|
+
end
|
273
|
+
create_file_from_template('Procfile.erb', 'Procfile',erb_hash)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def debug_script
|
278
|
+
"webpack-dev-server --config #{File.join(@webpack_config_directory, 'debug.js')}"
|
279
|
+
end
|
280
|
+
|
281
|
+
def development_script
|
282
|
+
"webpack-dev-server --config #{File.join(@webpack_config_directory, 'development.js')}"
|
283
|
+
end
|
284
|
+
|
285
|
+
def production_script
|
286
|
+
"parallel-webpack --config=#{File.join(@webpack_config_directory, 'production.js')}"
|
287
|
+
end
|
288
|
+
|
289
|
+
def install_webpack_config
|
290
|
+
erb_hash = {
|
291
|
+
asset_output_directory: File.join(@conf_rel_prefix, @asset_output_directory),
|
292
|
+
default_targets: @dev_default_targets,
|
293
|
+
js_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application.js'),
|
294
|
+
js_common_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_common.js'),
|
295
|
+
js_ssr_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_ssr.js'),
|
296
|
+
js_web_worker_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_web_worker.js'),
|
297
|
+
opal_directory: File.join(@conf_rel_prefix, @opal_directory),
|
298
|
+
stylesheets_directory: File.join(@conf_rel_prefix, @styles_directory),
|
299
|
+
hmr_hook: @hmr_hook
|
300
|
+
}
|
301
|
+
if @js_entrypoints_directory.start_with?('app')
|
302
|
+
erb_hash[:dev_server_before] = <<~JAVASCRIPT
|
303
|
+
// enable page reload for updates within the app/views directory
|
304
|
+
before: function(app, server) {
|
305
|
+
chokidar.watch(path.resolve(__dirname, path.join('..', '..', 'app', 'views'))).on('all', function () {
|
306
|
+
server.sockWrite(server.sockets, 'content-changed');
|
307
|
+
})
|
308
|
+
},
|
309
|
+
JAVASCRIPT
|
310
|
+
else
|
311
|
+
erb_hash[:dev_server_before] = <<~JAVASCRIPT
|
312
|
+
// uncomment to enable page reload for updates within another directory, which may contain just html files,
|
313
|
+
// for example the 'views' directory:
|
314
|
+
// before: function(app, server) {
|
315
|
+
// chokidar.watch(path.resolve(__dirname, path.join('..', 'views')).on('all', function () {
|
316
|
+
// server.sockWrite(server.sockets, 'content-changed');
|
317
|
+
// })
|
318
|
+
// },
|
319
|
+
JAVASCRIPT
|
320
|
+
end
|
321
|
+
create_file_from_template('debug.js.erb', File.join(@webpack_config_directory, 'debug.js'), erb_hash)
|
322
|
+
create_file_from_template('development.js.erb', File.join(@webpack_config_directory, 'development.js'), erb_hash)
|
323
|
+
erb_hash[:default_targets] = @pro_default_targets
|
324
|
+
create_file_from_template('production.js.erb', File.join(@webpack_config_directory, 'production.js'), erb_hash)
|
325
|
+
end
|
326
|
+
|
327
|
+
def install_webpacker_config
|
328
|
+
environment_js = File.read(File.join('config', 'webpack', 'environment.js'), mode: 'r')
|
329
|
+
new_environment_js = ''
|
330
|
+
environment_js.lines.each do |line|
|
331
|
+
new_environment_js << line
|
332
|
+
if line.start_with?('const { environment }')
|
333
|
+
new_environment_js << "\n"
|
334
|
+
new_environment_js << File.read(File.join(templates_path, 'webpacker.js'), mode: 'r')
|
335
|
+
new_environment_js << "\n"
|
336
|
+
end
|
337
|
+
end
|
338
|
+
File.write(File.join('config', 'webpack', 'environment.js'), new_environment_js)
|
339
|
+
end
|
340
|
+
|
341
|
+
def install_webpacker_js_entry
|
342
|
+
application_js = File.read(File.join('app', 'javascript', 'packs', 'application.js'), mode: 'r')
|
343
|
+
application_js << <<~JAVASCRIPT
|
344
|
+
|
345
|
+
// import and load opal ruby files
|
346
|
+
import init_app from '#{options[:opal_name]}_loader.rb';
|
347
|
+
init_app();
|
348
|
+
Opal.load('#{options[:opal_name]}_loader');
|
349
|
+
|
350
|
+
JAVASCRIPT
|
351
|
+
File.write(File.join('app', 'javascript', 'packs', 'application.js'), application_js)
|
352
|
+
end
|
353
|
+
|
354
|
+
def install_webpacker_package_json
|
355
|
+
package_json_file = File.read('package.json')
|
356
|
+
package_json = Oj.load(package_json_file, mode: :strict)
|
357
|
+
package_json["dependencies"]["opal-webpack-loader"] = "^#{OpalWebpackLoader::VERSION}"
|
358
|
+
File.write('package.json', Oj.dump(package_json, mode: :strict, indent: 2))
|
359
|
+
puts "Updated package.json for opal-webpack-loader"
|
360
|
+
end
|
361
|
+
|
362
|
+
def templates_path
|
363
|
+
File.realpath(File.join(File.dirname(File.realpath(__FILE__)), 'templates'))
|
364
|
+
end
|
365
|
+
|
366
|
+
def create_file_from_template(template_path, target_file_path, data_hash)
|
367
|
+
template = ERB.new(File.read(File.join(templates_path, template_path), mode: 'r'))
|
368
|
+
result = template.result_with_hash(data_hash)
|
369
|
+
if File.exist?(target_file_path)
|
370
|
+
ext = '_owl_new'
|
371
|
+
puts "#{target_file_path} exists, not overwriting, creating #{target_file_path + ext} instead."
|
372
|
+
else
|
373
|
+
ext = ''
|
374
|
+
puts "Creating #{target_file_path}."
|
375
|
+
end
|
376
|
+
|
377
|
+
File.write(target_file_path + ext, result, mode: 'w')
|
378
|
+
end
|
379
|
+
|
380
|
+
def add_gem
|
381
|
+
# TODO specifying a version results in bundler printing a error and not adding the gem
|
382
|
+
# `bundle add opal-webpack-loader -v "#{OpalWebpackLoader::VERSION}" --skip-install`ß´
|
383
|
+
end
|
384
|
+
|
385
|
+
def print_message
|
386
|
+
puts <<~TEXT
|
387
|
+
|
388
|
+
Add the following lines to your Gemfile:
|
389
|
+
|
390
|
+
gem 'opal', github: 'janbiedermann/opal', branch: 'es6_modules_1_2'
|
391
|
+
gem 'opal-webpack-loader', '~> #{OpalWebpackLoader::VERSION}'
|
392
|
+
|
393
|
+
owl currently works only with above opal branch. If you have a existing "gem 'opal'", please replace it with above line.
|
394
|
+
|
395
|
+
Also check above output for files ending in '_owl_new' and merge their contents with the existing files.
|
396
|
+
|
397
|
+
After that run according to your preference either:
|
398
|
+
|
399
|
+
yarn install
|
400
|
+
|
401
|
+
or:
|
402
|
+
|
403
|
+
npm install
|
404
|
+
|
405
|
+
and then:
|
406
|
+
|
407
|
+
bundle install
|
408
|
+
|
409
|
+
For further instructions see http://github.com/isomorfeus/opal-webpack-loader
|
410
|
+
|
411
|
+
TEXT
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|