Mischback / colorizer

A simple web-based colorscheme builder which focuses on contrast values.

Home Page:https://mischback.github.io/colorizer/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build process for ``development`` and ``production``

Mischback opened this issue · comments

Production Requirements

  • Script
    • create optimized bundle colorizer.js using Rollup's terser plugin
    • no source maps
  • Style
    • compile using sass
    • run through postcss with purgecss, autoprefixer and cssnano
  • Cache Busting
    • create the assets and then hash the respective file's content and add hash to the filename
    • replace original filename with filename with hash in index.html

Development Requirements

  • Script
    • create bundle colorizer.js in human readable form
    • include TS sources / sourcemaps
  • Style
    • compile using sass
    • run through postcss with purgecss

Experimental (.rollup.config.js)

// SPDX-FileCopyrightText: 2023 Mischback
// SPDX-License-Identifier: MIT
// SPDX-FileType: SOURCE

/**
 * Configuration for ``Rollup``.
 * 
 * ``Rollup`` is only used to *bundle* the script files. It does not create
 * *the whole bundle*, including other static assets (e.g. stylesheets, ...).
 *
 * The overall build process is driven by ``make`` and there are dedicated
 * recipes to transpile / post-process the other assets.
 *
 * This configuration deliberately omits specifying the ``input`` file(s) and
 * the desired output location. These parameters should be provided by command
 * line arguments (``--input``/``-i`` and ``--file``/``-o`` or 
 * ``--dir``/``-d``).
 *
 * References:
 * - https://rollupjs.org/configuration-options/#input
 * - https://rollupjs.org/configuration-options/#output-dir
 * - https://rollupjs.org/configuration-options/#output-file
 */

// import nodeResolve from "@rollup/plugin-node-resolve";  // Not in use as of now!
import terser from "@rollup/plugin-terser";
import typescript from "@rollup/plugin-typescript";

/* Determine if we're running in *development mode*.
 *
 * See the ``Makefile`` for the value of the *development flag*.
 */
const devMode = process.env.DEV_FLAG === "dev";

/* TODO: "es" or "iife"?!
 *
 * https://rollupjs.org/configuration-options/#output-format
 */
const defaultOutputFormat = "es";

const config = {
  output: {
    assetFileNames: "[name][extname]",
    format: outputFormat,
  },
  plugins: [
    typescript(),
  ],
};

if (devMode === true) {
  // FIXME: Make sourcemaps actually work
  //        Desired: Show references to the actual TS sources!
  //        Ref: https://stackoverflow.com/questions/63218218/rollup-is-not-generating-typescript-sourcemap
  config.output.sourcemaps = true;
  config.output.validate = true;  // highly experimental
} else {
  config.output.plugins = [terser()];
}

export default config;
// SPDX-FileCopyrightText: 2023 Mischback
// SPDX-License-Identifier: MIT
// SPDX-FileType: SOURCE

// import nodeResolve from "@rollup/plugin-node-resolve";  // Not in use as of now!
import terser from "@rollup/plugin-terser";
import typescript from "@rollup/plugin-typescript";

/* Determine if we're running in *development mode*.
 *
 * See the ``Makefile`` for the value of the *development flag*.
 */
const devMode = process.env.DEV_FLAG === "dev";

/* TODO: "es" or "iife"?!
 *
 * https://rollupjs.org/configuration-options/#output-format
 */
const defaultOutputFormat = "es";

export default cmdArgs => {
  const inputEntrypoint = cmdArgs.input || false;
  if (inputEntrypoint === false) {
    throw new Error("Missing argument: --input/-i");
  }
  delete cmdArgs.input;

  const outputDir = cmdArgs.output.dir || false;
  if (outputDir === false) {
    throw new Error("Missing argument: --dir/-d");
  }
  delete cmdArgs.output.dir;

  const outputFormat = cmdArgs.output.format || defaultOutputFormat;
  delete cmdArgs.output.format;

  const config = {
    input: inputEntrypoint,
    plugins: [
      typescript(),
    ],
    output: {
      dir: outputDir,
      format: outputFormat,
    },
  };

  if (devMode === true) {
    config.output.assetFileNames = "[name].[ext]";
    config.output.sourcemaps = true;
    config.output.validate = true;  // highly experimental
  } else {
    config.output.assetFileNames = "[name].[hash:10].[ext]";
    config.output.plugins = [terser()];
  }

  console.log(config);

  return config;
}

Experimental (postcss.config.js)

// SPDX-FileCopyrightText: 2023 Mischback
// SPDX-License-Identifier: MIT
// SPDX-FileType: SOURCE

const purgecss = require("@fullhuman/postcss-purgecss")(
  {
    content: ["./**/*.html"],
    fontFace: true,
    keyFrames: true,
    variables: true,
    // safelist: [],
    blocklist: [],
  }
);

/* Determine if we're running in *development mode*.
 *
 * See the ``Makefile`` for the value of the *development flag*.
 */
const devMode = process.env.DEV_FLAG === "dev";

/* The default output format.
 *
 * *development mode* will skip all optimisation plugins.
 */
const config = {
  plugins: [
    purgecss,
    require("autoprefixer")(),
    require("cssnano")(),
  ],
};

if (devMode === true) {
  config.plugins = [purgecss];
}

module.exports = config;

Experimental Cache Busting

Generally speaking, cache busting is quite easy (see initial post in this issue).

A possible solution might be implemented using posthtml:

  • get posthtml
    npm install --save-dev posthtml posthtml-cli posthtml-hash
  • provide configuration for posthtml
  • integrate into build process
    • modify index.html source file (adjust href/src attributes)
      • the approach described in the doc might not work, as .[hash]. might clash with Rollup's output.assetFileNames configuration parameter
      • however, custom patterns are possible; have to be synchronized with .rollup.config.js (output.assetFileNames)
        • not required when the Makefile below; instead, this has to be synchronized with $(BUILD_ASSETS) setup
    • adjust .rollup.config.js (see above) to create the required filename for the bundle the Makefile did work!
    • provide recipe in Makefile

Experimental Makefile

# Source directory
SRC_DIR := $(REPO_ROOT)/src

# All script source files, meant to be used as a dependency
SRC_SCRIPT := $(shell find $(SRC_DIR)/script -type f)

# All style source files, meant to be used as a dependency
SRC_STYLE := $(shell find $(SRC_DIR)/style -type f)

# This string will be injected into filenames of static assets.
# Has to be synchronized with ``posthtml.config.js``.
BUSTING_HOOK := BUSTING

# Build directory
BUILD_DIR := $(REPO_ROOT)/dist
BUILD_HTML_DIR := $(BUILD_DIR)
BUILD_ASSETS_DIR := $(BUILD_DIR)/assets
BUILD_ASSETS_RAW := style.css colorizer.js

# 1: Should still be ``style.css colorizer.js``
# BUILD_ASSETS := $(join $(basename $(BUILD_ASSETS_RAW)), $(suffix $(BUILD_ASSETS_RAW)))
# 2: Should be ``style.asdf.css colorizer.asdf.js``
# BUILD_ASSETS := $(join $(addsuffix $(BUSTING_HOOK), $(basename $(BUILD_ASSETS_RAW))), $(suffix $(BUILD_ASSETS_RAW)))
# 3: 
BUILD_ASSETS := $(addprefix $(BUILD_ASSETS_DIR)/, $(join $(addsuffix ".asdf.", $(basename $(BUILD_ASSETS_RAW))), $(suffix $(BUILD_ASSETS_RAW))))


debug/assets :
	echo $(BUILD_ASSETS)
.PHONY: debug/assets



build : $(BUILD_HTML_DIR)/index.html
.PHONY : build

# Build in development mode
#
# Build for development, providing source maps etc...
# This forces a rebuild every time!
build/development :
	touch $(SRC_DIR)/index.html && \
	touch $(firstword $(SRC_SCRIPT)) && \
	touch $(firstword $(SRC_STYLE)) && \
	BUILD_MODE=$(DEV_FLAG) \
	$(MAKE) build
.PHONY : build/development

$(BUILD_HTML_DIR)/index.html : $(SRC_DIR)/index.html $(BUILD_ASSETS) posthtml.config.js | $(STAMP_NODE_READY)
	$(create_dir)
	npx posthtml -c .posthtml.config.js -i $< -o $@ 

# Run ``sass`` to compile SASS/SCSS sources to CSS
$(BUILD_ASSETS_DIR)/%.$(BUSTING_HOOK).css : $(SRC_DIR)/style/%.scss $(SRC_STYLE) postcss.config.js | $(STAMP_NODE_READY)
	$(create_dir)
ifeq ($(BUILD_MODE), $(DEV_FLAG))
	echo "[development] building stylesheet..."
	# FIXME: Why is the DEV_FLAG not passed here, but below?!
	npx sass --verbose --embed-sources --embed-source-map --stop-on-error $< | \
	npx postcss -o $@
else
	DEV_FLAG=$(DEV_FLAG) \
	npx sass --verbose --stop-on-error $< | \
	npx postcss -o $@
endif

# Run ``rollup`` to transpile and bundle TS sources to JS
$(BUILD_ASSETS_DIR)/%.$(BUSTING_HOOK).js : $(SRC_DIR)/script/%.ts $(SRC_SCRIPT) rollup.config.js | $(STAMP_NODE_READY)
	$(create_dir)
ifeq ($(BUILD_MODE), $(DEV_FLAG))
	echo "[development] building script bundle..."
	DEV_FLAG=$(DEV_FLAG) \
	npx rollup -c rollup.config.js --bundleConfigAsCjs -i $< -o $@
else
	npx rollup -c rollup.config.js --bundleConfigAsCjs -i $< -o $@
endif