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