webpacker 2.0 → 3.0.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/.gitignore +2 -0
- data/.rubocop.yml +21 -21
- data/CHANGELOG.md +107 -4
- data/Gemfile +3 -1
- data/Gemfile.lock +15 -8
- data/README.md +137 -937
- data/docs/assets.md +106 -0
- data/docs/css.md +82 -0
- data/docs/deployment.md +39 -0
- data/docs/env.md +62 -0
- data/docs/es6.md +53 -0
- data/docs/folder-structure.md +66 -0
- data/docs/misc.md +23 -0
- data/docs/props.md +105 -0
- data/docs/testing.md +45 -0
- data/docs/troubleshooting.md +65 -0
- data/docs/typescript.md +115 -0
- data/docs/webpack-dev-server.md +32 -0
- data/docs/webpack.md +108 -0
- data/docs/yarn.md +12 -0
- data/lib/install/angular.rb +4 -7
- data/lib/install/bin/webpack-dev-server.tt +35 -11
- data/lib/install/bin/webpack.tt +3 -4
- data/lib/install/config/.babelrc +1 -0
- data/lib/install/config/.postcssrc.yml +1 -2
- data/lib/install/config/webpack/development.js +2 -31
- data/lib/install/config/webpack/environment.js +3 -0
- data/lib/install/config/webpack/production.js +2 -34
- data/lib/install/config/webpack/test.js +2 -5
- data/lib/install/config/webpacker.yml +20 -2
- data/lib/install/elm.rb +6 -11
- data/lib/install/examples/vue/hello_vue.js +31 -2
- data/lib/install/react.rb +2 -5
- data/lib/install/template.rb +3 -8
- data/lib/install/vue.rb +4 -7
- data/lib/tasks/webpacker.rake +1 -1
- data/lib/tasks/webpacker/{check_webpack_binstubs.rake → check_binstubs.rake} +3 -2
- data/lib/tasks/webpacker/check_node.rake +8 -6
- data/lib/tasks/webpacker/check_yarn.rake +2 -2
- data/lib/tasks/webpacker/clobber.rake +2 -3
- data/lib/tasks/webpacker/compile.rake +16 -18
- data/lib/tasks/webpacker/verify_install.rake +5 -5
- data/lib/tasks/webpacker/yarn_install.rake +1 -1
- data/lib/webpacker.rb +15 -11
- data/lib/webpacker/commands.rb +22 -0
- data/lib/webpacker/compiler.rb +66 -10
- data/lib/webpacker/configuration.rb +54 -38
- data/lib/webpacker/dev_server.rb +47 -0
- data/lib/webpacker/dev_server_proxy.rb +24 -0
- data/lib/webpacker/helper.rb +23 -5
- data/lib/webpacker/instance.rb +44 -0
- data/lib/webpacker/manifest.rb +58 -34
- data/lib/webpacker/railtie.rb +22 -3
- data/lib/webpacker/version.rb +2 -1
- data/package.json +37 -7
- data/package/asset_host.js +21 -0
- data/package/config.js +8 -0
- data/package/environment.js +95 -0
- data/package/environments/development.js +47 -0
- data/package/environments/production.js +34 -0
- data/package/environments/test.js +3 -0
- data/package/index.js +16 -0
- data/package/loaders/babel.js +11 -0
- data/{lib/install/config/loaders/core → package/loaders}/coffee.js +0 -0
- data/{lib/install/config/loaders/installers → package/loaders}/elm.js +4 -5
- data/{lib/install/config/loaders/core → package/loaders}/erb.js +0 -0
- data/package/loaders/file.js +15 -0
- data/package/loaders/style.js +31 -0
- data/{lib/install/config/loaders/installers/angular.js → package/loaders/typescript.js} +1 -1
- data/package/loaders/vue.js +12 -0
- data/test/compiler_test.rb +20 -0
- data/test/configuration_test.rb +43 -19
- data/test/dev_server_test.rb +24 -0
- data/test/helper_test.rb +21 -5
- data/test/manifest_test.rb +25 -19
- data/test/test_app/public/packs/manifest.json +3 -1
- data/test/webpacker_test_helper.rb +40 -0
- data/webpacker.gemspec +1 -1
- data/yarn.lock +4701 -578
- metadata +52 -29
- data/lib/install/config/loaders/core/assets.js +0 -12
- data/lib/install/config/loaders/core/babel.js +0 -5
- data/lib/install/config/loaders/core/sass.js +0 -15
- data/lib/install/config/loaders/installers/react.js +0 -5
- data/lib/install/config/loaders/installers/vue.js +0 -13
- data/lib/install/config/webpack/configuration.js +0 -35
- data/lib/install/config/webpack/shared.js +0 -58
- data/lib/webpacker/env.rb +0 -23
- data/lib/webpacker/file_loader.rb +0 -24
- data/test/env_test.rb +0 -14
- data/test/webpacker_test.rb +0 -15
@@ -1,5 +1,5 @@
|
|
1
1
|
namespace :webpacker do
|
2
|
-
desc "Support for older Rails versions.Install all JavaScript dependencies as specified via Yarn"
|
2
|
+
desc "Support for older Rails versions. Install all JavaScript dependencies as specified via Yarn"
|
3
3
|
task :yarn_install, [:arg1, :arg2] do |task, args|
|
4
4
|
system "yarn #{args[:arg1]} #{args[:arg2]}"
|
5
5
|
end
|
data/lib/webpacker.rb
CHANGED
@@ -1,24 +1,28 @@
|
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
2
|
+
require "active_support/logger"
|
3
|
+
require "active_support/tagged_logging"
|
4
|
+
|
1
5
|
module Webpacker
|
2
6
|
extend self
|
3
7
|
|
4
|
-
def
|
5
|
-
|
6
|
-
Webpacker::Configuration.load
|
7
|
-
Webpacker::Manifest.load
|
8
|
+
def instance=(instance)
|
9
|
+
@instance = instance
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
11
|
-
Webpacker::
|
12
|
-
Webpacker::Manifest.load
|
12
|
+
def instance
|
13
|
+
@instance ||= Webpacker::Instance.new
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
delegate :logger, :logger=, :env, to: :instance
|
17
|
+
delegate :config, :compiler, :manifest, :commands, :dev_server, to: :instance
|
18
|
+
delegate :bootstrap, :clobber, :compile, to: :commands
|
18
19
|
end
|
19
20
|
|
20
|
-
require "webpacker/
|
21
|
+
require "webpacker/instance"
|
21
22
|
require "webpacker/configuration"
|
22
23
|
require "webpacker/manifest"
|
23
24
|
require "webpacker/compiler"
|
25
|
+
require "webpacker/commands"
|
26
|
+
require "webpacker/dev_server"
|
27
|
+
|
24
28
|
require "webpacker/railtie" if defined?(Rails)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Webpacker::Commands
|
2
|
+
delegate :config, :compiler, :manifest, to: :@webpacker
|
3
|
+
|
4
|
+
def initialize(webpacker)
|
5
|
+
@webpacker = webpacker
|
6
|
+
end
|
7
|
+
|
8
|
+
def clobber
|
9
|
+
config.public_output_path.rmtree if config.public_output_path.exist?
|
10
|
+
config.cache_path.rmtree if config.cache_path.exist?
|
11
|
+
end
|
12
|
+
|
13
|
+
def bootstrap
|
14
|
+
config.refresh
|
15
|
+
manifest.refresh
|
16
|
+
end
|
17
|
+
|
18
|
+
def compile
|
19
|
+
compiler.compile
|
20
|
+
manifest.refresh
|
21
|
+
end
|
22
|
+
end
|
data/lib/webpacker/compiler.rb
CHANGED
@@ -1,20 +1,76 @@
|
|
1
|
-
require "
|
1
|
+
require "open3"
|
2
|
+
require "digest/sha1"
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
class Webpacker::Compiler
|
5
|
+
# Additional paths that test compiler needs to watch
|
6
|
+
# Webpacker::Compiler.watched_paths << 'bower_components'
|
7
|
+
mattr_accessor(:watched_paths) { [] }
|
8
|
+
|
9
|
+
# Additional environment variables that the compiler is being run with
|
10
|
+
# Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
|
11
|
+
mattr_accessor(:env) { {} }
|
12
|
+
|
13
|
+
delegate :config, :logger, to: :@webpacker
|
14
|
+
|
15
|
+
def initialize(webpacker)
|
16
|
+
@webpacker = webpacker
|
17
|
+
end
|
5
18
|
|
6
19
|
def compile
|
7
|
-
|
8
|
-
|
20
|
+
if stale?
|
21
|
+
record_compilation_digest
|
22
|
+
run_webpack
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns true if all the compiled packs are up to date with the underlying asset files.
|
27
|
+
def fresh?
|
28
|
+
watched_files_digest == last_compilation_digest
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns true if the compiled packs are out of date with the underlying asset files.
|
32
|
+
def stale?
|
33
|
+
!fresh?
|
9
34
|
end
|
10
35
|
|
11
36
|
private
|
12
|
-
def
|
13
|
-
|
37
|
+
def last_compilation_digest
|
38
|
+
compilation_digest_path.read if compilation_digest_path.exist? && config.public_manifest_path.exist?
|
39
|
+
end
|
40
|
+
|
41
|
+
def watched_files_digest
|
42
|
+
files = Dir[*default_watched_paths, *watched_paths].reject { |f| File.directory?(f) }
|
43
|
+
Digest::SHA1.hexdigest(files.map { |f| "#{File.basename(f)}/#{File.mtime(f).utc.to_i}" }.join("/"))
|
44
|
+
end
|
45
|
+
|
46
|
+
def record_compilation_digest
|
47
|
+
config.cache_path.mkpath
|
48
|
+
compilation_digest_path.write(watched_files_digest)
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_webpack
|
52
|
+
logger.info "Compiling…"
|
53
|
+
|
54
|
+
sterr, stdout, status = Open3.capture3(webpack_env, "#{RbConfig.ruby} ./bin/webpack")
|
55
|
+
|
56
|
+
if status.success?
|
57
|
+
logger.info "Compiled all packs in #{config.public_output_path}"
|
58
|
+
else
|
59
|
+
logger.error "Compilation failed:\n#{sterr}\n#{stdout}"
|
60
|
+
end
|
61
|
+
|
62
|
+
status.success?
|
63
|
+
end
|
64
|
+
|
65
|
+
def default_watched_paths
|
66
|
+
["#{config.source_path}/**/*", "yarn.lock", "package.json", "config/webpack/**/*"].freeze
|
67
|
+
end
|
68
|
+
|
69
|
+
def compilation_digest_path
|
70
|
+
config.cache_path.join(".last-compilation-digest")
|
14
71
|
end
|
15
72
|
|
16
|
-
def
|
17
|
-
@
|
18
|
-
Rake::Task[name]
|
73
|
+
def webpack_env
|
74
|
+
env.merge("NODE_ENV" => @webpacker.env, "ASSET_HOST" => ActionController::Base.helpers.compute_asset_host)
|
19
75
|
end
|
20
76
|
end
|
@@ -1,59 +1,75 @@
|
|
1
|
-
|
1
|
+
class Webpacker::Configuration
|
2
|
+
delegate :root_path, :config_path, :env, to: :@webpacker
|
2
3
|
|
3
|
-
|
4
|
+
def initialize(webpacker)
|
5
|
+
@webpacker = webpacker
|
6
|
+
end
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
source_path.join(fetch(:source_entry_path))
|
9
|
-
end
|
8
|
+
def refresh
|
9
|
+
@data = load
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def dev_server
|
13
|
+
fetch(:dev_server)
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def compile?
|
17
|
+
fetch(:compile)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def source_path
|
21
|
+
root_path.join(fetch(:source_path))
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def source_entry_path
|
25
|
+
source_path.join(fetch(:source_entry_path))
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
def public_path
|
29
|
+
root_path.join("public")
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
def public_output_path
|
33
|
+
public_path.join(fetch(:public_output_path))
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def public_manifest_path
|
37
|
+
public_output_path.join("manifest.json")
|
38
|
+
end
|
39
|
+
|
40
|
+
def cache_manifest?
|
41
|
+
fetch(:cache_manifest)
|
42
|
+
end
|
38
43
|
|
44
|
+
def cache_path
|
45
|
+
root_path.join(fetch(:cache_path))
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
39
49
|
def fetch(key)
|
40
50
|
data.fetch(key, defaults[key])
|
41
51
|
end
|
42
52
|
|
43
53
|
def data
|
44
|
-
|
45
|
-
raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Configuration.load must be called first") unless instance
|
46
|
-
instance.data
|
54
|
+
@data ||= load
|
47
55
|
end
|
48
56
|
|
49
|
-
def
|
50
|
-
|
57
|
+
def load
|
58
|
+
YAML.load(config_path.read)[env].deep_symbolize_keys
|
59
|
+
|
60
|
+
rescue Errno::ENOENT => e
|
61
|
+
raise "Webpacker configuration file not found #{config_path}. " \
|
62
|
+
"Please run rails webpacker:install " \
|
63
|
+
"Error: #{e.message}"
|
64
|
+
|
65
|
+
rescue Psych::SyntaxError => e
|
66
|
+
raise "YAML syntax error occurred while parsing #{config_path}. " \
|
67
|
+
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
|
68
|
+
"Error: #{e.message}"
|
51
69
|
end
|
52
|
-
end
|
53
70
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
HashWithIndifferentAccess.new(YAML.load(File.read(@path))[Webpacker.env])
|
71
|
+
def defaults
|
72
|
+
@defaults ||= \
|
73
|
+
HashWithIndifferentAccess.new(YAML.load_file(File.expand_path("../../install/config/webpacker.yml", __FILE__))[env])
|
58
74
|
end
|
59
75
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Webpacker::DevServer
|
2
|
+
delegate :config, to: :@webpacker
|
3
|
+
|
4
|
+
def initialize(webpacker)
|
5
|
+
@webpacker = webpacker
|
6
|
+
end
|
7
|
+
|
8
|
+
def running?
|
9
|
+
Socket.tcp(host, port, connect_timeout: 1).close
|
10
|
+
true
|
11
|
+
rescue Errno::ECONNREFUSED, NoMethodError
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def hot_module_replacing?
|
16
|
+
fetch(:hmr)
|
17
|
+
end
|
18
|
+
|
19
|
+
def host
|
20
|
+
fetch(:host)
|
21
|
+
end
|
22
|
+
|
23
|
+
def port
|
24
|
+
fetch(:port)
|
25
|
+
end
|
26
|
+
|
27
|
+
def https?
|
28
|
+
fetch(:https)
|
29
|
+
end
|
30
|
+
|
31
|
+
def protocol
|
32
|
+
https? ? "https" : "http"
|
33
|
+
end
|
34
|
+
|
35
|
+
def host_with_port
|
36
|
+
"#{host}:#{port}"
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def fetch(key)
|
41
|
+
config.dev_server.fetch(key, defaults[key])
|
42
|
+
end
|
43
|
+
|
44
|
+
def defaults
|
45
|
+
config.send(:defaults)[:dev_server]
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "rack/proxy"
|
2
|
+
|
3
|
+
class Webpacker::DevServerProxy < Rack::Proxy
|
4
|
+
def rewrite_response(response)
|
5
|
+
status, headers, body = response
|
6
|
+
headers.delete "transfer-encoding"
|
7
|
+
headers.delete "content-length" if Webpacker.dev_server.running? && Webpacker.dev_server.https?
|
8
|
+
response
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform_request(env)
|
12
|
+
if env["PATH_INFO"] =~ /#{public_output_uri_path}/ && Webpacker.dev_server.running?
|
13
|
+
env["HTTP_HOST"] = Webpacker.dev_server.host_with_port
|
14
|
+
super(env)
|
15
|
+
else
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def public_output_uri_path
|
22
|
+
Webpacker.config.public_output_path.relative_path_from(Webpacker.config.public_path)
|
23
|
+
end
|
24
|
+
end
|
data/lib/webpacker/helper.rb
CHANGED
@@ -9,7 +9,7 @@ module Webpacker::Helper
|
|
9
9
|
# In production mode:
|
10
10
|
# <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css"
|
11
11
|
def asset_pack_path(name, **options)
|
12
|
-
asset_path(Webpacker
|
12
|
+
asset_path(Webpacker.manifest.lookup(name), **options)
|
13
13
|
end
|
14
14
|
# Creates a script tag that references the named pack file, as compiled by Webpack per the entries list
|
15
15
|
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
|
@@ -24,24 +24,42 @@ module Webpacker::Helper
|
|
24
24
|
# # In production mode:
|
25
25
|
# <%= javascript_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
|
26
26
|
# <script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
|
27
|
-
def javascript_pack_tag(
|
28
|
-
javascript_include_tag(
|
27
|
+
def javascript_pack_tag(*names, **options)
|
28
|
+
javascript_include_tag(*sources_from_pack_manifest(names, type: :javascript), **options)
|
29
29
|
end
|
30
30
|
|
31
31
|
# Creates a link tag that references the named pack file, as compiled by Webpack per the entries list
|
32
32
|
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
|
33
33
|
# app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
|
34
34
|
#
|
35
|
+
# Note: If the development server is running and hot module replacement is active, this will return nothing.
|
36
|
+
# In that setup you need to configure your styles to be inlined in your JavaScript for hot reloading.
|
37
|
+
#
|
35
38
|
# Examples:
|
36
39
|
#
|
37
40
|
# # In development mode:
|
38
41
|
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
|
39
42
|
# <link rel="stylesheet" media="screen" href="/packs/calendar.css" data-turbolinks-track="reload" />
|
40
43
|
#
|
44
|
+
# # In development mode with hot module replacement:
|
45
|
+
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
|
46
|
+
# nil
|
47
|
+
#
|
41
48
|
# # In production mode:
|
42
49
|
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
|
43
50
|
# <link rel="stylesheet" media="screen" href="/packs/calendar-1016838bab065ae1e122.css" data-turbolinks-track="reload" />
|
44
|
-
def stylesheet_pack_tag(
|
45
|
-
|
51
|
+
def stylesheet_pack_tag(*names, **options)
|
52
|
+
unless Webpacker.dev_server.running? && Webpacker.dev_server.hot_module_replacing?
|
53
|
+
stylesheet_link_tag(*sources_from_pack_manifest(names, type: :stylesheet), **options)
|
54
|
+
end
|
46
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def sources_from_pack_manifest(names, type:)
|
59
|
+
names.map { |name| Webpacker.manifest.lookup(pack_name_with_extension(name, type: type)) }
|
60
|
+
end
|
61
|
+
|
62
|
+
def pack_name_with_extension(name, type:)
|
63
|
+
"#{name}#{compute_asset_extname(name, type: type)}"
|
64
|
+
end
|
47
65
|
end
|
@@ -0,0 +1,44 @@
|
|
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: Rails.root, config_path: Rails.root.join("config/webpacker.yml"))
|
7
|
+
@root_path, @config_path = root_path, config_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def env
|
11
|
+
(ENV["NODE_ENV"].presence_in(available_environments) ||
|
12
|
+
Rails.env.presence_in(available_environments) ||
|
13
|
+
"production".freeze).inquiry
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
@config ||= Webpacker::Configuration.new self
|
18
|
+
end
|
19
|
+
|
20
|
+
def compiler
|
21
|
+
@compiler ||= Webpacker::Compiler.new self
|
22
|
+
end
|
23
|
+
|
24
|
+
def dev_server
|
25
|
+
@dev_server ||= Webpacker::DevServer.new self
|
26
|
+
end
|
27
|
+
|
28
|
+
def manifest
|
29
|
+
@manifest ||= Webpacker::Manifest.new self
|
30
|
+
end
|
31
|
+
|
32
|
+
def commands
|
33
|
+
@commands ||= Webpacker::Commands.new self
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def available_environments
|
38
|
+
if config_path.exist?
|
39
|
+
YAML.load(config_path.read).keys
|
40
|
+
else
|
41
|
+
[].freeze
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|