daml/navigator/frontend/BUILD.bazel
Andreas Herrmann 15395b31a2
Document non-reproducible outputs (#7115)
* Explain why vsix is non-reproducible

* Explain why frontend bundle is non-reproducible

changelog_begin
changelog_end

Co-authored-by: Andreas Herrmann <andreas.herrmann@tweag.io>
2020-08-13 09:19:46 +00:00

151 lines
5.7 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
load("@os_info//:os_info.bzl", "is_windows")
# load ("@npm_bazel_typescript//:index.bzl", "ts_library")
filegroup(
name = "src",
srcs = glob(["src/**"]),
)
# TODO: Set up a target for generating GraphQL query definition files.
# Currently, these checked in, and updated with 'make update-graphql-types'.
# TODO: Consider switching from Apollo to https://github.com/dotansimha/graphql-code-generator,
# as the latter can be configured such that no postprocessing on the generated files is necessary.
# nodejs_binary(
# name = "apollo_codegen",
# entry_point = "node_modules/apollo/bin/run",
# data = [
# "@navigator_frontend_deps//apollo",
# ":src_files"
# ],
# templated_args = [
# "client:codegen",
# "-c ./apollo.config.js",
# "--passthroughCustomScalars",
# "--customScalarsPrefix=OpaqueTypes.",
# "--outputFlat",
# "--target",
# "typescript",
# "--includes=\"$(location :src)/ui-core/**/*.ts*\"",
# "$(location :src)/ui-core/src/api/QueriesBody.txt"
# ]
# )
# Webpack build tool
# The webpack config is a JavaScript file that can import other modules.
# These dependencies are not automagically detected by the pregenerated
# "@navigator_frontend_deps//webpack/bin:webpack" target, so we need to create
# a custom node.js binary that has access to all plugins loaded by webpack at runtime.
nodejs_binary(
name = "webpack",
entry_point = "@navigator_frontend_deps//:node_modules/webpack/bin/webpack.js",
node_modules = "@navigator_frontend_deps//:node_modules",
# The webpack build step requires almost all of the node_modules dependencies
# data = [
# ...
# ],
)
# TODO (drsk) We should switch the frontend rule to use the bazel typescript rules instead of
# webpack. Something like the following:
# ts_library(
# name = "frontend",
# tsconfig = ":tsconfig.json",
# srcs = glob(["**/*.ts"]),
# data = [":package.json", ":tslint.json"],
# node_modules = "@navigator_frontend_deps//:node_modules",
# visibility = [
# "//navigator:__subpackages__",
# ],
# )
# Builds the frontend single page application and bundles all output files
#  (HTML + JavaScript + CSS + images) in a .tgz or .jar archive.
# This target is non-reproducible. The browsercheck and bundle outputs
# generated by webpack contain hashes in their file names that are different
# on each invokation. The following were attempted to make the outputs
# reproducible but failed:
# - Use `[contenthash]` instead of `[hash]` (including `output.chunkFilename`), see https://webpack.js.org/guides/caching/
# - Configure `optimization.moduleIds = 'hashed'`, see https://webpack.js.org/configuration/optimization/#optimizationmoduleids
# - Configure `optimization.chunkIds = 'named'`, see https://webpack.js.org/configuration/optimization/#optimizationchunkids
# - Use https://www.npmjs.com/package/webpack-plugin-hash-output
# - Disable source map
genrule(
name = "frontend",
srcs = [
"webpack.config.js",
"declarations.d.ts",
"tsconfig.json",
"tslint.json",
"package.json",
".modernizrrc",
":src",
"@navigator_frontend_deps//:node_modules",
],
outs = [
"frontend.tgz",
"frontend.jar",
],
cmd = """
# Working directories
export IN="$$(pwd)/$(@D)/in"
export OUT="$$(pwd)/$(@D)/out"
rm -rf $$IN $$OUT
mkdir "$$IN" "$$OUT"
# Our tools (node.js, webpack, webpack plugins, typescript) do not work nicely
# with symbolic links and a node_modules directory that is not in the project root.
# All input files are therefore copied to a working directory.
cp -rL "$$(pwd)/$$(dirname $(execpath declarations.d.ts))/src" "$$IN/src"
cp -rL "$$(pwd)/external/navigator_frontend_deps/node_modules" "$$IN/node_modules"
cp -L "$$(pwd)/$(execpath webpack.config.js)" "$$IN/webpack.config.js"
cp -L "$$(pwd)/$(execpath .modernizrrc)" "$$IN/.modernizrrc"
cp -L "$$(pwd)/$(execpath tsconfig.json)" "$$IN/tsconfig.json"
cp -L "$$(pwd)/$(execpath tslint.json)" "$$IN/tslint.json"
cp -L "$$(pwd)/$(execpath declarations.d.ts)" "$$IN/declarations.d.ts"
# Webpack needs the HOME variable to be set
export HOME="$$IN"
# Run webpack.
# To debug, add the following options:
# -d --progress --display-error-details --verbose
WP_IN={WP_IN}
WP_OUT={WP_OUT}
$(execpath :webpack) \\
--config="$$IN/webpack.config.js" \\
--env.prod \\
--env.paths_case_check="{PATHS_CASE_CHECK}" \\
--env.bazel_in_dir="{WP_IN_ESCAPED}" \\
--env.bazel_out_dir="{WP_OUT_ESCAPED}"
# Package result (.TGZ)
# To debug, change 'c' to 'cv'.
echo "Packaging result from $$OUT to $(@D)/frontend.tgz"
$(execpath //bazel_tools/sh:mktgz) $(@D)/frontend.tgz -C $$OUT .
# Package result (.JAR)
echo "Packaging result from $$OUT to $(@D)/frontend.jar"
$(rootpath @bazel_tools//tools/zip:zipper) c "$(@D)/frontend.jar" \\
$$($(POSIX_FIND) $$OUT -type f -printf "%P=%p\\n" | $(POSIX_SORT))
""".format(
PATHS_CASE_CHECK = "false" if is_windows else "true",
WP_IN = "$$(cygpath -w $$IN)" if is_windows else "$$IN",
WP_IN_ESCAPED = "'$$WP_IN'" if is_windows else "$$WP_IN",
WP_OUT = "$$(cygpath -w $$OUT/frontend)" if is_windows else "$$OUT/frontend",
WP_OUT_ESCAPED = "'$$WP_OUT'" if is_windows else "$$WP_OUT",
),
toolchains = ["@rules_sh//sh/posix:make_variables"],
tools = [
":webpack",
"//bazel_tools/sh:mktgz",
"@bazel_tools//tools/zip:zipper",
],
visibility = [
"//navigator:__subpackages__",
],
)