From ba045068ed619e4891da8d71ea38b07ceb92efda Mon Sep 17 00:00:00 2001
From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com>
Date: Fri, 4 Feb 2022 09:54:36 -0800
Subject: [PATCH 01/39] Bring over prototype of updated heft-web-rig
---
rigs/heft-web-rig/package.json | 30 +-
.../profiles/app/config/heft.json | 156 ++++++++++
.../profiles/app/config/jest.config.json | 5 +
.../profiles/app/config/rush-project.json | 12 +
.../profiles/app/config/typescript.json | 116 ++++++++
.../profiles/app/tsconfig-base.json | 31 ++
.../profiles/app/webpack-base.config.js | 33 +++
.../library/config/api-extractor-task.json | 6 +
.../profiles/library/config/heft.json | 174 ++++++++---
.../profiles/library/config/typescript.json | 66 ++++-
.../profiles/library/tsconfig-base.json | 2 +
.../shared/webpack-base.config.js | 270 ++++++++++++++++++
12 files changed, 847 insertions(+), 54 deletions(-)
create mode 100644 rigs/heft-web-rig/profiles/app/config/heft.json
create mode 100644 rigs/heft-web-rig/profiles/app/config/jest.config.json
create mode 100644 rigs/heft-web-rig/profiles/app/config/rush-project.json
create mode 100644 rigs/heft-web-rig/profiles/app/config/typescript.json
create mode 100644 rigs/heft-web-rig/profiles/app/tsconfig-base.json
create mode 100644 rigs/heft-web-rig/profiles/app/webpack-base.config.js
create mode 100644 rigs/heft-web-rig/shared/webpack-base.config.js
diff --git a/rigs/heft-web-rig/package.json b/rigs/heft-web-rig/package.json
index ec0c4b6a844..c761e929ad1 100644
--- a/rigs/heft-web-rig/package.json
+++ b/rigs/heft-web-rig/package.json
@@ -16,15 +16,31 @@
"@rushstack/heft": "^0.44.2"
},
"dependencies": {
- "@microsoft/api-extractor": "workspace:*",
- "@rushstack/heft-jest-plugin": "workspace:*",
- "@rushstack/heft-sass-plugin": "workspace:*",
- "@rushstack/heft-webpack4-plugin": "workspace:*",
- "eslint": "~8.7.0",
+ "@microsoft/api-extractor": "^7.19.4",
+ "@rushstack/heft-jest-plugin": "^0.2.2",
+ "@rushstack/heft-sass-plugin": "^0.3.6",
+ "@rushstack/heft-webpack5-plugin": "^0.4.32",
+ "@rushstack/node-core-library": "^3.45.0",
+ "eslint": "~8.8.0",
"jest-environment-jsdom": "~27.4.2",
- "typescript": "~4.5.2"
+ "typescript": "~4.5.5",
+ "autoprefixer": "~10.4.2",
+ "css-loader": "~6.6.0",
+ "css-minimizer-webpack-plugin": "~3.4.1",
+ "html-webpack-plugin": "~5.5.0",
+ "mini-css-extract-plugin": "~2.5.3",
+ "postcss-loader": "~6.2.1",
+ "postcss": "~8.4.6",
+ "sass-loader": "~12.4.0",
+ "sass": "~1.49.7",
+ "source-map-loader": "~3.0.1",
+ "style-loader": "~3.3.1",
+ "terser-webpack-plugin": "~5.3.1",
+ "url-loader": "~4.1.1",
+ "webpack-bundle-analyzer": "~4.5.0",
+ "webpack-merge": "~5.8.0"
},
"devDependencies": {
- "@rushstack/heft": "workspace:*"
+ "@rushstack/heft": "^0.44.2"
}
}
diff --git a/rigs/heft-web-rig/profiles/app/config/heft.json b/rigs/heft-web-rig/profiles/app/config/heft.json
new file mode 100644
index 00000000000..d866bc04980
--- /dev/null
+++ b/rigs/heft-web-rig/profiles/app/config/heft.json
@@ -0,0 +1,156 @@
+/**
+ * Defines configuration used by core Heft.
+ */
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/heft/heft.schema.json",
+
+ /**
+ * Optionally specifies another JSON config file that this file extends from. This provides a way for standard
+ * settings to be shared across multiple projects.
+ */
+ // "extends": "base-project/config/heft.json",
+
+ "eventActions": [
+ // {
+ // /**
+ // * (Required) The kind of built-in operation that should be performed.
+ // * The "deleteGlobs" action deletes files or folders that match the specified glob patterns.
+ // */
+ // "actionKind": "deleteGlobs",
+ //
+ // /**
+ // * (Required) The Heft stage when this action should be performed. Note that heft.json event actions
+ // * are scheduled after any plugin tasks have processed the event. For example, a "compile" event action
+ // * will be performed after the TypeScript compiler has been invoked.
+ // *
+ // * Options: "clean", "pre-compile", "compile", "bundle", "post-build"
+ // */
+ // "heftEvent": "clean",
+ //
+ // /**
+ // * (Required) A user-defined tag whose purpose is to allow configs to replace/delete handlers that
+ // * were added by other configs.
+ // */
+ // "actionId": "my-example-action",
+ //
+ // /**
+ // * (Required) Glob patterns to be deleted. The paths are resolved relative to the project folder.
+ // * Documentation for supported glob syntaxes: https://www.npmjs.com/package/fast-glob
+ // */
+ // "globsToDelete": [
+ // "dist",
+ // "lib",
+ // "lib-esnext",
+ // "temp"
+ // ]
+ // },
+ //
+ // {
+ // /**
+ // * (Required) The kind of built-in operation that should be performed.
+ // * The "copyFiles" action copies files that match the specified patterns.
+ // */
+ // "actionKind": "copyFiles",
+ //
+ // /**
+ // * (Required) The Heft stage when this action should be performed. Note that heft.json event actions
+ // * are scheduled after any plugin tasks have processed the event. For example, a "compile" event action
+ // * will be performed after the TypeScript compiler has been invoked.
+ // *
+ // * Options: "pre-compile", "compile", "bundle", "post-build"
+ // */
+ // "heftEvent": "pre-compile",
+ //
+ // /**
+ // * (Required) A user-defined tag whose purpose is to allow configs to replace/delete handlers that
+ // * were added by other configs.
+ // */
+ // "actionId": "my-example-action",
+ //
+ // /**
+ // * (Required) An array of copy operations to run perform during the specified Heft event.
+ // */
+ // "copyOperations": [
+ // {
+ // /**
+ // * (Required) The base folder that files will be copied from, relative to the project root.
+ // * Settings such as "includeGlobs" and "excludeGlobs" will be resolved relative
+ // * to this folder.
+ // * NOTE: Assigning "sourceFolder" does not by itself select any files to be copied.
+ // */
+ // "sourceFolder": "src",
+ //
+ // /**
+ // * (Required) One or more folders that files will be copied into, relative to the project root.
+ // * If you specify more than one destination folder, Heft will read the input files only once, using
+ // * streams to efficiently write multiple outputs.
+ // */
+ // "destinationFolders": ["dist/assets"],
+ //
+ // /**
+ // * If specified, this option recursively scans all folders under "sourceFolder" and includes any files
+ // * that match the specified extensions. (If "fileExtensions" and "includeGlobs" are both
+ // * specified, their selections are added together.)
+ // */
+ // "fileExtensions": [".jpg", ".png"],
+ //
+ // /**
+ // * A list of glob patterns that select files to be copied. The paths are resolved relative
+ // * to "sourceFolder".
+ // * Documentation for supported glob syntaxes: https://www.npmjs.com/package/fast-glob
+ // */
+ // "includeGlobs": ["assets/*.md"],
+ //
+ // /**
+ // * A list of glob patterns that exclude files/folders from being copied. The paths are resolved relative
+ // * to "sourceFolder". These exclusions eliminate items that were selected by the "includeGlobs"
+ // * or "fileExtensions" setting.
+ // */
+ // "excludeGlobs": [],
+ //
+ // /**
+ // * Normally, when files are selected under a child folder, a corresponding folder will be created in
+ // * the destination folder. Specify flatten=true to discard the source path and copy all matching files
+ // * to the same folder. If two files have the same name an error will be reported.
+ // * The default value is false.
+ // */
+ // "flatten": false,
+ //
+ // /**
+ // * If true, filesystem hard links will be created instead of copying the file. Depending on the
+ // * operating system, this may be faster. (But note that it may cause unexpected behavior if a tool
+ // * modifies the link.) The default value is false.
+ // */
+ // "hardlink": false
+ // }
+ // ]
+ // }
+
+ {
+ "actionKind": "deleteGlobs",
+ "heftEvent": "clean",
+ "actionId": "defaultClean",
+ "globsToDelete": ["dist", "lib", "lib-amd", "lib-commonjs", "lib-es6", "temp"]
+ }
+ ],
+
+ /**
+ * The list of Heft plugins to be loaded.
+ */
+ "heftPlugins": [
+ // {
+ // /**
+ // * The path to the plugin package.
+ // */
+ // "plugin": "path/to/my-plugin",
+ //
+ // /**
+ // * An optional object that provides additional settings that may be defined by the plugin.
+ // */
+ // // "options": { }
+ // }
+ { "plugin": "@rushstack/heft-jest-plugin" },
+ { "plugin": "@rushstack/heft-sass-plugin" },
+ { "plugin": "@rushstack/heft-webpack5-plugin" }
+ ]
+}
diff --git a/rigs/heft-web-rig/profiles/app/config/jest.config.json b/rigs/heft-web-rig/profiles/app/config/jest.config.json
new file mode 100644
index 00000000000..4d01d4f0f55
--- /dev/null
+++ b/rigs/heft-web-rig/profiles/app/config/jest.config.json
@@ -0,0 +1,5 @@
+{
+ "extends": "@rushstack/heft-jest-plugin/includes/jest-shared.config.json",
+
+ "testEnvironment": "jest-environment-jsdom"
+}
diff --git a/rigs/heft-web-rig/profiles/app/config/rush-project.json b/rigs/heft-web-rig/profiles/app/config/rush-project.json
new file mode 100644
index 00000000000..bce265a4f3f
--- /dev/null
+++ b/rigs/heft-web-rig/profiles/app/config/rush-project.json
@@ -0,0 +1,12 @@
+{
+ "operationSettings": [
+ {
+ "operationName": "_phase:build",
+ "outputFolderNames": ["dist", "lib", "lib-commonjs", "temp"]
+ },
+ {
+ "operationName": "build",
+ "outputFolderNames": ["dist", "lib", "lib-commonjs", "temp"]
+ }
+ ]
+}
diff --git a/rigs/heft-web-rig/profiles/app/config/typescript.json b/rigs/heft-web-rig/profiles/app/config/typescript.json
new file mode 100644
index 00000000000..3858cf45631
--- /dev/null
+++ b/rigs/heft-web-rig/profiles/app/config/typescript.json
@@ -0,0 +1,116 @@
+/**
+ * Configures the TypeScript plugin for Heft. This plugin also manages linting.
+ */
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/heft/typescript.schema.json",
+
+ /**
+ * Optionally specifies another JSON config file that this file extends from. This provides a way for standard
+ * settings to be shared across multiple projects.
+ */
+ // "extends": "base-project/config/typescript.json",
+
+ /**
+ * If provided, emit these module kinds in addition to the modules specified in the tsconfig.
+ * Note that this option only applies to the main tsconfig.json configuration.
+ */
+ "additionalModuleKindsToEmit": [
+ // {
+ // /**
+ // * (Required) Must be one of "commonjs", "amd", "umd", "system", "es2015", "esnext"
+ // */
+ // "moduleKind": "amd",
+ //
+ // /**
+ // * (Required) The name of the folder where the output will be written.
+ // */
+ // "outFolderName": "lib-amd"
+ // }
+
+ {
+ "moduleKind": "commonjs",
+ "outFolderName": "lib-commonjs"
+ }
+ ],
+
+ /**
+ * If true, emit CommonJS module output to the folder specified in the tsconfig "outDir" compiler option with the .cjs extension alongside (or instead of, if TSConfig specifies CommonJS) the default compilation output.
+ */
+ // "emitCjsExtensionForCommonJS": true,
+
+ /**
+ * If true, emit ESNext module output to the folder specified in the tsconfig "outDir" compiler option with the .mjs extension alongside (or instead of, if TSConfig specifies ESNext) the default compilation output.
+ */
+ // "emitMjsExtensionForESModule": true,
+
+ /**
+ * Specifies the intermediary folder that tests will use. Because Jest uses the
+ * Node.js runtime to execute tests, the module format must be CommonJS.
+ *
+ * The default value is "lib".
+ */
+ "emitFolderNameForTests": "lib-commonjs",
+
+ /**
+ * If set to "true", the TSlint task will not be invoked.
+ */
+ // "disableTslint": true,
+
+ /**
+ * Set this to change the maximum number of file handles that will be opened concurrently for writing.
+ * The default is 50.
+ */
+ // "maxWriteParallelism": 50,
+
+ /**
+ * Configures additional file types that should be copied into the TypeScript compiler's emit folders, for example
+ * so that these files can be resolved by import statements.
+ */
+ "staticAssetsToCopy": {
+ /**
+ * File extensions that should be copied from the src folder to the destination folder(s).
+ */
+ // "fileExtensions": [
+ // ".json", ".css"
+ // ],
+
+ "fileExtensions": [
+ ".aac",
+ ".css",
+ ".eot",
+ ".gif",
+ ".jpeg",
+ ".jpg",
+ ".json",
+ ".m4a",
+ ".mp3",
+ ".mp4",
+ ".oga",
+ ".otf",
+ ".png",
+ ".scss",
+ ".svg",
+ ".ttf",
+ ".wav",
+ ".webm",
+ ".webp",
+ ".woff",
+ ".woff2"
+ ]
+
+ /**
+ * Glob patterns that should be explicitly included.
+ */
+ // "includeGlobs": [
+ // "some/path/*.js"
+ // ],
+
+ /**
+ * Glob patterns that should be explicitly excluded. This takes precedence over globs listed
+ * in "includeGlobs" and files that match the file extensions provided in "fileExtensions".
+ */
+ // "excludeGlobs": [
+ // "some/path/*.css"
+ // ]
+ }
+}
diff --git a/rigs/heft-web-rig/profiles/app/tsconfig-base.json b/rigs/heft-web-rig/profiles/app/tsconfig-base.json
new file mode 100644
index 00000000000..65b70d13c23
--- /dev/null
+++ b/rigs/heft-web-rig/profiles/app/tsconfig-base.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "http://json.schemastore.org/tsconfig",
+
+ "compilerOptions": {
+ "outDir": "../../../../../lib",
+ "rootDir": "../../../../../src",
+ "rootDirs": ["../../../../../src", "../../../../../temp/sass-ts"],
+
+ "forceConsistentCasingInFileNames": true,
+ "jsx": "react",
+ "declaration": true,
+ "sourceMap": true,
+ "declarationMap": true,
+ "inlineSources": true,
+ "experimentalDecorators": true,
+ "strict": true,
+ "useUnknownInCatchVariables": false,
+ "esModuleInterop": true,
+ "noEmitOnError": false,
+ "allowUnreachableCode": false,
+ "importHelpers": true,
+
+ "types": [],
+
+ "module": "esnext",
+ "moduleResolution": "node",
+ "target": "es5",
+ "lib": ["es5", "scripthost", "es2015.collection", "es2015.promise", "es2015.iterable", "dom"]
+ },
+ "include": ["../../../../../src/**/*.ts", "../../../../../src/**/*.tsx"]
+}
diff --git a/rigs/heft-web-rig/profiles/app/webpack-base.config.js b/rigs/heft-web-rig/profiles/app/webpack-base.config.js
new file mode 100644
index 00000000000..9d9bf8677ea
--- /dev/null
+++ b/rigs/heft-web-rig/profiles/app/webpack-base.config.js
@@ -0,0 +1,33 @@
+'use strict';
+
+const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const createWebpackConfigCommon = require('../../shared/webpack-base.config');
+
+module.exports = function createWebpackConfig({ env, argv, projectRoot, configOverride }) {
+ // Documentation: https://webpack.js.org/configuration/
+ const applicationOverrides = {
+ target: ['web', 'es5'],
+ entry: {
+ app: path.resolve(projectRoot, 'lib', 'start.js')
+ },
+ plugins: [
+ // NOTE: If your project's webpack.config.js provides its own "HtmlWebpackPlugin" configuration,
+ // it will replace the default definition here. This replacement is implemented
+ // using mergeWithCustomize() in shared/webpack-base.config.js
+
+ // See here for documentation: https://github.com/jantimon/html-webpack-plugin
+ new HtmlWebpackPlugin({
+ filename: 'index.html',
+ template: path.resolve(projectRoot, 'assets', 'index.html')
+ })
+ ]
+ };
+
+ return createWebpackConfigCommon({
+ env: env,
+ argv: argv,
+ projectRoot: projectRoot,
+ configOverride: createWebpackConfigCommon.merge(applicationOverrides, configOverride)
+ });
+};
diff --git a/rigs/heft-web-rig/profiles/library/config/api-extractor-task.json b/rigs/heft-web-rig/profiles/library/config/api-extractor-task.json
index 495ebc16533..48d02172207 100644
--- a/rigs/heft-web-rig/profiles/library/config/api-extractor-task.json
+++ b/rigs/heft-web-rig/profiles/library/config/api-extractor-task.json
@@ -7,6 +7,12 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/api-extractor-task.schema.json"
+ /**
+ * Optionally specifies another JSON config file that this file extends from. This provides a way for standard
+ * settings to be shared across multiple projects.
+ */
+ // "extends": "base-project/config/api-extractor-task.json",
+
/**
* If set to true, use the project's TypeScript compiler version for API Extractor's
* analysis. API Extractor's included TypeScript compiler can generally correctly
diff --git a/rigs/heft-web-rig/profiles/library/config/heft.json b/rigs/heft-web-rig/profiles/library/config/heft.json
index c9d54bf73a5..8faa275efcc 100644
--- a/rigs/heft-web-rig/profiles/library/config/heft.json
+++ b/rigs/heft-web-rig/profiles/library/config/heft.json
@@ -4,32 +4,133 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/heft.schema.json",
+ /**
+ * Optionally specifies another JSON config file that this file extends from. This provides a way for standard
+ * settings to be shared across multiple projects.
+ */
+ // "extends": "base-project/config/heft.json",
+
"eventActions": [
+ // {
+ // /**
+ // * (Required) The kind of built-in operation that should be performed.
+ // * The "deleteGlobs" action deletes files or folders that match the specified glob patterns.
+ // */
+ // "actionKind": "deleteGlobs",
+ //
+ // /**
+ // * (Required) The Heft stage when this action should be performed. Note that heft.json event actions
+ // * are scheduled after any plugin tasks have processed the event. For example, a "compile" event action
+ // * will be performed after the TypeScript compiler has been invoked.
+ // *
+ // * Options: "clean", "pre-compile", "compile", "bundle", "post-build"
+ // */
+ // "heftEvent": "clean",
+ //
+ // /**
+ // * (Required) A user-defined tag whose purpose is to allow configs to replace/delete handlers that
+ // * were added by other configs.
+ // */
+ // "actionId": "my-example-action",
+ //
+ // /**
+ // * (Required) Glob patterns to be deleted. The paths are resolved relative to the project folder.
+ // * Documentation for supported glob syntaxes: https://www.npmjs.com/package/fast-glob
+ // */
+ // "globsToDelete": [
+ // "dist",
+ // "lib",
+ // "lib-esnext",
+ // "temp"
+ // ]
+ // },
+ //
+ // {
+ // /**
+ // * (Required) The kind of built-in operation that should be performed.
+ // * The "copyFiles" action copies files that match the specified patterns.
+ // */
+ // "actionKind": "copyFiles",
+ //
+ // /**
+ // * (Required) The Heft stage when this action should be performed. Note that heft.json event actions
+ // * are scheduled after any plugin tasks have processed the event. For example, a "compile" event action
+ // * will be performed after the TypeScript compiler has been invoked.
+ // *
+ // * Options: "pre-compile", "compile", "bundle", "post-build"
+ // */
+ // "heftEvent": "pre-compile",
+ //
+ // /**
+ // * (Required) A user-defined tag whose purpose is to allow configs to replace/delete handlers that
+ // * were added by other configs.
+ // */
+ // "actionId": "my-example-action",
+ //
+ // /**
+ // * (Required) An array of copy operations to run perform during the specified Heft event.
+ // */
+ // "copyOperations": [
+ // {
+ // /**
+ // * (Required) The base folder that files will be copied from, relative to the project root.
+ // * Settings such as "includeGlobs" and "excludeGlobs" will be resolved relative
+ // * to this folder.
+ // * NOTE: Assigning "sourceFolder" does not by itself select any files to be copied.
+ // */
+ // "sourceFolder": "src",
+ //
+ // /**
+ // * (Required) One or more folders that files will be copied into, relative to the project root.
+ // * If you specify more than one destination folder, Heft will read the input files only once, using
+ // * streams to efficiently write multiple outputs.
+ // */
+ // "destinationFolders": ["dist/assets"],
+ //
+ // /**
+ // * If specified, this option recursively scans all folders under "sourceFolder" and includes any files
+ // * that match the specified extensions. (If "fileExtensions" and "includeGlobs" are both
+ // * specified, their selections are added together.)
+ // */
+ // "fileExtensions": [".jpg", ".png"],
+ //
+ // /**
+ // * A list of glob patterns that select files to be copied. The paths are resolved relative
+ // * to "sourceFolder".
+ // * Documentation for supported glob syntaxes: https://www.npmjs.com/package/fast-glob
+ // */
+ // "includeGlobs": ["assets/*.md"],
+ //
+ // /**
+ // * A list of glob patterns that exclude files/folders from being copied. The paths are resolved relative
+ // * to "sourceFolder". These exclusions eliminate items that were selected by the "includeGlobs"
+ // * or "fileExtensions" setting.
+ // */
+ // "excludeGlobs": [],
+ //
+ // /**
+ // * Normally, when files are selected under a child folder, a corresponding folder will be created in
+ // * the destination folder. Specify flatten=true to discard the source path and copy all matching files
+ // * to the same folder. If two files have the same name an error will be reported.
+ // * The default value is false.
+ // */
+ // "flatten": false,
+ //
+ // /**
+ // * If true, filesystem hard links will be created instead of copying the file. Depending on the
+ // * operating system, this may be faster. (But note that it may cause unexpected behavior if a tool
+ // * modifies the link.) The default value is false.
+ // */
+ // "hardlink": false
+ // }
+ // ]
+ // }
+
{
- /**
- * The kind of built-in operation that should be performed.
- * The "deleteGlobs" action deletes files or folders that match the
- * specified glob patterns.
- */
"actionKind": "deleteGlobs",
-
- /**
- * The stage of the Heft run during which this action should occur. Note that actions specified in heft.json
- * occur at the end of the stage of the Heft run.
- */
"heftEvent": "clean",
-
- /**
- * A user-defined tag whose purpose is to allow configs to replace/delete handlers that were added by other
- * configs.
- */
"actionId": "defaultClean",
-
- /**
- * Glob patterns to be deleted. The paths are resolved relative to the project folder.
- * Recommend exactly matching with "projectOutputFolderNames" in rush-project.json.
- */
- "globsToDelete": ["dist", "lib", "lib-commonjs", "temp"]
+ "globsToDelete": ["dist", "lib", "lib-amd", "lib-commonjs", "lib-es6", "temp"]
}
],
@@ -37,22 +138,19 @@
* The list of Heft plugins to be loaded.
*/
"heftPlugins": [
- {
- /**
- * The path to the plugin package.
- */
- "plugin": "@rushstack/heft-webpack4-plugin"
-
- /**
- * An optional object that provides additional settings that may be defined by the plugin.
- */
- // "options": { }
- },
- {
- "plugin": "@rushstack/heft-jest-plugin"
- },
- {
- "plugin": "@rushstack/heft-sass-plugin"
- }
+ // {
+ // /**
+ // * The path to the plugin package.
+ // */
+ // "plugin": "path/to/my-plugin",
+ //
+ // /**
+ // * An optional object that provides additional settings that may be defined by the plugin.
+ // */
+ // // "options": { }
+ // }
+ { "plugin": "@rushstack/heft-jest-plugin" },
+ { "plugin": "@rushstack/heft-sass-plugin" }
+ // { "plugin": "@rushstack/heft-webpack5-plugin" }
]
}
diff --git a/rigs/heft-web-rig/profiles/library/config/typescript.json b/rigs/heft-web-rig/profiles/library/config/typescript.json
index dc1cefb919f..3858cf45631 100644
--- a/rigs/heft-web-rig/profiles/library/config/typescript.json
+++ b/rigs/heft-web-rig/profiles/library/config/typescript.json
@@ -4,24 +4,45 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/typescript.schema.json",
+ /**
+ * Optionally specifies another JSON config file that this file extends from. This provides a way for standard
+ * settings to be shared across multiple projects.
+ */
+ // "extends": "base-project/config/typescript.json",
+
/**
* If provided, emit these module kinds in addition to the modules specified in the tsconfig.
* Note that this option only applies to the main tsconfig.json configuration.
*/
"additionalModuleKindsToEmit": [
+ // {
+ // /**
+ // * (Required) Must be one of "commonjs", "amd", "umd", "system", "es2015", "esnext"
+ // */
+ // "moduleKind": "amd",
+ //
+ // /**
+ // * (Required) The name of the folder where the output will be written.
+ // */
+ // "outFolderName": "lib-amd"
+ // }
+
{
- /**
- * (Required) Must be one of "commonjs", "amd", "umd", "system", "es2015", "esnext"
- */
"moduleKind": "commonjs",
-
- /**
- * (Required) The name of the folder where the output will be written.
- */
"outFolderName": "lib-commonjs"
}
],
+ /**
+ * If true, emit CommonJS module output to the folder specified in the tsconfig "outDir" compiler option with the .cjs extension alongside (or instead of, if TSConfig specifies CommonJS) the default compilation output.
+ */
+ // "emitCjsExtensionForCommonJS": true,
+
+ /**
+ * If true, emit ESNext module output to the folder specified in the tsconfig "outDir" compiler option with the .mjs extension alongside (or instead of, if TSConfig specifies ESNext) the default compilation output.
+ */
+ // "emitMjsExtensionForESModule": true,
+
/**
* Specifies the intermediary folder that tests will use. Because Jest uses the
* Node.js runtime to execute tests, the module format must be CommonJS.
@@ -42,13 +63,40 @@
// "maxWriteParallelism": 50,
/**
- * Describes the way files should be statically coped from src to TS output folders
+ * Configures additional file types that should be copied into the TypeScript compiler's emit folders, for example
+ * so that these files can be resolved by import statements.
*/
"staticAssetsToCopy": {
/**
* File extensions that should be copied from the src folder to the destination folder(s).
*/
- "fileExtensions": [".json"]
+ // "fileExtensions": [
+ // ".json", ".css"
+ // ],
+
+ "fileExtensions": [
+ ".aac",
+ ".css",
+ ".eot",
+ ".gif",
+ ".jpeg",
+ ".jpg",
+ ".json",
+ ".m4a",
+ ".mp3",
+ ".mp4",
+ ".oga",
+ ".otf",
+ ".png",
+ ".scss",
+ ".svg",
+ ".ttf",
+ ".wav",
+ ".webm",
+ ".webp",
+ ".woff",
+ ".woff2"
+ ]
/**
* Glob patterns that should be explicitly included.
diff --git a/rigs/heft-web-rig/profiles/library/tsconfig-base.json b/rigs/heft-web-rig/profiles/library/tsconfig-base.json
index 8c4d48b65b4..65b70d13c23 100644
--- a/rigs/heft-web-rig/profiles/library/tsconfig-base.json
+++ b/rigs/heft-web-rig/profiles/library/tsconfig-base.json
@@ -14,9 +14,11 @@
"inlineSources": true,
"experimentalDecorators": true,
"strict": true,
+ "useUnknownInCatchVariables": false,
"esModuleInterop": true,
"noEmitOnError": false,
"allowUnreachableCode": false,
+ "importHelpers": true,
"types": [],
diff --git a/rigs/heft-web-rig/shared/webpack-base.config.js b/rigs/heft-web-rig/shared/webpack-base.config.js
new file mode 100644
index 00000000000..77f38b557b6
--- /dev/null
+++ b/rigs/heft-web-rig/shared/webpack-base.config.js
@@ -0,0 +1,270 @@
+'use strict';
+
+// Import the Webpack instance installed by heft-webpack5-plugin
+const nodeCoreLibrary = require('@rushstack/node-core-library');
+const webpack = require(nodeCoreLibrary.Import.resolveModule({
+ modulePath: 'webpack',
+ baseFolderPath: nodeCoreLibrary.Import.resolvePackage({
+ packageName: '@rushstack/heft-webpack5-plugin',
+ baseFolderPath: __dirname
+ })
+}));
+
+const path = require('path');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const { DefinePlugin } = webpack;
+const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
+const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
+const { merge, mergeWithCustomize, mergeWithRules, unique } = require('webpack-merge');
+const sass = require('sass');
+const autoprefixer = require('autoprefixer');
+
+/**
+ * If the "--production" command-line parameter is specified when invoking Heft, then the
+ * "production" function parameter will be true. You can use this to enable bundling optimizations.
+ */
+function createWebpackConfig({ env, argv, projectRoot, configOverride }) {
+ const { production } = env;
+
+ const defaultArgs = {
+ // Documentation: https://webpack.js.org/configuration/mode/
+ mode: production ? 'production' : 'development',
+ resolve: {
+ extensions: ['.js', '.json']
+ },
+ output: production
+ ? {
+ chunkFilename: '[name].[contenthash].js',
+ filename: '[name].[contenthash].js',
+ sourceMapFilename: '[name].[contenthash].js.map'
+ }
+ : {},
+ module: {
+ rules: [
+ {
+ // The source-map-loader extracts existing source maps from all JavaScript entries. This includes both
+ // inline source maps as well as those linked via URL. All source map data is passed to Webpack for
+ // processing as per a chosen source map style specified by the devtool option in webpack.config.js.
+ // https://www.npmjs.com/package/source-map-loader
+ test: /\.js$/,
+ include: [path.resolve(projectRoot, 'lib')],
+ enforce: 'pre',
+ use: [
+ {
+ loader: require.resolve('source-map-loader')
+ }
+ ]
+ },
+
+ {
+ // Recommendation for CSS styles:
+ //
+ // We recommend the newer .scss file format because its syntax is a proper superset of familiar CSS.
+ // The older .sass syntax is accepted for backwards compatibility.
+ //
+ // Handling of formats:
+ // - *.scss: sass, autoprefixer, modules <--- recommended
+ // - *.global.scss: sass, autoprefixer, NO modules
+ // - *.css: NO sass, NO autoprefixer, NO modules
+ //
+ // If someone wants CSS with modules, they can simply use the .sass file extension, since SASS
+ // is essentially a superset of CSS. (There's a small performance penalty for applying SASS to
+ // a plain CSS file, but the extra syntax validation probably justifies that cost.)
+ //
+ // The SASS docs are here: https://sass-lang.com/documentation/syntax
+ test: /\.(scss|sass|css)$/,
+ exclude: /node_modules/,
+ use: [
+ // "For production builds it's recommended to extract the CSS from your bundle being able to
+ // use parallel loading of CSS/JS resources later on. This can be achieved by using the
+ // mini-css-extract-plugin, because it creates separate css files."
+ //
+ // "For development mode (including webpack-dev-server) you can use style-loader, because it injects
+ // CSS into the DOM using multiple and works faster."
+ //
+ // "WARNING: Do not use style-loader and mini-css-extract-plugin together."
+ production
+ ? {
+ loader: MiniCssExtractPlugin.loader
+ }
+ : {
+ // Generates JavaScript code that injects CSS styles into the DOM at runtime.
+ // The default configuration creates