Skip to content

Commit

Permalink
docs: revise buildpack devdocs
Browse files Browse the repository at this point in the history
  • Loading branch information
James Zetlen committed Aug 3, 2020
1 parent 14eed67 commit b8149be
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 85 deletions.
92 changes: 46 additions & 46 deletions packages/pwa-buildpack/lib/BuildBus/declare-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,24 @@ const { SOURCE_SEP } = require('./Target');
module.exports = targets => {
/**
* @exports BuiltinTargets
*
*/
const builtins = {
/**
* Collects the definitions and documentation for project-wide configuration
* values based on the `envVarDefinitions.json` file.
* Called to collect the definitions and documentation for project-wide
* configuration values. Core environment variables are defined in the
* [`envVarDefinitions.json` file]{@link /pwa-buildpack/reference/environment-variables/core-definitions/}.
*
* The environment variable schema object from this file is extensible
* using an [envVarDefinitions intercept function]{@link envVarDefinitionsIntercept}.
* Intercept this target in your project to add new environment
* variables, typed and documented. This integrates your extension
* configuration with the project-wide environment variable system.
*
* Intercept this target in your project to integrate your extension configuration
* with the project-wide environment variable system.
* @see [Variable definition schema]{@link /pwa-buildpack/reference/environment-variables/definitions-api/}
* @see [Core variable definitions]{@link /pwa-buildpack/reference/environment-variables/core-definitions/}
*
*
* @see [envVarDefinitions topic]{@link http://pwastudio.io/pwa-buildpack/reference/environment-variables/}
*
* @param {object} envVarDefinitions The [variable definitions object]{@link /pwa-buildpack/reference/environment-variables/definitions-api/}.
* Modify in place.
* @member {tapable.SyncHook}
*
* @example <caption>Add config fields for your extension</caption>
* targets.of('@magento/pwa-buildpack').envVarDefinitions.tap(defs => {
* defs.sections.push({
Expand All @@ -50,15 +51,16 @@ module.exports = targets => {
envVarDefinitions: new targets.types.Sync(['definitions']),

/**
* Collects requests to intercept and modify individual files from this
* dependency.
* Called when configuring the loading and processing rules for Webpack.
*
* Since the storefront developer is in charge of important dependencies,
* Interceptors receive a function `addTransform()`. They may call this function to request that Webpack process _a particular file_ with a particular transform module.
*
* Since the storefront developer is in charge of important dependencies,
* the interceptor files in the storefront project itself should be able to
* transform ANY file from ANY dependency.
* However, interceptor files in the storefront dependencies are prevented
* from modifying files from other dependencies.
*
*
* NOTE: This is a very low-level extension point. It should be used as a
* building block for higher-level extensions that expose functional
* areas rather than files on disk.
Expand All @@ -81,7 +83,7 @@ module.exports = targets => {
*
* Calls interceptors whenever a Webpack Compiler object is created.
* This almost always happens once per build, even in dev mode.
*
*
* Use an [intercept function]{@link webpackCompilerIntercept} on this target
* to access the [webpack compiler]{@link https://webpack.js.org/api/compiler-hooks/}.
*
Expand All @@ -106,26 +108,20 @@ module.exports = targets => {
* the modules by default. It will expect extension code to be CommonJS
* style and will not process the ES Modules.
* Likewise, if your extension uses CSS Modules, you must add the `cssModules` flag using this target.
* Use a [specialFeatures intercept function]{@link specialFeaturesIntercept}
* Use a [specialFeatures intercept function]{@link specialFeaturesIntercept}
* to add special build features for the modules used in your project.
*
* @see [Special flags in `configureWebpack()`]{@link http://pwastudio.io/pwa-buildpack/reference/configure-webpack/#special-flags}
*
* @member {tapable.SyncHook}
*
*
* @example <caption>Declare that your extension contains CSS modules.</caption>
* targets.of('@magento/pwa-buildpack').specialFeatures.tap(featuresByModule => {
* featuresByModule['my-module'] = { cssModules: true };
* })
*/
specialFeatures: new targets.types.Sync(['special']),

/**
* @callback transformUpwardIntercept
* @param {object} Parsed UPWARD definition object.
* @returns {Promise} - Interceptors do not need to return.
*/

/**
* Exposes the fully merged UPWARD definition for fine tuning. The
* UpwardIncludePlugin does a simple shallow merge of the upward.yml
Expand Down Expand Up @@ -154,9 +150,8 @@ module.exports = targets => {
* })
*
*
* @type {tapable.AsyncSeriesHook}
* @member {tapable.AsyncSeriesHook}
* @param {transformUpwardIntercept} interceptor
* @memberof BuiltinTargets
*/
transformUpward: new targets.types.AsyncSeries(['definitions'])
};
Expand Down Expand Up @@ -220,20 +215,6 @@ module.exports = targets => {
targets.declare(builtins);
};

/** Type definitions related to: envVarDefinitions */

/**
* Passed as the first parameter to interceptors of the `envVarDefinitions` object.
*
* Interceptors of `envVarDefinitions` may mutate the definitions object.
* These functions do not need to return a value.
*
* @see [EnvVarDefinitions]{@link http://pwastudio.io/pwa-buildpack/reference/environment-variables/definitions-api/#envvardefinitions--object}
*
* @callback envVarDefinitionsIntercept
* @param {EnvVarDefinitions} defs - The definitions object
*/

/** Type definitions related to: transformModules */

/**
Expand All @@ -249,23 +230,23 @@ module.exports = targets => {

/**
* Callback to add a transform.
*
* @see [TransformRequest]{@link https://pwastudio.io/pwa-buildpack/reference/moduletransformconfig/#buildpackwebpacktoolstransformrequest--object}
*
*
* @see [TransformRequest]{@link https://pwastudio.io/pwa-buildpack/reference/transform-requests/#addTransform}
*
* @callback addTransform
* @param {Buildpack/WebpackTools~TransformRequest} transformRequest -
* [Request]{@link https://pwastudio.io/pwa-buildpack/reference/moduletransformconfig/#buildpackwebpacktoolstransformrequest--object}
* [Request]{@link https://pwastudio.io/pwa-buildpack/reference/transform-requests/#addTransform}
* to apply a transform to a file provided by this dependency.
*/

/** Type definitions related to: webpackCompiler */

/**
* Intercept function signature for the webpackCompiler target.
*
*
* Interceptors of `webpackCompiler` should tap hooks on the provided
* `compiler` object. Any returned value will be ignored.
*
*
* @callback webpackCompilerIntercept
* @param {webpack.Compiler} compiler - The [webpack compiler]{@link https://webpack.js.org/api/compiler-hooks/} instance
*/
Expand All @@ -274,11 +255,30 @@ module.exports = targets => {

/**
* Intercept function signature for the specialFeatures target.
*
*
* Interceptors of the `specialFeatures` target can use the mapping object provided
* to map special build flags to their project modules.
*
* @callback specialFeaturesIntercept
* @param {Object.<string, SpecialBuildFlags>} featuresByModule -
* An object mapping of module names to their special build flags
*/

/** Type definitions related to: transformUpward */

/**
* Intercept function signature for the transformUpward target.
*
* Interceptors of the `transformUpward` target receive the parsed UPWARD
* definition as a plain JavaScript object. Mutate that object in place to
* change the final `upward.yml` output by the build.
*
* This Target can be used asynchronously. If you need to do asynchronous work
* to get what you need to modify the UPWARD definition (for example, a network
* request) then you can provide an `async` function as interceptor (or simply
* return a Promise from any function).
*
* @callback transformUpwardIntercept
* @param {object} definition - Parsed UPWARD definition object.
* @returns {Promise}
*/
79 changes: 57 additions & 22 deletions packages/pwa-buildpack/lib/WebpackTools/ModuleTransformConfig.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,74 @@
/**
* @module Buildpack/WebpackTools
*/
const path = require('path');

/**
* @typedef {Object} TransformRequest
* Instruction to the Webpack transform loader to pass a given file through a
* transform function implemented in a given Node module, with an optional set
* of configuration values that will be passed to the transform function.
* @typedef {function(TransformRequest)} addTransform
* Add a request to transform a file in the build. This function is passed as
* the first argument to an interceptor of the `transformModules` target.
*
* @prop {string} type - Type of transform. `'babel'` expects a Babel plugin as the `transformModule`. `"source"` expects a Webpack loader.
* @prop {string} requestor - Name of the file doing the requesting.
* @prop {string} fileToTransform - Relative path to the file in this module
* to be transformed when it is loaded by the compilation.
* @prop {string} transformModule - The Node module that exports the transform
* function to use. Node will resolve this relative to project root.
* @prop {object} [options] - Config values to send to the transform function.
* _Note: Options should be serializable to JSON as Webpack loader options._
* @param {TransformRequest} req - Instruction object for the requested
* transform, including the transform to apply, the target source code, and
* other options.
*
* @returns null
*/

/** @enum {string} */
const TransformType = {
/**
* Process the _source code_ of `fileToTransform` through the
* `transformModule` as text. When applying a `source` TransformRequest,
* Buildpack will use the `transformModule` as a [Webpack
* loader](https://v4.webpack.js.org/api/loaders/), so it must implement
* that interface. Any Webpack loader can be used as a `transformModule`
* for `source` TransformRequests.
*
* `source` transforms are fast and can run on source code of any language,
* but they aren't as precise and safe as AST-type transforms when modifying
* code.
*/
source: 'source',
/**
* Process the _abstract syntax tree_ of the ES module specified by `fileToTransform` through the `transformModule` as a [Babel AST](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md).
* When applying a `babel` TransformRequest, Buildpack will use the
* `transformModule` as a [Babel plugin](https://github.com/jamiebuilds/babel-handbook), so it must implement that interface. Any Babel plugin can be used as a `transformModule` for `babel` TransformRequests.
*
* `babel` transforms are powerful and versatile, giving the transformer
* much more insight into the structure of the source code to modify.
* However, they are slower than `source` transforms, and they can only work
* on ES Modules.
*/
babel: 'babel'
};

/**
* @typedef {Object.<string, FileExportWrappers>} configSerialized
* A map of filenames of modules to be wrapped, to FileExportWrappers declaring
* which exports of those modules will be wrapped with what.
* @typedef {Object} TransformRequest
* Instruction for configuring Webpack to apply custom transformations to one
* particular file. The [`configureWebpack()` function]{@link /pwa-buildpack/reference/configure-webpack/}
* gathers TransformRequests from all interceptors of the `transformModules`
* target and turns them into a configuration of Webpack [module
* rules](https://v4.webpack.js.org/configuration/module/#modulerules).
*
* @prop {TransformType} type - The type of transformation to apply.
* @prop {string} requestor - Name of the module making this request. Used for debugging purposes.
* @prop {string} fileToTransform - Resolvable path to the file to be transformed itself, the same path that you'd use in `import` or `require()`.
* @prop {string} transformModule - Absolute path to the Node module that will actually be doing the transforming. This path may be resolved using different
* rules at different times, so it's best for this path to always be absolute.
* @prop {object} [options] - Config values to send to the transform function.
* _Note: Options should be serializable to JSON as Webpack loader options
* and/or Babel plugin options.._
*/

/**
* Configuration builder for module transforms. Accepts TransformRequests
* and emits loader config objects for Buildpack's custom transform loaders.
*/
class ModuleTransformConfig {
/** @borrows TransformType as types */
static get types() {
return TransformType;
}
/**
* @private
* @constructs
* @param {MagentoResolver} resolver - Resolver to use when finding real paths of
* modules requested.
Expand Down Expand Up @@ -75,10 +113,7 @@ class ModuleTransformConfig {
: path.join(requestor, fileToTransform);
}
/**
*
* Add a request to transform a file in the build.
*
* @param {TransformRequest} req - Request object
* @borrows addTransform as add
*/
add({ requestor, fileToTransform, transformModule, type, options }) {
let absTransformModule;
Expand Down
4 changes: 2 additions & 2 deletions pwa-devdocs/src/_data/buildpack-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ entries:
entries:
- label: Targets
url: /pwa-buildpack/reference/targets/
- label: ModuleTransformConfig
url: /pwa-buildpack/reference/moduletransformconfig/
- label: EnvVarDefinitions
url: /pwa-buildpack/reference/environment-variables/definitions-api/
- label: Transform Requests
url: /pwa-buildpack/reference/transform-requests/
# # TODO: when i document this
# - label: WrapEsmLoader
# url: /pwa-buildpack/reference/webpack-tools/loaders/wrap-esm-loader/
Expand Down

This file was deleted.

9 changes: 4 additions & 5 deletions pwa-devdocs/src/pwa-buildpack/reference/targets/index.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
---
title: Extensibility Targets
title: Built-in Targets
---

Buildpack's targets follow the same Target API as other packages' targets, but they play a unique role. Buildpack targets are the fundamental "roots" of the PWA Studio Target system.

All other Targets operate by intercepting other Targets.
Targets can only be called when Buildpack core code creates a BuildBus, which it does for every build and for many commands.
Extensions will then run their declare and intercept files, attaching interceptor functions to each others' dependencies.
Still, nothing _calls_ targets to run any interceptors until Buildpack begins the process, by directly invoking one of its _own_ targets.
BuildBus runs the declare and intercept phases by itself.
But nothing _calls_ targets to run any interceptors until Buildpack begins the process, by directly invoking one of its _own_ targets.

The Buildpack targets are therefore very generic and low-level. They are meant to be used as building blocks for higher-level targets which provide a convenient API for some common business purpose, such as adding routing or navigation logic.
The Buildpack targets are therefore very generic and low-level. They are meant to be used as building blocks for higher-level feature targets, such as adding routing or navigation logic.

Even deeper than Buildpack targets are the very similar Hooks that make up [Webpack's plugin system](https://v4.webpack.js.org/api/plugins/). Interceptors can use Buildpack's `webpackCompiler` target to acquire a reference to the Webpack Compiler object for each build, and can then do anything a Webpack plugin can do.
Because of their similarity in form and function, the PWA Studio Targets system integrates seamlessly into the larger Webpack ecosystem as a commerce-driven superset of its functionality.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Transform Requests
---

The built-in [`transformModules`][] target is a powerful way to customize the build process for a partiular file or set of files.
Many common Targets are implemented using the `transformModules` target and a custom transformer module.

Interceptors of this target receive a single function as their first argument. This is the `addTransform` function documented below.

<!--
The reference doc content is generated automatically from the source code.
To update this section, update the doc blocks in the source code
-->

{% include auto-generated/pwa-buildpack/lib/WebpackTools/ModuleTransformConfig.md %}


[`transformModules`]: {%link pwa-buildpack/reference/targets/index.md %}#module_BuiltinTargets.transformModules

0 comments on commit b8149be

Please sign in to comment.