mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-04 12:04:20 +08:00
Make priv generation into a compiler task (#2978)
This commit is contained in:
parent
28bbca9b0a
commit
9535e9e536
4 changed files with 83 additions and 57 deletions
|
@ -33,17 +33,17 @@ defmodule LivebookWeb.Endpoint do
|
|||
# To account for both cases, we configure Plug.Static :from as MFA
|
||||
# and return the accessible priv/ location in both scenarios.
|
||||
#
|
||||
# The priv/ static files are generated by the livebook.gen_priv task
|
||||
# before building the escript or the release. We gzip the static
|
||||
# files in priv/, since we want to serve them gzipped, and we don't
|
||||
# include the non-gzipped ones to minimize app size. Note that we
|
||||
# still have a separate static/ directory with the CI-precompiled
|
||||
# assets, which we keep in Git so that people can install escript
|
||||
# from GitHub or run MIX_ENV=prod phx.server, without Node and NPM.
|
||||
# Storing minified assets is already not ideal, but we definitely
|
||||
# want to avoid storing the gzipped variants in Git. That's why we
|
||||
# store the assets uncompressed and then generate priv/static with
|
||||
# their compressed variants as part of the build process.
|
||||
# The priv/ static files are generated by the compile.livebook_priv
|
||||
# as part of compilation. We gzip the static files in priv/, since
|
||||
# we want to serve them gzipped, and we don't include the non-gzipped
|
||||
# ones to minimize app size. Note that we still have a separate
|
||||
# static/ directory with the CI-precompiled assets, which we keep
|
||||
# in Git so that people can install escript from GitHub or run
|
||||
# MIX_ENV=prod phx.server, without Node and NPM. Storing minified
|
||||
# assets is already not ideal, but we definitely want to avoid
|
||||
# storing the gzipped variants in Git. That's why we store the
|
||||
# assets uncompressed and then generate priv/static with their
|
||||
# compressed variants at compile time.
|
||||
|
||||
if code_reloading? do
|
||||
# In development, we use assets from tmp/static_dev, which are
|
||||
|
|
70
lib/mix/tasks/compile.livebook_priv.ex
Normal file
70
lib/mix/tasks/compile.livebook_priv.ex
Normal file
|
@ -0,0 +1,70 @@
|
|||
defmodule Mix.Tasks.Compile.LivebookPriv do
|
||||
@moduledoc false
|
||||
|
||||
use Mix.Task
|
||||
|
||||
@gzippable_exts ~w(.js .css .txt .text .html .json .svg .eot .ttf)
|
||||
|
||||
@impl true
|
||||
def run(_args) do
|
||||
app_path = Mix.Project.app_path()
|
||||
manifest_path = Path.join(app_path, "compile.livebook_priv")
|
||||
|
||||
prev_mtime =
|
||||
case File.read(manifest_path) do
|
||||
{:ok, binary} -> :erlang.binary_to_term(binary)
|
||||
{:error, _error} -> nil
|
||||
end
|
||||
|
||||
mtime1 =
|
||||
compress_and_copy(
|
||||
"static",
|
||||
Path.join(app_path, "priv/static"),
|
||||
prev_mtime
|
||||
)
|
||||
|
||||
mtime2 =
|
||||
compress_and_copy(
|
||||
"iframe/priv/static/iframe",
|
||||
Path.join(app_path, "priv/iframe_static"),
|
||||
prev_mtime
|
||||
)
|
||||
|
||||
mtime = max(mtime1, mtime2)
|
||||
File.write!(manifest_path, :erlang.term_to_binary(mtime))
|
||||
:ok
|
||||
end
|
||||
|
||||
defp compress_and_copy(source_dir, target_dir, prev_mtime) do
|
||||
source_paths = Path.wildcard(Path.join(source_dir, "**/*"))
|
||||
mtime = paths_mtime(source_paths)
|
||||
|
||||
changed? = prev_mtime == nil or mtime > prev_mtime
|
||||
|
||||
if changed? do
|
||||
File.rm_rf!(target_dir)
|
||||
|
||||
for source_path <- source_paths, File.regular?(source_path) do
|
||||
target_path = Path.join(target_dir, Path.relative_to(source_path, source_dir))
|
||||
File.mkdir_p!(Path.dirname(target_path))
|
||||
|
||||
if Path.extname(source_path) in @gzippable_exts do
|
||||
content = source_path |> File.read!() |> :zlib.gzip()
|
||||
File.write!(target_path <> ".gz", content)
|
||||
else
|
||||
File.cp!(source_path, target_path)
|
||||
end
|
||||
end
|
||||
|
||||
Mix.shell().info("Generated #{target_dir} with compressed files from #{source_dir}")
|
||||
end
|
||||
|
||||
mtime
|
||||
end
|
||||
|
||||
defp paths_mtime(paths) do
|
||||
paths
|
||||
|> Enum.map(fn path -> File.stat!(path).mtime end)
|
||||
|> Enum.max()
|
||||
end
|
||||
end
|
|
@ -1,42 +0,0 @@
|
|||
defmodule Mix.Tasks.Livebook.GenPriv do
|
||||
@moduledoc false
|
||||
|
||||
use Mix.Task
|
||||
|
||||
@gzippable_exts ~w(.js .css .txt .text .html .json .svg .eot .ttf)
|
||||
|
||||
@impl true
|
||||
def run([]) do
|
||||
# Use absolute paths, instead of relying on the current mix project,
|
||||
# so the task can be invoked by nerves_livebook.
|
||||
app_path = Application.app_dir(:livebook)
|
||||
project_dir = Path.expand("../../..", __DIR__)
|
||||
|
||||
compress_and_copy(Path.join(project_dir, "static"), Path.join(app_path, "priv/static"))
|
||||
|
||||
compress_and_copy(
|
||||
Path.join(project_dir, "iframe/priv/static/iframe"),
|
||||
Path.join(app_path, "priv/iframe_static")
|
||||
)
|
||||
end
|
||||
|
||||
defp compress_and_copy(source_dir, target_dir) do
|
||||
File.rm_rf!(target_dir)
|
||||
|
||||
source_paths = Path.wildcard(Path.join(source_dir, "**/*"))
|
||||
|
||||
for source_path <- source_paths, File.regular?(source_path) do
|
||||
target_path = Path.join(target_dir, Path.relative_to(source_path, source_dir))
|
||||
File.mkdir_p!(Path.dirname(target_path))
|
||||
|
||||
if Path.extname(source_path) in @gzippable_exts do
|
||||
content = source_path |> File.read!() |> :zlib.gzip()
|
||||
File.write!(target_path <> ".gz", content)
|
||||
else
|
||||
File.cp!(source_path, target_path)
|
||||
end
|
||||
end
|
||||
|
||||
Mix.shell().info("Generated #{target_dir} with compressed files from #{source_dir}")
|
||||
end
|
||||
end
|
6
mix.exs
6
mix.exs
|
@ -18,6 +18,7 @@ defmodule Livebook.MixProject do
|
|||
description: @description,
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
test_elixirc_options: [docs: true],
|
||||
compilers: Mix.compilers() ++ [:livebook_priv],
|
||||
start_permanent: Mix.env() == :prod,
|
||||
listeners: [Phoenix.CodeReloader],
|
||||
aliases: aliases(),
|
||||
|
@ -69,10 +70,7 @@ defmodule Livebook.MixProject do
|
|||
setup: ["deps.get", "cmd --cd assets npm install"],
|
||||
"assets.deploy": ["cmd npm run deploy --prefix assets"],
|
||||
"format.all": ["format", "cmd --cd assets npm run --silent format"],
|
||||
"protobuf.generate": ["cmd --cd proto mix protobuf.generate"],
|
||||
"phx.server": ["livebook.gen_priv", "phx.server"],
|
||||
"escript.build": ["livebook.gen_priv", "escript.build"],
|
||||
release: ["livebook.gen_priv", "release"]
|
||||
"protobuf.generate": ["cmd --cd proto mix protobuf.generate"]
|
||||
]
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue