opal-webpack-loader 0.6.6 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6fddd8a389b2b937b326028f4526acde3fa4684a07494c35171d48129f75a53
4
- data.tar.gz: 96b0a819a4715984f48d9813f1a70107e6f945a00e24feca6834a4a82e97251a
3
+ metadata.gz: 0d16462b0c87b2e4b5bfd45379a397ed582943e2d392080e58c44b81cbd500db
4
+ data.tar.gz: 6c0274bbc3dacbb1c735bf4078526a1669512ba1074d318b28018067ce70563d
5
5
  SHA512:
6
- metadata.gz: 886a5692649c816ea1c84de476ab36b763e2dcb2e95ca15a83ccaaf153e6354a4e9a5903a59ad644b9efb63e28d4fe01a28e8d04ceb723ce7888c83043456553
7
- data.tar.gz: 30e45fe1b42b7007f53726529afc979d9c0a71b60a062e535ce97030344bcf419996eda241f5371b14e3426b987a7c359b4de48c4294298c0ee64ecf8476f538
6
+ metadata.gz: 1b41086c5835da79c0199c0a259aafab20bd96f68e07097321c6426e7b0e464f11e1e7e724064f009bdf0a50643450f77e341665ad5d9ace677c0f18701113f3
7
+ data.tar.gz: ccf1621264e8a7109f804dcf9a8f61d328dcd2ebca83087a7c6d84f22928558695dcb1d1d3c652bfac5cc8fe1ab7aa2360d4f506cfbfd3ec5fd6335896744580
@@ -1,38 +1,57 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'opal-webpack-loader/compile_server'
3
+ require 'opal-webpack-loader/compile_worker'
4
+ require 'opal-webpack-loader/load_path_manager'
3
5
  require 'open3'
4
6
 
7
+ at_exit do
8
+ if OpalWebpackLoader::CompileServer.unlink_socket?
9
+ if File.exist?(OpalWebpackLoader::CompileServer::OWCS_SOCKET_PATH)
10
+ File.unlink(OpalWebpackLoader::CompileServer::OWCS_SOCKET_PATH)
11
+ end
12
+ end
13
+ end
14
+
5
15
  puts "args: #{ARGV}"
6
16
 
7
17
  if ARGV[0] == 'stop' || ARGV[0] == 'kill'
8
- OpalWebpackCompileServer::Exe.stop
18
+ OpalWebpackLoader::CompileServer.stop
9
19
  else
10
20
  if ARGV[0] == 'start'
11
- OpalWebpackCompileServer::Exe.stop
12
- runargs = ARGV[1..-1]
21
+ OpalWebpackLoader::CompileServer.stop(false)
22
+ number_of_workers = ARGV[1].to_i
23
+ if number_of_workers == 0
24
+ number_of_workers == 4
25
+ runargs = ARGV[1..-1]
26
+ else
27
+ runargs = ARGV[2..-1]
28
+ end
13
29
  else
14
- runargs = ARGV
30
+ raise 'arguments must be either "stop" or "start number_of_workers process_to_run --with args"'
31
+ exit(1)
15
32
  end
16
33
 
17
- pid = fork { OpalWebpackCompileServer::Exe.run }
34
+ OpalWebpackLoader::LoadPathManager.create_load_paths_cache
35
+
36
+ pid = fork { OpalWebpackLoader::CompileServer.new.start(number_of_workers) }
18
37
 
19
38
  have_socket = false
20
39
  start_time = Time.now
21
40
  begin
22
41
  until have_socket
23
- if File.exist?(OpalWebpackCompileServer::OWCS_SOCKET_PATH)
42
+ if File.exist?(OpalWebpackLoader::CompileServer::OWCS_SOCKET_PATH)
24
43
  have_socket = true
25
44
  else
26
45
  if Time.now - start_time > 60
27
46
  puts "opal-webpack-compile-server didnt start in time. Exiting"
28
- OpalWebpackCompileServer::Exe.stop(false)
47
+ OpalWebpackLoader::CompileServer.stop(false)
29
48
  Process.kill("TERM", pid)
30
49
  exit 1
31
50
  end
32
51
  end
33
52
  end
34
53
  rescue Exception => e
35
- OpalWebpackCompileServer::Exe.stop(false)
54
+ OpalWebpackLoader::CompileServer.stop(false)
36
55
  puts "opal-webpack-compile-server couldn't start:"
37
56
  puts e.backtrace.join("\n")
38
57
  puts e.message
@@ -54,7 +73,7 @@ else
54
73
 
55
74
  thread.join # don't exit until the external process is done
56
75
  end
57
- rescue Interrupt => e
76
+ rescue Interrupt
58
77
  puts "opal-webpack-compile-server got interrupted. Exiting with drama."
59
78
  Process.kill("TERM", pid)
60
79
  exit 0
@@ -1,173 +1,142 @@
1
- require 'oj'
2
- require 'eventmachine'
3
- require 'opal/paths'
4
- require 'opal/source_map'
5
- require 'source_map'
6
- require 'opal/compiler'
7
1
  require 'socket'
8
2
 
9
- at_exit do
10
- if OpalWebpackCompileServer::Exe.unlink_socket?
11
- if File.exist?(OpalWebpackCompileServer::OWCS_SOCKET_PATH)
12
- File.unlink(OpalWebpackCompileServer::OWCS_SOCKET_PATH)
13
- end
14
- end
15
- end
16
-
17
- module OpalWebpackCompileServer
18
- OWL_CACHE_DIR = './.owl_cache/'
19
- OWL_LP_CACHE = OWL_CACHE_DIR + 'load_paths.json'
20
- OWCS_SOCKET_PATH = OWL_CACHE_DIR + 'owcs_socket'
3
+ module OpalWebpackLoader
4
+ class CompileServer
5
+ OWL_CACHE_DIR = File.join('.','.owl_cache/')
6
+ OWL_LP_CACHE = File.join(OWL_CACHE_DIR, 'load_paths.json')
7
+ OWCS_SOCKET_PATH = File.join(OWL_CACHE_DIR, 'owcs_socket')
8
+ SIGNALS = %w[QUIT INT TERM TTIN TTOU]
9
+ TIMEOUT = 15
21
10
 
22
- class Compiler < EventMachine::Connection
23
- def initialize(*args)
24
- @received_data = ''
25
- super(*args)
11
+ def self.unlink_socket?
12
+ @unlink
26
13
  end
27
14
 
28
- def receive_data(data)
29
- @received_data << data
15
+ def self.unlink_socket_on_exit
16
+ @unlink = true
17
+ end
30
18
 
31
- return unless @received_data.end_with?("}\x04")
19
+ def self.dont_unlink_socket_on_exit
20
+ @unlink = false
21
+ end
32
22
 
33
- if @received_data.start_with?('command:stop')
34
- EventMachine.stop
35
- exit(0)
23
+ def self.stop(do_exit = true)
24
+ if File.exist?(OWCS_SOCKET_PATH)
25
+ dont_unlink_socket_on_exit
26
+ begin
27
+ s = UNIXSocket.new(OWCS_SOCKET_PATH)
28
+ s.send("command:stop\x04", 0)
29
+ s.close
30
+ rescue
31
+ # socket cant be reached so owlcs is already dead, delete socket
32
+ unlink_socket_on_exit
33
+ end
34
+ exit(0) if do_exit
36
35
  end
36
+ end
37
37
 
38
- request_json = Oj.load(@received_data.chop!, {})
39
-
40
- @received_data = ''
41
-
42
- compile_source_map = request_json["source_map"]
43
- filename = request_json["filename"]
44
- source = File.read(filename)
38
+ def initialize
39
+ @read_pipe, @write_pipe = IO.pipe
40
+ @workers = {}
41
+ @signal_queue = []
42
+ end
45
43
 
46
- operation = proc do
47
- begin
48
- c = Opal::Compiler.new(source, file: filename, es6_modules: true)
49
- c.compile
50
- result = { 'javascript' => c.result }
51
- if compile_source_map
52
- result['source_map'] = c.source_map.as_json
53
- result['source_map']['sourcesContent'] = [source]
54
- result['source_map']['file'] = filename
55
- result['source_map']['names'] = result['source_map']['names'].map(&:to_s)
44
+ def start(number_of_workers = 4)
45
+ $PROGRAM_NAME = 'owl compile server'
46
+ @number_of_workers = number_of_workers
47
+ @server_pid = Process.pid
48
+ $stderr.sync = $stdout.sync = true
49
+ @socket = UNIXServer.new(OWCS_SOCKET_PATH)
50
+ spawn_workers
51
+ SIGNALS.each { |sig| trap_deferred(sig) }
52
+ trap('CHLD') { @write_pipe.write_nonblock('.') }
53
+
54
+ loop do
55
+ reap_workers
56
+ case (mode = @signal_queue.shift)
57
+ when nil
58
+ kill_runaway_workers
59
+ spawn_workers
60
+ when 'QUIT', 'TERM', 'INT'
61
+ @workers.each_pair do |pid, _worker|
62
+ Process.kill('TERM', pid)
63
+ end
64
+ break
65
+ when 'TTIN'
66
+ @number_of_workers += 1
67
+ when 'TTOU'
68
+ unless @number_of_workers <= 0
69
+ Config.workers -= 1
70
+ kill_worker('QUIT', @workers.keys.max)
56
71
  end
57
- result['required_trees'] = c.required_trees
58
- Oj.dump(result, {})
59
- rescue Exception => e
60
- Oj.dump({ 'error' => { 'name' => e.class, 'message' => e.message, 'backtrace' => e.backtrace.join("\n") } }, {})
61
72
  end
73
+ reap_workers
74
+ ready = IO.select([@read_pipe], nil, nil, 1) || next
75
+ ready.first && ready.first.first || next
76
+ @read_pipe.read_nonblock(1)
77
+ OpalWebpackLoader::CompileServer.unlink_socket_on_exit
62
78
  end
63
-
64
- callback = proc do |json|
65
- self.send_data(json)
66
- close_connection_after_writing
67
- end
68
-
69
- EM.defer(operation, callback)
70
79
  end
71
- end
72
80
 
73
- class LoadPathManager
74
- def self.get_load_path_entries(path)
75
- path_entries = []
76
- return [] unless Dir.exist?(path)
77
- dir_entries = Dir.entries(path)
78
- dir_entries.each do |entry|
79
- next if entry == '.'
80
- next if entry == '..'
81
- next unless entry
82
- absolute_path = File.join(path, entry)
83
- if File.directory?(absolute_path)
84
- more_path_entries = get_load_path_entries(absolute_path)
85
- path_entries.push(*more_path_entries) if more_path_entries.size > 0
86
- elsif (absolute_path.end_with?('.rb') || absolute_path.end_with?('.js')) && File.file?(absolute_path)
87
- path_entries.push(absolute_path)
88
- end
81
+ private
82
+
83
+ def reap_workers
84
+ loop do
85
+ pid, status = Process.waitpid2(-1, Process::WNOHANG) || break
86
+ reap_worker(pid, status)
89
87
  end
90
- path_entries
88
+ rescue Errno::ECHILD
91
89
  end
92
90
 
93
- def self.get_load_paths
94
- load_paths = if File.exist?(File.join('bin', 'rails'))
95
- %x{
96
- bundle exec rails runner "puts (Rails.configuration.respond_to?(:assets) ? (Rails.configuration.assets.paths + Opal.paths).uniq : Opal.paths)"
97
- }
98
- else
99
- %x{
100
- bundle exec ruby -e 'if File.exist?("app_loader.rb"); require "./app_loader.rb"; else; require "bundler/setup"; Bundler.require; set :run, false if defined? Sinatra; end; puts Opal.paths'
101
- }
102
- end
103
- if $? == 0
104
- load_path_lines = load_paths.split("\n")
105
- load_path_lines.pop if load_path_lines.last == ''
106
-
107
- load_path_entries = []
108
-
109
- cwd = Dir.pwd
110
-
111
- load_path_lines.each do |path|
112
- next if path.start_with?(cwd)
113
- more_path_entries = get_load_path_entries(path)
114
- load_path_entries.push(*more_path_entries) if more_path_entries.size > 0
115
- end
116
- cache_obj = { 'opal_load_paths' => load_path_lines, 'opal_load_path_entries' => load_path_entries }
117
- Dir.mkdir(OpalWebpackCompileServer::OWL_CACHE_DIR) unless Dir.exist?(OpalWebpackCompileServer::OWL_CACHE_DIR)
118
- File.write(OpalWebpackCompileServer::OWL_LP_CACHE, Oj.dump(cache_obj, {}))
119
- load_path_lines
120
- else
121
- raise 'Error getting load paths!'
122
- exit(2)
91
+ def reap_worker(pid, status)
92
+ worker = @workers.delete(pid)
93
+ begin
94
+ worker.tempfile.close
95
+ rescue
96
+ nil
123
97
  end
98
+ puts "OpalWebpackLoader::CompileServer: Reaped worker #{worker.number} (PID:#{pid}) status: #{status.exitstatus}"
124
99
  end
125
- end
126
100
 
127
- class Exe
128
- def self.unlink_socket?
129
- @unlink
101
+ def kill_worker(signal, pid)
102
+ Process.kill(signal, pid)
103
+ rescue Errno::ESRCH
130
104
  end
131
105
 
132
- def self.unlink_on_exit
133
- @unlink = true
106
+ def kill_runaway_workers
107
+ now = Time.now
108
+ @workers.each_pair do |pid, worker|
109
+ (now - worker.tempfile.ctime) <= TIMEOUT && next
110
+ $stderr.puts "worker #{worker.number} (PID:#{pid}) has timed out"
111
+ kill_worker('KILL', pid)
112
+ end
134
113
  end
135
114
 
136
- def self.dont_unlink_on_exit
137
- @unlink = false
115
+ def init_worker(worker)
116
+ @write_pipe.close
117
+ @read_pipe.close
118
+ @workers.each_pair { |_, w| w.tempfile.close }
119
+ worker.start
138
120
  end
139
121
 
140
- def self.stop(do_exit = true)
141
- if File.exist?(OWCS_SOCKET_PATH)
142
- dont_unlink_on_exit
143
- begin
144
- s = UNIXSocket.new(OWCS_SOCKET_PATH)
145
- s.send("command:stop\n", 0)
146
- s.close
147
- rescue
148
- # socket cant be reached so owcs is already dead, delete socket
149
- unlink_on_exit
150
- end
151
- exit(0) if do_exit
122
+ def spawn_workers
123
+ worker_number = -1
124
+ until (worker_number += 1) == @number_of_workers
125
+ @workers.value?(worker_number) && next
126
+ tempfile = Tempfile.new('')
127
+ tempfile.unlink
128
+ tempfile.sync = true
129
+ worker = OpalWebpackLoader::CompileWorker.new(@server_pid, @socket, tempfile, worker_number)
130
+ pid = fork { init_worker(worker) }
131
+ @workers[pid] = worker
152
132
  end
153
133
  end
154
134
 
155
- def self.run
156
- if File.exist?(OWCS_SOCKET_PATH) # OWCS already running
157
- puts 'Another Opal Webpack Compile Server already running, exiting'
158
- dont_unlink_on_exit
159
- exit(1)
160
- else
161
- unlink_on_exit
162
- load_paths = OpalWebpackCompileServer::LoadPathManager.get_load_paths
163
- if load_paths
164
- Opal.append_paths(*load_paths)
165
- # Process.daemon(true)
166
- EventMachine.run do
167
- EventMachine.start_unix_domain_server(OWCS_SOCKET_PATH, OpalWebpackCompileServer::Compiler)
168
- end
169
- end
135
+ def trap_deferred(signal)
136
+ trap(signal) do |_|
137
+ @signal_queue << signal
138
+ @write_pipe.write_nonblock('.')
170
139
  end
171
140
  end
172
141
  end
173
- end
142
+ end
@@ -0,0 +1,96 @@
1
+ require 'oj'
2
+ require 'opal/paths'
3
+ require 'opal/source_map'
4
+ require 'source_map'
5
+ require 'opal/compiler'
6
+ require 'socket'
7
+
8
+ module OpalWebpackLoader
9
+ class CompileWorker
10
+ SIGNALS = %w[QUIT TTIN TTOU]
11
+
12
+ attr_reader :number, :tempfile
13
+
14
+ def initialize(master_pid, socket, tempfile, number)
15
+ @master_pid = master_pid
16
+ @socket = socket
17
+ @tempfile = tempfile
18
+ @number = number
19
+ end
20
+
21
+ def ==(other_number)
22
+ number == other_number
23
+ end
24
+
25
+ def start
26
+ $PROGRAM_NAME = "owl compile worker #{number}"
27
+ SIGNALS.each { |sig| trap(sig, 'IGNORE') }
28
+ trap('CHLD', 'DEFAULT')
29
+ alive = true
30
+ %w[TERM INT].each { |sig| trap(sig) { exit(0) } }
31
+ trap('QUIT') do
32
+ alive = false
33
+ begin
34
+ @socket.close
35
+ rescue
36
+ nil
37
+ end
38
+ end
39
+ ret = nil
40
+ i = 0
41
+ while alive && @master_pid == Process.ppid
42
+ tempfile.chmod(i += 1)
43
+
44
+ if ret
45
+ begin
46
+ client = @socket.accept_nonblock
47
+ request = client.gets("\x04")
48
+
49
+ if request.start_with?('command:stop')
50
+ OpalWebpackLoader::CompileServer.unlink_socket_on_exit
51
+ Process.kill('TERM', @master_pid)
52
+ exit(0)
53
+ else
54
+ result = compile(request)
55
+ client.write result
56
+ client.flush
57
+ client.close
58
+ end
59
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
60
+ end
61
+ end
62
+ tempfile.chmod(i += 1)
63
+ ret = begin
64
+ IO.select([@socket], nil, nil, OpalWebpackLoader::CompileServer::TIMEOUT / 2) || next
65
+ rescue Errno::EBADF
66
+ end
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def compile(request)
73
+ request_json = Oj.load(request.chop!, {})
74
+
75
+ compile_source_map = request_json["source_map"]
76
+ filename = request_json["filename"]
77
+ source = File.read(filename)
78
+
79
+ begin
80
+ c = Opal::Compiler.new(source, file: filename, es6_modules: true)
81
+ c.compile
82
+ result = { 'javascript' => c.result }
83
+ if compile_source_map
84
+ result['source_map'] = c.source_map.as_json
85
+ result['source_map']['sourcesContent'] = [source]
86
+ result['source_map']['file'] = filename
87
+ result['source_map']['names'] = result['source_map']['names'].map(&:to_s)
88
+ end
89
+ result['required_trees'] = c.required_trees
90
+ Oj.dump(result, {})
91
+ rescue Exception => e
92
+ Oj.dump({ 'error' => { 'name' => e.class, 'message' => e.message, 'backtrace' => e.backtrace.join("\n") } }, {})
93
+ end
94
+ end
95
+ end
96
+ end
@@ -162,7 +162,7 @@ module OpalWebpackLoader
162
162
  install_webpack_config
163
163
  install_package_json
164
164
  install_js_entries
165
- install_opal_entry
165
+ install_opal_entries
166
166
  install_procfile
167
167
  end
168
168
 
@@ -172,10 +172,12 @@ module OpalWebpackLoader
172
172
  create_file_from_template('application_common.js.erb', File.join(@js_entrypoints_directory, 'application_common.js'),erb_hash)
173
173
  create_file_from_template('application_debug.js.erb', File.join(@js_entrypoints_directory, 'application_debug.js'), erb_hash)
174
174
  create_file_from_template('application_ssr.js.erb', File.join(@js_entrypoints_directory, 'application_ssr.js'), erb_hash)
175
+ create_file_from_template('application_web_worker.js.erb', File.join(@js_entrypoints_directory, 'application_web_worker.js'), erb_hash)
175
176
  end
176
177
 
177
- def install_opal_entry
178
+ def install_opal_entries
178
179
  create_file_from_template('opal_loader.rb.erb', File.join(@opal_directory, "#{options[:opal_name]}_loader.rb"), {})
180
+ create_file_from_template('opal_web_worker_loader.rb.erb', File.join(@opal_directory, "#{options[:opal_name]}_web_worker_loader.rb"), {})
179
181
  end
180
182
 
181
183
  def install_package_json
@@ -226,24 +228,26 @@ module OpalWebpackLoader
226
228
  end
227
229
 
228
230
  def debug_script
229
- "bundle exec opal-webpack-compile-server start webpack-dev-server --config #{File.join(@webpack_config_directory, 'debug.js')}"
231
+ "bundle exec opal-webpack-compile-server start 4 webpack-dev-server --config #{File.join(@webpack_config_directory, 'debug.js')}"
230
232
  end
231
233
 
232
234
  def development_script
233
- "bundle exec opal-webpack-compile-server start webpack-dev-server --config #{File.join(@webpack_config_directory, 'development.js')}"
235
+ "bundle exec opal-webpack-compile-server start 4 webpack-dev-server --config #{File.join(@webpack_config_directory, 'development.js')}"
234
236
  end
235
237
 
236
238
  def production_script
237
- "bundle exec opal-webpack-compile-server start webpack --config=#{File.join(@webpack_config_directory, 'production.js')}"
239
+ "bundle exec opal-webpack-compile-server start 4 webpack --config=#{File.join(@webpack_config_directory, 'production.js')}"
238
240
  end
239
241
 
240
242
  def install_webpack_config
241
243
  erb_hash = {
242
244
  asset_output_directory: File.join(@conf_rel_prefix, @asset_output_directory),
245
+ default_targets: 'browser',
243
246
  js_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application.js'),
244
247
  js_common_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_common.js'),
245
248
  js_debug_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_debug.js'),
246
249
  js_ssr_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_ssr.js'),
250
+ js_web_worker_entry: File.join(@conf_rel_prefix, @js_entrypoints_directory, 'application_web_worker.js'),
247
251
  opal_directory: File.join(@conf_rel_prefix, @opal_directory),
248
252
  stylesheets_directory: File.join(@conf_rel_prefix, @styles_directory),
249
253
  hmr_hook: ''
@@ -0,0 +1,55 @@
1
+ module OpalWebpackLoader
2
+ class LoadPathManager
3
+ def self.get_load_path_entries(path)
4
+ path_entries = []
5
+ return [] unless Dir.exist?(path)
6
+ dir_entries = Dir.entries(path)
7
+ dir_entries.each do |entry|
8
+ next if entry == '.'
9
+ next if entry == '..'
10
+ next unless entry
11
+ absolute_path = File.join(path, entry)
12
+ if File.directory?(absolute_path)
13
+ more_path_entries = get_load_path_entries(absolute_path)
14
+ path_entries.push(*more_path_entries) if more_path_entries.size > 0
15
+ elsif (absolute_path.end_with?('.rb') || absolute_path.end_with?('.js')) && File.file?(absolute_path)
16
+ path_entries.push(absolute_path)
17
+ end
18
+ end
19
+ path_entries
20
+ end
21
+
22
+ def self.create_load_paths_cache
23
+ load_paths = if File.exist?(File.join('bin', 'rails'))
24
+ %x{
25
+ bundle exec rails runner "puts (Rails.configuration.respond_to?(:assets) ? (Rails.configuration.assets.paths + Opal.paths).uniq : Opal.paths)"
26
+ }
27
+ else
28
+ %x{
29
+ bundle exec ruby -e 'if File.exist?("app_loader.rb"); require "./app_loader.rb"; else; require "bundler/setup"; Bundler.require; set :run, false if defined? Sinatra; end; puts Opal.paths'
30
+ }
31
+ end
32
+ if $? == 0
33
+ load_path_lines = load_paths.split("\n")
34
+ load_path_lines.pop if load_path_lines.last == ''
35
+
36
+ load_path_entries = []
37
+
38
+ cwd = Dir.pwd
39
+
40
+ load_path_lines.each do |path|
41
+ next if path.start_with?(cwd)
42
+ more_path_entries = get_load_path_entries(path)
43
+ load_path_entries.push(*more_path_entries) if more_path_entries.size > 0
44
+ end
45
+ cache_obj = { 'opal_load_paths' => load_path_lines, 'opal_load_path_entries' => load_path_entries }
46
+ Dir.mkdir(OpalWebpackLoader::CompileServer::OWL_CACHE_DIR) unless Dir.exist?(OpalWebpackLoader::CompileServer::OWL_CACHE_DIR)
47
+ File.write(OpalWebpackLoader::CompileServer::OWL_LP_CACHE, Oj.dump(cache_obj, {}))
48
+ load_path_lines
49
+ else
50
+ raise 'Error getting load paths!'
51
+ exit(2)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,11 @@
1
+ // entry file for browser webworkers
2
+ // import npm modules that are only valid to use within browser webworkers
3
+ // import ...;
4
+
5
+ // import and load opal ruby files
6
+ import init_webworker from '<%= opal_name %>_webworker_loader.rb';
7
+ init_webworker();
8
+ Opal.load('<%= opal_name %>_webworker_loader');
9
+
10
+ // allow for hot reloading
11
+ if (module.hot) { module.hot.accept(); }
@@ -5,7 +5,7 @@ const chokidar = require('chokidar');
5
5
  const OwlResolver = require('opal-webpack-loader/resolver'); // to resolve ruby files
6
6
  const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); // to watch for added ruby files
7
7
 
8
- module.exports = {
8
+ const common_config = {
9
9
  context: path.resolve(__dirname, '<%= opal_directory %>'),
10
10
  mode: "development",
11
11
  optimization: {
@@ -20,10 +20,6 @@ module.exports = {
20
20
  // devtool: 'cheap-eval-source-map', // less accurate
21
21
  // devtool: 'inline-source-map', // slowest
22
22
  // devtool: 'inline-cheap-source-map',
23
- entry: {
24
- application: [path.resolve(__dirname, '<%= js_debug_entry %>')],
25
- application_ssr: [path.resolve(__dirname, '<%= js_ssr_entry %>')]
26
- },
27
23
  output: {
28
24
  // webpack-dev-server keeps the output in memory
29
25
  filename: '[name].js',
@@ -145,8 +141,36 @@ module.exports = {
145
141
  // poll: 50,
146
142
  ignored: /\bnode_modules\b/
147
143
  },
148
- contentBase: path.resolve(__dirname, 'public')
149
- // watchContentBase: true
144
+ contentBase: path.resolve(__dirname, 'public'),
145
+ // watchContentBase: true,
146
+ // writeToDisk: true, // TODO this may need to be activated for ssr to work in development
147
+ useLocalIp: true
150
148
  }
151
149
  };
152
150
 
151
+ const browser_config = {
152
+ target: 'web',
153
+ entry: {
154
+ application: [path.resolve(__dirname, '<%= js_entry %>')]
155
+ }
156
+ };
157
+
158
+ const ssr_config = {
159
+ target: 'node',
160
+ entry: {
161
+ application_ssr: [path.resolve(__dirname, '<%= js_ssr_entry %>')]
162
+ }
163
+ };
164
+
165
+ const web_worker_config = {
166
+ target: 'webworker',
167
+ entry: {
168
+ web_worker: [path.resolve(__dirname, '<%= js_web_worker_entry %>')]
169
+ }
170
+ };
171
+
172
+ const browser = Object.assign({}, common_config, browser_config);
173
+ const ssr = Object.assign({}, common_config, ssr_config);
174
+ const web_worker = Object.assign({}, common_config, web_worker_config);
175
+
176
+ module.exports = [ <%= default_targets %> ];
@@ -5,7 +5,7 @@ const chokidar = require('chokidar');
5
5
  const OwlResolver = require('opal-webpack-loader/resolver'); // to resolve ruby files
6
6
  const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); // to watch for added ruby files
7
7
 
8
- module.exports = {
8
+ const common_config = {
9
9
  context: path.resolve(__dirname, '<%= opal_directory %>'),
10
10
  mode: "development",
11
11
  optimization: {
@@ -15,10 +15,6 @@ module.exports = {
15
15
  maxAssetSize: 20000000,
16
16
  maxEntrypointSize: 20000000
17
17
  },
18
- entry: {
19
- application: [path.resolve(__dirname, '<%= js_entry %>')],
20
- application_ssr: [path.resolve(__dirname, '<%= js_ssr_entry %>')]
21
- },
22
18
  output: {
23
19
  // webpack-dev-server keeps the output in memory
24
20
  filename: '[name].js',
@@ -129,8 +125,36 @@ module.exports = {
129
125
  // poll: 50,
130
126
  ignored: /\bnode_modules\b/
131
127
  },
132
- contentBase: path.resolve(__dirname, 'public')
133
- // watchContentBase: true
128
+ contentBase: path.resolve(__dirname, 'public'),
129
+ // watchContentBase: true,
130
+ // writeToDisk: true,
131
+ useLocalIp: true
134
132
  }
135
133
  };
136
134
 
135
+ const browser_config = {
136
+ target: 'web',
137
+ entry: {
138
+ application: [path.resolve(__dirname, '<%= js_entry %>')]
139
+ }
140
+ };
141
+
142
+ const ssr_config = {
143
+ target: 'node',
144
+ entry: {
145
+ application_ssr: [path.resolve(__dirname, '<%= js_ssr_entry %>')]
146
+ }
147
+ };
148
+
149
+ const web_worker_config = {
150
+ target: 'webworker',
151
+ entry: {
152
+ webworker: [path.resolve(__dirname, '<%= js_web_worker_entry %>')]
153
+ }
154
+ };
155
+
156
+ const browser = Object.assign({}, common_config, browser_config);
157
+ const ssr = Object.assign({}, common_config, ssr_config);
158
+ const web_worker = Object.assign({}, common_config, web_worker_config);
159
+
160
+ module.exports = [ <%= default_targets %> ];
@@ -0,0 +1,9 @@
1
+ require 'opal'
2
+
3
+ # the gem opal-autoloader may be used, so its not necessary to use 'require' all the time,
4
+ # just using 'require_tree' to bundle everything is enough:
5
+ #
6
+ # require 'opal-autoloader'
7
+ # require_tree 'my_app' # for a sub directory 'my_app'
8
+
9
+
@@ -3,7 +3,7 @@ const OwlResolver = require('opal-webpack-loader/resolver');
3
3
  const CompressionPlugin = require("compression-webpack-plugin"); // for gzipping the packs
4
4
  const ManifestPlugin = require('webpack-manifest-plugin'); // for generating the manifest
5
5
 
6
- module.exports = {
6
+ const common_config = {
7
7
  context: path.resolve(__dirname, '<%= opal_directory %>'),
8
8
  mode: "production",
9
9
  optimization: {
@@ -13,10 +13,6 @@ module.exports = {
13
13
  maxAssetSize: 20000000,
14
14
  maxEntrypointSize: 20000000
15
15
  },
16
- entry: {
17
- application: [path.resolve(__dirname, '<%= js_entry %>')],
18
- application_ssr: [path.resolve(__dirname, '<%= js_ssr_entry %>')]
19
- },
20
16
  output: {
21
17
  filename: '[name]-[chunkhash].js', // include fingerprint in file name, so browsers get the latest
22
18
  path: path.resolve(__dirname, '<%= asset_output_directory %>'),
@@ -92,3 +88,29 @@ module.exports = {
92
88
  }
93
89
  };
94
90
 
91
+ const browser_config = {
92
+ target: 'web',
93
+ entry: {
94
+ application: [path.resolve(__dirname, '<%= js_entry %>')]
95
+ }
96
+ };
97
+
98
+ const ssr_config = {
99
+ target: 'node',
100
+ entry: {
101
+ application_ssr: [path.resolve(__dirname, '<%= js_ssr_entry %>')]
102
+ }
103
+ };
104
+
105
+ const web_worker_config = {
106
+ target: 'webworker',
107
+ entry: {
108
+ web_worker: [path.resolve(__dirname, '<%= js_web_worker_entry %>')]
109
+ }
110
+ };
111
+
112
+ const browser = Object.assign({}, common_config, browser_config);
113
+ const ssr = Object.assign({}, common_config, ssr_config);
114
+ const web_worker = Object.assign({}, common_config, web_worker_config);
115
+
116
+ module.exports = [ <%= default_targets %> ];
@@ -1,3 +1,3 @@
1
1
  module OpalWebpackLoader
2
- VERSION="0.6.6"
2
+ VERSION="0.7.0"
3
3
  end
@@ -27,7 +27,9 @@ RSpec.describe 'owl installer' do
27
27
  expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_common.js'))).to be true
28
28
  expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_debug.js'))).to be true
29
29
  expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_ssr.js'))).to be true
30
+ expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_web_worker.js'))).to be true
30
31
  expect(File.exist?(File.join('app', 'opal', 'opal_loader.rb'))).to be true
32
+ expect(File.exist?(File.join('app', 'opal', 'opal_web_worker_loader.rb'))).to be true
31
33
  expect(File.exist?(File.join('config', 'initializers', 'opal_webpack_loader.rb'))).to be true
32
34
  expect(File.exist?(File.join('config', 'webpack', 'debug.js'))).to be true
33
35
  expect(File.exist?(File.join('config', 'webpack', 'development.js'))).to be true
@@ -48,7 +50,9 @@ RSpec.describe 'owl installer' do
48
50
  expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_common.js'))).to be true
49
51
  expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_debug.js'))).to be true
50
52
  expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_ssr.js'))).to be true
53
+ expect(File.exist?(File.join('app', 'assets', 'javascripts', 'application_web_worker.js'))).to be true
51
54
  expect(File.exist?(File.join('app', 'hyperhyper', 'hyperhyper_loader.rb'))).to be true
55
+ expect(File.exist?(File.join('app', 'hyperhyper', 'hyperhyper_web_worker_loader.rb'))).to be true
52
56
  expect(File.exist?(File.join('config', 'initializers', 'opal_webpack_loader.rb'))).to be true
53
57
  expect(File.exist?(File.join('config', 'webpack', 'debug.js'))).to be true
54
58
  expect(File.exist?(File.join('config', 'webpack', 'development.js'))).to be true
data/spec/owl_spec.rb CHANGED
@@ -15,19 +15,18 @@ RSpec.describe 'owl' do
15
15
 
16
16
  after do
17
17
  Dir.chdir('..') if Dir.pwd.end_with?('railing')
18
- # FileUtils.rm_rf('railing') if Dir.exist?('railing')
18
+ FileUtils.rm_rf('railing') if Dir.exist?('railing')
19
19
  Dir.chdir('..')
20
20
  Dir.chdir('..')
21
21
  end
22
22
 
23
23
  it 'can run the production build script' do
24
- `bundle exec rails new railing --skip-git --skip-bundle --skip-sprockets --skip-spring --skip-bootsnap`
24
+ `bundle exec rails new railing --skip-git --skip-bundle --skip-sprockets --skip-javascript --skip-spring --skip-bootsnap`
25
25
  expect(Dir.exist?('railing')).to be true
26
26
  Dir.chdir('railing')
27
27
  arg_val = %w[rails]
28
28
  expect(Dir.exist?(File.join('railing', 'config', 'webpack'))).to be false
29
29
  OpalWebpackLoader::Installer::CLI.start(arg_val)
30
- FileUtils.mv(File.join('app', 'assets', 'javascripts', 'application.js_owl_new'), File.join('app', 'assets', 'javascripts', 'application.js´'))
31
30
  gemfile = File.read('Gemfile')
32
31
  gemfile << <<~GEMS
33
32
 
@@ -67,7 +66,7 @@ RSpec.describe 'owl' do
67
66
 
68
67
  after do
69
68
  Dir.chdir('..') if Dir.pwd.end_with?('flattering')
70
- #FileUtils.rm_rf('flattering') if Dir.exist?('flattering')
69
+ FileUtils.rm_rf('flattering') if Dir.exist?('flattering')
71
70
  Dir.chdir('..')
72
71
  Dir.chdir('..')
73
72
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-webpack-loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-28 00:00:00.000000000 Z
11
+ date: 2019-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.11.0
27
- - !ruby/object:Gem::Dependency
28
- name: eventmachine
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 1.2.7
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 1.2.7
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: oj
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +136,9 @@ files:
150
136
  - bin/owl-install
151
137
  - lib/opal-webpack-loader.rb
152
138
  - lib/opal-webpack-loader/compile_server.rb
139
+ - lib/opal-webpack-loader/compile_worker.rb
153
140
  - lib/opal-webpack-loader/installer_cli.rb
141
+ - lib/opal-webpack-loader/load_path_manager.rb
154
142
  - lib/opal-webpack-loader/manifest.rb
155
143
  - lib/opal-webpack-loader/rails_view_helper.rb
156
144
  - lib/opal-webpack-loader/templates/Procfile.erb
@@ -160,10 +148,12 @@ files:
160
148
  - lib/opal-webpack-loader/templates/application_common.js.erb
161
149
  - lib/opal-webpack-loader/templates/application_debug.js.erb
162
150
  - lib/opal-webpack-loader/templates/application_ssr.js.erb
151
+ - lib/opal-webpack-loader/templates/application_web_worker.js.erb
163
152
  - lib/opal-webpack-loader/templates/debug.js.erb
164
153
  - lib/opal-webpack-loader/templates/development.js.erb
165
154
  - lib/opal-webpack-loader/templates/initializer.rb.erb
166
155
  - lib/opal-webpack-loader/templates/opal_loader.rb.erb
156
+ - lib/opal-webpack-loader/templates/opal_web_worker_loader.rb.erb
167
157
  - lib/opal-webpack-loader/templates/package.json.erb
168
158
  - lib/opal-webpack-loader/templates/production.js.erb
169
159
  - lib/opal-webpack-loader/templates/webpacker_development.js_example