jetpacker 0.1.0 → 0.2.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/.eslintignore +4 -0
- data/.eslintrc.js +14 -0
- data/.gitignore +11 -11
- data/.node-version +1 -0
- data/.rubocop.yml +125 -0
- data/.travis.yml +54 -5
- data/CHANGELOG.jetpacker.md +7 -0
- data/CHANGELOG.md +1000 -0
- data/CONTRIBUTING.md +33 -0
- data/Gemfile +9 -3
- data/Gemfile.lock +157 -21
- data/MIT-LICENSE +20 -0
- data/README.md +671 -16
- data/Rakefile +8 -3
- data/docs/assets.md +119 -0
- data/docs/cloud9.md +310 -0
- data/docs/css.md +253 -0
- data/docs/deployment.md +130 -0
- data/docs/docker.md +68 -0
- data/docs/engines.md +200 -0
- data/docs/env.md +65 -0
- data/docs/es6.md +72 -0
- data/docs/folder-structure.md +66 -0
- data/docs/misc.md +23 -0
- data/docs/props.md +223 -0
- data/docs/testing.md +137 -0
- data/docs/troubleshooting.md +156 -0
- data/docs/typescript.md +126 -0
- data/docs/v4-upgrade.md +142 -0
- data/docs/webpack-dev-server.md +92 -0
- data/docs/webpack.md +364 -0
- data/docs/yarn.md +23 -0
- data/gemfiles/Gemfile-rails-edge +12 -0
- data/gemfiles/Gemfile-rails.4.2.x +9 -0
- data/gemfiles/Gemfile-rails.5.0.x +9 -0
- data/gemfiles/Gemfile-rails.5.1.x +9 -0
- data/gemfiles/Gemfile-rails.5.2.x +9 -0
- data/gemfiles/Gemfile-rails.6.0.x +9 -0
- data/jetpacker.gemspec +28 -22
- data/lib/install/angular.rb +23 -0
- data/lib/install/bin/webpack +18 -0
- data/lib/install/bin/webpack-dev-server +18 -0
- data/lib/install/binstubs.rb +4 -0
- data/lib/install/coffee.rb +25 -0
- data/lib/install/config/.browserslistrc +1 -0
- data/lib/install/config/babel.config.js +72 -0
- data/lib/install/config/postcss.config.js +12 -0
- data/lib/install/config/webpack/development.js +5 -0
- data/lib/install/config/webpack/environment.js +3 -0
- data/lib/install/config/webpack/production.js +5 -0
- data/lib/install/config/webpack/test.js +5 -0
- data/lib/install/config/webpacker.yml +96 -0
- data/lib/install/elm.rb +39 -0
- data/lib/install/erb.rb +25 -0
- data/lib/install/examples/angular/hello_angular.js +7 -0
- data/lib/install/examples/angular/hello_angular/app/app.component.ts +9 -0
- data/lib/install/examples/angular/hello_angular/app/app.module.ts +16 -0
- data/lib/install/examples/angular/hello_angular/index.ts +8 -0
- data/lib/install/examples/angular/hello_angular/polyfills.ts +73 -0
- data/lib/install/examples/coffee/hello_coffee.coffee +4 -0
- data/lib/install/examples/elm/Main.elm +55 -0
- data/lib/install/examples/elm/hello_elm.js +16 -0
- data/lib/install/examples/erb/hello_erb.js.erb +6 -0
- data/lib/install/examples/react/babel.config.js +87 -0
- data/lib/install/examples/react/hello_react.jsx +26 -0
- data/lib/install/examples/react/tsconfig.json +20 -0
- data/lib/install/examples/stimulus/application.js +1 -0
- data/lib/install/examples/stimulus/controllers/hello_controller.js +18 -0
- data/lib/install/examples/stimulus/controllers/index.js +9 -0
- data/lib/install/examples/svelte/app.svelte +11 -0
- data/lib/install/examples/svelte/hello_svelte.js +20 -0
- data/lib/install/examples/typescript/hello_typescript.ts +4 -0
- data/lib/install/examples/typescript/tsconfig.json +23 -0
- data/lib/install/examples/vue/app.vue +22 -0
- data/lib/install/examples/vue/hello_vue.js +72 -0
- data/lib/install/javascript/packs/application.js +18 -0
- data/lib/install/loaders/coffee.js +6 -0
- data/lib/install/loaders/elm.js +25 -0
- data/lib/install/loaders/erb.js +11 -0
- data/lib/install/loaders/svelte.js +9 -0
- data/lib/install/loaders/typescript.js +11 -0
- data/lib/install/loaders/vue.js +6 -0
- data/lib/install/react.rb +18 -0
- data/lib/install/stimulus.rb +12 -0
- data/lib/install/svelte.rb +29 -0
- data/lib/install/template.rb +55 -0
- data/lib/install/typescript.rb +46 -0
- data/lib/install/vue.rb +49 -0
- data/lib/jetpacker/version.rb +2 -1
- data/lib/tasks/installers.rake +37 -0
- data/lib/tasks/webpacker.rake +28 -0
- data/lib/tasks/webpacker/binstubs.rake +11 -0
- data/lib/tasks/webpacker/check_binstubs.rake +12 -0
- data/lib/tasks/webpacker/check_node.rake +24 -0
- data/lib/tasks/webpacker/check_yarn.rake +24 -0
- data/lib/tasks/webpacker/clean.rake +21 -0
- data/lib/tasks/webpacker/clobber.rake +16 -0
- data/lib/tasks/webpacker/compile.rake +43 -0
- data/lib/tasks/webpacker/info.rake +20 -0
- data/lib/tasks/webpacker/install.rake +13 -0
- data/lib/tasks/webpacker/verify_install.rake +13 -0
- data/lib/tasks/webpacker/yarn_install.rake +21 -0
- data/lib/webpacker.rb +46 -0
- data/lib/webpacker/commands.rb +50 -0
- data/lib/webpacker/compiler.rb +107 -0
- data/lib/webpacker/configuration.rb +113 -0
- data/lib/webpacker/dev_server.rb +66 -0
- data/lib/webpacker/dev_server_proxy.rb +31 -0
- data/lib/webpacker/dev_server_runner.rb +72 -0
- data/lib/webpacker/env.rb +39 -0
- data/lib/webpacker/helper.rb +176 -0
- data/lib/webpacker/instance.rb +37 -0
- data/lib/webpacker/manifest.rb +118 -0
- data/lib/webpacker/railtie.rb +98 -0
- data/lib/webpacker/rake_tasks.rb +6 -0
- data/lib/webpacker/runner.rb +22 -0
- data/lib/webpacker/version.rb +4 -0
- data/lib/webpacker/webpack_runner.rb +32 -0
- data/package.json +82 -0
- data/package/__tests__/config.js +55 -0
- data/package/__tests__/dev_server.js +43 -0
- data/package/__tests__/development.js +30 -0
- data/package/__tests__/env.js +46 -0
- data/package/__tests__/production.js +29 -0
- data/package/__tests__/staging.js +29 -0
- data/package/__tests__/test.js +26 -0
- data/package/config.js +37 -0
- data/package/config_types/__tests__/config_list.js +118 -0
- data/package/config_types/__tests__/config_object.js +43 -0
- data/package/config_types/config_list.js +75 -0
- data/package/config_types/config_object.js +55 -0
- data/package/config_types/index.js +7 -0
- data/package/dev_server.js +20 -0
- data/package/env.js +19 -0
- data/package/environments/__tests__/base.js +74 -0
- data/package/environments/base.js +166 -0
- data/package/environments/development.js +51 -0
- data/package/environments/production.js +79 -0
- data/package/environments/test.js +3 -0
- data/package/index.js +24 -0
- data/package/rules/babel.js +21 -0
- data/package/rules/css.js +3 -0
- data/package/rules/file.js +20 -0
- data/package/rules/index.js +20 -0
- data/package/rules/module.css.js +3 -0
- data/package/rules/module.sass.js +8 -0
- data/package/rules/node_modules.js +24 -0
- data/package/rules/sass.js +8 -0
- data/package/utils/__tests__/deep_assign.js +32 -0
- data/package/utils/__tests__/deep_merge.js +10 -0
- data/package/utils/__tests__/get_style_rule.js +65 -0
- data/package/utils/__tests__/objectify.js +9 -0
- data/package/utils/deep_assign.js +22 -0
- data/package/utils/deep_merge.js +22 -0
- data/package/utils/get_style_rule.js +45 -0
- data/package/utils/helpers.js +58 -0
- data/package/utils/objectify.js +3 -0
- data/test/command_test.rb +33 -0
- data/test/compiler_test.rb +75 -0
- data/test/configuration_test.rb +108 -0
- data/test/dev_server_runner_test.rb +51 -0
- data/test/dev_server_test.rb +47 -0
- data/test/env_test.rb +23 -0
- data/test/helper_test.rb +142 -0
- data/test/manifest_test.rb +42 -0
- data/test/rake_tasks_test.rb +69 -0
- data/test/test_app/Rakefile +3 -0
- data/test/test_app/app/javascript/packs/application.js +10 -0
- data/test/test_app/bin/webpack +14 -0
- data/test/test_app/bin/webpack-dev-server +14 -0
- data/test/test_app/config.ru +5 -0
- data/test/test_app/config/application.rb +12 -0
- data/test/test_app/config/environment.rb +4 -0
- data/test/test_app/config/webpack/development.js +0 -0
- data/test/test_app/config/webpacker.yml +97 -0
- data/test/test_app/config/webpacker_public_root.yml +19 -0
- data/test/test_app/package.json +13 -0
- data/test/test_app/public/packs/manifest.json +31 -0
- data/test/test_app/yarn.lock +11 -0
- data/test/test_helper.rb +33 -0
- data/test/webpack_runner_test.rb +51 -0
- data/test/webpacker_test.rb +13 -0
- data/yarn.lock +8321 -0
- metadata +267 -29
- data/.rspec +0 -3
- data/LICENSE.txt +0 -21
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/lib/jetpacker.rb +0 -6
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
class Webpacker::DevServer
|
|
2
|
+
DEFAULT_ENV_PREFIX = "WEBPACKER_DEV_SERVER".freeze
|
|
3
|
+
|
|
4
|
+
# Configure dev server connection timeout (in seconds), default: 0.01
|
|
5
|
+
# Webpacker.dev_server.connect_timeout = 1
|
|
6
|
+
cattr_accessor(:connect_timeout) { 0.01 }
|
|
7
|
+
|
|
8
|
+
attr_reader :config
|
|
9
|
+
|
|
10
|
+
def initialize(config)
|
|
11
|
+
@config = config
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def running?
|
|
15
|
+
if config.dev_server.present?
|
|
16
|
+
Socket.tcp(host, port, connect_timeout: connect_timeout).close
|
|
17
|
+
true
|
|
18
|
+
else
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
rescue
|
|
22
|
+
false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def host
|
|
26
|
+
fetch(:host)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def port
|
|
30
|
+
fetch(:port)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def https?
|
|
34
|
+
case fetch(:https)
|
|
35
|
+
when true, "true", Hash
|
|
36
|
+
true
|
|
37
|
+
else
|
|
38
|
+
false
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def protocol
|
|
43
|
+
https? ? "https" : "http"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def host_with_port
|
|
47
|
+
"#{host}:#{port}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def pretty?
|
|
51
|
+
fetch(:pretty)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def env_prefix
|
|
55
|
+
config.dev_server.fetch(:env_prefix, DEFAULT_ENV_PREFIX)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
def fetch(key)
|
|
60
|
+
ENV["#{env_prefix}_#{key.upcase}"] || config.dev_server.fetch(key, defaults[key])
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def defaults
|
|
64
|
+
config.send(:defaults)[:dev_server] || {}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require "rack/proxy"
|
|
2
|
+
|
|
3
|
+
class Webpacker::DevServerProxy < Rack::Proxy
|
|
4
|
+
delegate :config, :dev_server, to: :@webpacker
|
|
5
|
+
|
|
6
|
+
def initialize(app = nil, opts = {})
|
|
7
|
+
@webpacker = opts.delete(:webpacker) || Webpacker.instance
|
|
8
|
+
opts[:streaming] = false if Jets.env.test? && !opts.key?(:streaming)
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def perform_request(env)
|
|
13
|
+
if env["PATH_INFO"].start_with?("/#{public_output_uri_path}") && dev_server.running?
|
|
14
|
+
env["HTTP_HOST"] = env["HTTP_X_FORWARDED_HOST"] = env["HTTP_X_FORWARDED_SERVER"] = dev_server.host_with_port
|
|
15
|
+
env["HTTP_X_FORWARDED_PROTO"] = env["HTTP_X_FORWARDED_SCHEME"] = dev_server.protocol
|
|
16
|
+
unless dev_server.https?
|
|
17
|
+
env["HTTPS"] = env["HTTP_X_FORWARDED_SSL"] = "off"
|
|
18
|
+
end
|
|
19
|
+
env["SCRIPT_NAME"] = ""
|
|
20
|
+
|
|
21
|
+
super(env)
|
|
22
|
+
else
|
|
23
|
+
@app.call(env)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
def public_output_uri_path
|
|
29
|
+
config.public_output_path.relative_path_from(config.public_path).to_s + "/"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require "shellwords"
|
|
2
|
+
require "socket"
|
|
3
|
+
require "webpacker/configuration"
|
|
4
|
+
require "webpacker/dev_server"
|
|
5
|
+
require "webpacker/runner"
|
|
6
|
+
|
|
7
|
+
module Webpacker
|
|
8
|
+
class DevServerRunner < Webpacker::Runner
|
|
9
|
+
def run
|
|
10
|
+
load_config
|
|
11
|
+
detect_port!
|
|
12
|
+
execute_cmd
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
def load_config
|
|
17
|
+
app_root = Pathname.new(@app_path)
|
|
18
|
+
|
|
19
|
+
@config = Configuration.new(
|
|
20
|
+
root_path: app_root,
|
|
21
|
+
config_path: app_root.join("config/webpacker.yml"),
|
|
22
|
+
env: ENV["JETS_ENV"]
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
dev_server = DevServer.new(@config)
|
|
26
|
+
|
|
27
|
+
@hostname = dev_server.host
|
|
28
|
+
@port = dev_server.port
|
|
29
|
+
@pretty = dev_server.pretty?
|
|
30
|
+
|
|
31
|
+
rescue Errno::ENOENT, NoMethodError
|
|
32
|
+
$stdout.puts "webpack dev_server configuration not found in #{@config.config_path}[#{ENV["JETS_ENV"]}]."
|
|
33
|
+
$stdout.puts "Please run bundle exec rails webpacker:install to install Webpacker"
|
|
34
|
+
exit!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def detect_port!
|
|
38
|
+
server = TCPServer.new(@hostname, @port)
|
|
39
|
+
server.close
|
|
40
|
+
|
|
41
|
+
rescue Errno::EADDRINUSE
|
|
42
|
+
$stdout.puts "Another program is running on port #{@port}. Set a new port in #{@config.config_path} for dev_server"
|
|
43
|
+
exit!
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def execute_cmd
|
|
47
|
+
env = Webpacker::Compiler.env
|
|
48
|
+
|
|
49
|
+
cmd = if node_modules_bin_exist?
|
|
50
|
+
["#{@node_modules_bin_path}/webpack-dev-server"]
|
|
51
|
+
else
|
|
52
|
+
["yarn", "webpack-dev-server"]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
if ARGV.include?("--debug")
|
|
56
|
+
cmd = [ "node", "--inspect-brk"] + cmd
|
|
57
|
+
ARGV.delete("--debug")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
cmd += ["--config", @webpack_config]
|
|
61
|
+
cmd += ["--progress", "--color"] if @pretty
|
|
62
|
+
|
|
63
|
+
Dir.chdir(@app_path) do
|
|
64
|
+
Kernel.exec env, *cmd
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def node_modules_bin_exist?
|
|
69
|
+
File.exist?("#{@node_modules_bin_path}/webpack-dev-server")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class Webpacker::Env
|
|
2
|
+
DEFAULT = "production".freeze
|
|
3
|
+
|
|
4
|
+
delegate :config_path, :logger, to: :@webpacker
|
|
5
|
+
|
|
6
|
+
def self.inquire(webpacker)
|
|
7
|
+
new(webpacker).inquire
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(webpacker)
|
|
11
|
+
@webpacker = webpacker
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def inquire
|
|
15
|
+
fallback_env_warning if config_path.exist? && !current
|
|
16
|
+
current || DEFAULT.inquiry
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
def current
|
|
21
|
+
Jets.env.presence_in(available_environments)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def fallback_env_warning
|
|
25
|
+
logger.info "JETS_ENV=#{Jets.env} environment is not defined in config/webpacker.yml, falling back to #{DEFAULT} environment"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def available_environments
|
|
29
|
+
if config_path.exist?
|
|
30
|
+
YAML.load(config_path.read).keys
|
|
31
|
+
else
|
|
32
|
+
[].freeze
|
|
33
|
+
end
|
|
34
|
+
rescue Psych::SyntaxError => e
|
|
35
|
+
raise "YAML syntax error occurred while parsing #{config_path}. " \
|
|
36
|
+
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
|
|
37
|
+
"Error: #{e.message}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
module Webpacker::Helper
|
|
2
|
+
# Returns the current Webpacker instance.
|
|
3
|
+
# Could be overridden to use multiple Webpacker
|
|
4
|
+
# configurations within the same app (e.g. with engines).
|
|
5
|
+
def current_webpacker_instance
|
|
6
|
+
Webpacker.instance
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Computes the relative path for a given Webpacker asset.
|
|
10
|
+
# Returns the relative path using manifest.json and passes it to asset_path helper.
|
|
11
|
+
# This will use asset_path internally, so most of their behaviors will be the same.
|
|
12
|
+
#
|
|
13
|
+
# Example:
|
|
14
|
+
#
|
|
15
|
+
# # When extract_css is false in webpacker.yml and the file is a css:
|
|
16
|
+
# <%= asset_pack_path 'calendar.css' %> # => nil
|
|
17
|
+
#
|
|
18
|
+
# # When extract_css is true in webpacker.yml or the file is not a css:
|
|
19
|
+
# <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css"
|
|
20
|
+
def asset_pack_path(name, **options)
|
|
21
|
+
if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
|
|
22
|
+
asset_path(current_webpacker_instance.manifest.lookup!(name), options)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Computes the absolute path for a given Webpacker asset.
|
|
27
|
+
# Returns the absolute path using manifest.json and passes it to asset_url helper.
|
|
28
|
+
# This will use asset_url internally, so most of their behaviors will be the same.
|
|
29
|
+
#
|
|
30
|
+
# Example:
|
|
31
|
+
#
|
|
32
|
+
# # When extract_css is false in webpacker.yml and the file is a css:
|
|
33
|
+
# <%= asset_pack_url 'calendar.css' %> # => nil
|
|
34
|
+
#
|
|
35
|
+
# # When extract_css is true in webpacker.yml or the file is not a css:
|
|
36
|
+
# <%= asset_pack_url 'calendar.css' %> # => "http://example.com/packs/calendar-1016838bab065ae1e122.css"
|
|
37
|
+
def asset_pack_url(name, **options)
|
|
38
|
+
if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
|
|
39
|
+
asset_url(current_webpacker_instance.manifest.lookup!(name), options)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Creates an image tag that references the named pack file.
|
|
44
|
+
#
|
|
45
|
+
# Example:
|
|
46
|
+
#
|
|
47
|
+
# <%= image_pack_tag 'application.png', size: '16x10', alt: 'Edit Entry' %>
|
|
48
|
+
# <img alt='Edit Entry' src='/packs/application-k344a6d59eef8632c9d1.png' width='16' height='10' />
|
|
49
|
+
def image_pack_tag(name, **options)
|
|
50
|
+
image_tag(resolve_path_to_image(name), options)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Creates a link tag for a favicon that references the named pack file.
|
|
54
|
+
#
|
|
55
|
+
# Example:
|
|
56
|
+
#
|
|
57
|
+
# <%= favicon_pack_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png' %>
|
|
58
|
+
# <link href="/packs/mb-icon-k344a6d59eef8632c9d1.png" rel="apple-touch-icon" type="image/png" />
|
|
59
|
+
def favicon_pack_tag(name, **options)
|
|
60
|
+
favicon_link_tag(resolve_path_to_image(name), options)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Creates a script tag that references the named pack file, as compiled by webpack per the entries list
|
|
64
|
+
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
|
|
65
|
+
# app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
|
|
66
|
+
#
|
|
67
|
+
# Example:
|
|
68
|
+
#
|
|
69
|
+
# <%= javascript_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
|
|
70
|
+
# <script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
|
|
71
|
+
def javascript_pack_tag(*names, **options)
|
|
72
|
+
javascript_include_tag(*sources_from_manifest_entries(names, type: :javascript), **options)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Creates script tags that reference the js chunks from entrypoints when using split chunks API,
|
|
76
|
+
# as compiled by webpack per the entries list in config/webpack/shared.js.
|
|
77
|
+
# By default, this list is auto-generated to match everything in
|
|
78
|
+
# app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
|
|
79
|
+
# See: https://webpack.js.org/plugins/split-chunks-plugin/
|
|
80
|
+
# Example:
|
|
81
|
+
#
|
|
82
|
+
# <%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %> # =>
|
|
83
|
+
# <script src="/packs/vendor-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
|
|
84
|
+
# <script src="/packs/calendar~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
|
|
85
|
+
# <script src="/packs/calendar-1016838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
|
|
86
|
+
# <script src="/packs/map~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
|
|
87
|
+
# <script src="/packs/map-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload"></script>
|
|
88
|
+
# DO:
|
|
89
|
+
# <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
|
|
90
|
+
# DON'T:
|
|
91
|
+
# <%= javascript_packs_with_chunks_tag 'calendar' %>
|
|
92
|
+
# <%= javascript_packs_with_chunks_tag 'map' %>
|
|
93
|
+
def javascript_packs_with_chunks_tag(*names, **options)
|
|
94
|
+
javascript_include_tag(*sources_from_manifest_entrypoints(names, type: :javascript), **options)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Creates a link tag, for preloading, that references a given Webpacker asset.
|
|
98
|
+
# In production mode, the digested reference is automatically looked up.
|
|
99
|
+
# See: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
|
|
100
|
+
# Example:
|
|
101
|
+
#
|
|
102
|
+
# <%= preload_pack_asset 'fonts/fa-regular-400.woff2' %> # =>
|
|
103
|
+
# <link rel="preload" href="/packs/fonts/fa-regular-400-944fb546bd7018b07190a32244f67dc9.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
104
|
+
def preload_pack_asset(name, **options)
|
|
105
|
+
if self.class.method_defined?(:preload_link_tag)
|
|
106
|
+
preload_link_tag(current_webpacker_instance.manifest.lookup!(name), options)
|
|
107
|
+
else
|
|
108
|
+
raise "You need Rails >= 5.2 to use this tag."
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Creates a link tag that references the named pack file, as compiled by webpack per the entries list
|
|
113
|
+
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
|
|
114
|
+
# app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
|
|
115
|
+
#
|
|
116
|
+
# Note: If the development server is running and hot module replacement is active, this will return nothing.
|
|
117
|
+
# In that setup you need to configure your styles to be inlined in your JavaScript for hot reloading.
|
|
118
|
+
#
|
|
119
|
+
# Examples:
|
|
120
|
+
#
|
|
121
|
+
# # When extract_css is false in webpacker.yml:
|
|
122
|
+
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
|
|
123
|
+
# nil
|
|
124
|
+
#
|
|
125
|
+
# # When extract_css is true in webpacker.yml:
|
|
126
|
+
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
|
|
127
|
+
# <link rel="stylesheet" media="screen" href="/packs/calendar-1016838bab065ae1e122.css" data-turbolinks-track="reload" />
|
|
128
|
+
def stylesheet_pack_tag(*names, **options)
|
|
129
|
+
if current_webpacker_instance.config.extract_css?
|
|
130
|
+
stylesheet_link_tag(*sources_from_manifest_entries(names, type: :stylesheet), **options)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Creates link tags that reference the css chunks from entrypoints when using split chunks API,
|
|
135
|
+
# as compiled by webpack per the entries list in config/webpack/shared.js.
|
|
136
|
+
# By default, this list is auto-generated to match everything in
|
|
137
|
+
# app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
|
|
138
|
+
# See: https://webpack.js.org/plugins/split-chunks-plugin/
|
|
139
|
+
#
|
|
140
|
+
# Examples:
|
|
141
|
+
#
|
|
142
|
+
# <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %> # =>
|
|
143
|
+
# <link rel="stylesheet" media="screen" href="/packs/3-8c7ce31a.chunk.css" />
|
|
144
|
+
# <link rel="stylesheet" media="screen" href="/packs/calendar-8c7ce31a.chunk.css" />
|
|
145
|
+
# <link rel="stylesheet" media="screen" href="/packs/map-8c7ce31a.chunk.css" />
|
|
146
|
+
# DO:
|
|
147
|
+
# <%= stylesheet_packs_with_chunks_tag 'calendar', 'map' %>
|
|
148
|
+
# DON'T:
|
|
149
|
+
# <%= stylesheet_packs_with_chunks_tag 'calendar' %>
|
|
150
|
+
# <%= stylesheet_packs_with_chunks_tag 'map' %>
|
|
151
|
+
def stylesheet_packs_with_chunks_tag(*names, **options)
|
|
152
|
+
if current_webpacker_instance.config.extract_css?
|
|
153
|
+
stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
def stylesheet?(name)
|
|
159
|
+
File.extname(name) == ".css"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def sources_from_manifest_entries(names, type:)
|
|
163
|
+
names.map { |name| current_webpacker_instance.manifest.lookup!(name, type: type) }.flatten
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def sources_from_manifest_entrypoints(names, type:)
|
|
167
|
+
names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks!(name, type: type) }.flatten.uniq
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def resolve_path_to_image(name)
|
|
171
|
+
path = name.starts_with?("media/images/") ? name : "media/images/#{name}"
|
|
172
|
+
asset_path(current_webpacker_instance.manifest.lookup!(path))
|
|
173
|
+
rescue
|
|
174
|
+
asset_path(current_webpacker_instance.manifest.lookup!(name))
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class Webpacker::Instance
|
|
2
|
+
cattr_accessor(:logger) { ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT)) }
|
|
3
|
+
|
|
4
|
+
attr_reader :root_path, :config_path
|
|
5
|
+
|
|
6
|
+
def initialize(root_path: Jets.root, config_path: Jets.root.join("config/webpacker.yml"))
|
|
7
|
+
@root_path, @config_path = root_path, config_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def env
|
|
11
|
+
@env ||= Webpacker::Env.inquire self
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def config
|
|
15
|
+
@config ||= Webpacker::Configuration.new(
|
|
16
|
+
root_path: root_path,
|
|
17
|
+
config_path: config_path,
|
|
18
|
+
env: env
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def compiler
|
|
23
|
+
@compiler ||= Webpacker::Compiler.new self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def dev_server
|
|
27
|
+
@dev_server ||= Webpacker::DevServer.new config
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def manifest
|
|
31
|
+
@manifest ||= Webpacker::Manifest.new self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def commands
|
|
35
|
+
@commands ||= Webpacker::Commands.new self
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Singleton registry for accessing the packs path using a generated manifest.
|
|
2
|
+
# This allows javascript_pack_tag, stylesheet_pack_tag, asset_pack_path to take a reference to,
|
|
3
|
+
# say, "calendar.js" or "calendar.css" and turn it into "/packs/calendar-1016838bab065ae1e314.js" or
|
|
4
|
+
# "/packs/calendar-1016838bab065ae1e314.css".
|
|
5
|
+
#
|
|
6
|
+
# When the configuration is set to on-demand compilation, with the `compile: true` option in
|
|
7
|
+
# the webpacker.yml file, any lookups will be preceded by a compilation if one is needed.
|
|
8
|
+
class Webpacker::Manifest
|
|
9
|
+
class MissingEntryError < StandardError; end
|
|
10
|
+
|
|
11
|
+
delegate :config, :compiler, :dev_server, to: :@webpacker
|
|
12
|
+
|
|
13
|
+
def initialize(webpacker)
|
|
14
|
+
@webpacker = webpacker
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def refresh
|
|
18
|
+
@data = load
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def lookup_pack_with_chunks(name, pack_type = {})
|
|
22
|
+
compile if compiling?
|
|
23
|
+
|
|
24
|
+
manifest_pack_type = manifest_type(pack_type[:type])
|
|
25
|
+
manifest_pack_name = manifest_name(name, manifest_pack_type)
|
|
26
|
+
find("entrypoints")[manifest_pack_name][manifest_pack_type]
|
|
27
|
+
rescue NoMethodError
|
|
28
|
+
nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def lookup_pack_with_chunks!(name, pack_type = {})
|
|
32
|
+
lookup_pack_with_chunks(name, pack_type) || handle_missing_entry(name)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Computes the relative path for a given Webpacker asset using manifest.json.
|
|
36
|
+
# If no asset is found, returns nil.
|
|
37
|
+
#
|
|
38
|
+
# Example:
|
|
39
|
+
#
|
|
40
|
+
# Webpacker.manifest.lookup('calendar.js') # => "/packs/calendar-1016838bab065ae1e122.js"
|
|
41
|
+
def lookup(name, pack_type = {})
|
|
42
|
+
compile if compiling?
|
|
43
|
+
|
|
44
|
+
find(full_pack_name(name, pack_type[:type]))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Like lookup, except that if no asset is found, raises a Webpacker::Manifest::MissingEntryError.
|
|
48
|
+
def lookup!(name, pack_type = {})
|
|
49
|
+
lookup(name, pack_type) || handle_missing_entry(name)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
def compiling?
|
|
54
|
+
config.compile? && !dev_server.running?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def compile
|
|
58
|
+
Webpacker.logger.tagged("Webpacker") { compiler.compile }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def data
|
|
62
|
+
if config.cache_manifest?
|
|
63
|
+
@data ||= load
|
|
64
|
+
else
|
|
65
|
+
refresh
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def find(name)
|
|
70
|
+
data[name.to_s].presence
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def full_pack_name(name, pack_type)
|
|
74
|
+
return name unless File.extname(name.to_s).empty?
|
|
75
|
+
"#{name}.#{manifest_type(pack_type)}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def handle_missing_entry(name)
|
|
79
|
+
raise Webpacker::Manifest::MissingEntryError, missing_file_from_manifest_error(name)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def load
|
|
83
|
+
if config.public_manifest_path.exist?
|
|
84
|
+
JSON.parse config.public_manifest_path.read
|
|
85
|
+
else
|
|
86
|
+
{}
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# The `manifest_name` method strips of the file extension of the name, because in the
|
|
91
|
+
# manifest hash the entrypoints are defined by their pack name without the extension.
|
|
92
|
+
# When the user provides a name with a file extension, we want to try to strip it off.
|
|
93
|
+
def manifest_name(name, pack_type)
|
|
94
|
+
return name if File.extname(name.to_s).empty?
|
|
95
|
+
File.basename(name, pack_type)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def manifest_type(pack_type)
|
|
99
|
+
case pack_type
|
|
100
|
+
when :javascript then "js"
|
|
101
|
+
when :stylesheet then "css"
|
|
102
|
+
else pack_type.to_s
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def missing_file_from_manifest_error(bundle_name)
|
|
107
|
+
<<-MSG
|
|
108
|
+
Webpacker can't find #{bundle_name} in #{config.public_manifest_path}. Possible causes:
|
|
109
|
+
1. You want to set webpacker.yml value of compile to true for your environment
|
|
110
|
+
unless you are using the `webpack -w` or the webpack-dev-server.
|
|
111
|
+
2. webpack has not yet re-run to reflect updates.
|
|
112
|
+
3. You have misconfigured Webpacker's config/webpacker.yml file.
|
|
113
|
+
4. Your webpack configuration is not creating a manifest.
|
|
114
|
+
Your manifest contains:
|
|
115
|
+
#{JSON.pretty_generate(@data)}
|
|
116
|
+
MSG
|
|
117
|
+
end
|
|
118
|
+
end
|