diff --git a/index.js b/index.js index 0344c367..3af837b8 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,14 @@ * @import webpack from 'webpack' */ +/** + * @import { OptionsCallback } from './lib/utils/apply-options-callback.js' + */ + +/** + * @typedef {{from: string, pattern?: RegExp|string, to?: string|null, includeSubdirectories?: boolean, context?: string}} CopyFilesOptions + */ + const EncoreProxy = require('./lib/EncoreProxy'); const WebpackConfig = require('./lib/WebpackConfig'); const configGenerator = require('./lib/config-generator'); @@ -117,7 +125,7 @@ class Encore { * }) * ``` * - * @param {Function} definePluginOptionsCallback + * @param {OptionsCallback[0]>} definePluginOptionsCallback * @returns {Encore} */ configureDefinePlugin(definePluginOptionsCallback = () => {}) { @@ -138,7 +146,7 @@ class Encore { * }) * ``` * - * @param {Function} friendlyErrorsPluginOptionsCallback + * @param {OptionsCallback} friendlyErrorsPluginOptionsCallback * @returns {Encore} */ configureFriendlyErrorsPlugin(friendlyErrorsPluginOptionsCallback = () => {}) { @@ -159,7 +167,7 @@ class Encore { * }) * ``` * - * @param {Function} manifestPluginOptionsCallback + * @param {OptionsCallback} manifestPluginOptionsCallback * @returns {Encore} */ configureManifestPlugin(manifestPluginOptionsCallback = () => {}) { @@ -185,7 +193,7 @@ class Encore { * }) * ``` * - * @param {Function} terserPluginOptionsCallback + * @param {OptionsCallback>} terserPluginOptionsCallback * @returns {Encore} */ configureTerserPlugin(terserPluginOptionsCallback = () => {}) { @@ -206,7 +214,7 @@ class Encore { * }) * ``` * - * @param {Function} cssMinimizerPluginOptionsCallback + * @param {OptionsCallback>} cssMinimizerPluginOptionsCallback * @returns {Encore} */ configureCssMinimizerPlugin(cssMinimizerPluginOptionsCallback = () => {}) { @@ -226,10 +234,10 @@ class Encore { * If the JavaScript file imports/requires CSS/Sass/LESS files, * then a CSS file (e.g. main.css) will also be output. * - * @param {string} name The name (without extension) that will be used - * as the output filename (e.g. app will become app.js) - * in the output directory. - * @param {string|Array} src The path to the source file (or files) + * @param {string} name The name (without extension) that will be used + * as the output filename (e.g. app will become app.js) + * in the output directory. + * @param {string|string[]} src The path to the source file (or files) * @returns {Encore} */ addEntry(name, src) { @@ -252,7 +260,7 @@ class Encore { * If the JavaScript files imports/requires CSS/Sass/LESS files, * then a CSS file (e.g. main.css) will also be output. * - * @param {Record} entries where the Keys are the + * @param {Record} entries where the Keys are the * names (without extension) that will be used * as the output filename (e.g. app will become app.js) * in the output directory. The values are the path(s) @@ -278,10 +286,10 @@ class Encore { * is to use addEntry() and then require/import your CSS files from * within your JavaScript files. * - * @param {string} name The name (without extension) that will be used - * as the output filename (e.g. app will become app.css) - * in the output directory. - * @param {string|Array} src The path to the source file (or files) + * @param {string} name The name (without extension) that will be used + * as the output filename (e.g. app will become app.css) + * in the output directory. + * @param {string|string[]} src The path to the source file (or files) * @returns {Encore} */ addStyleEntry(name, src) { @@ -326,7 +334,7 @@ class Encore { * Encore.addPlugin(new MyWebpackPlugin(), PluginPriorities.DefinePlugin); * ``` * - * @param {object} plugin + * @param {webpack.WebpackPluginInstance} plugin * @param {number} priority * @returns {Encore} */ @@ -339,7 +347,7 @@ class Encore { /** * Adds a custom loader config * - * @param {object} loader The loader config object + * @param {webpack.RuleSetRule} loader The loader config object * @returns {Encore} */ addLoader(loader) { @@ -351,7 +359,7 @@ class Encore { /** * Alias to addLoader * - * @param {object} rule + * @param {webpack.RuleSetRule} rule * @returns {Encore} */ addRule(rule) { @@ -414,7 +422,7 @@ class Encore { * ]); * ``` * - * @param {*} externals + * @param {webpack.Externals} externals * @returns {Encore} */ addExternals(externals) { @@ -584,7 +592,7 @@ class Encore { * - {string} context (default: path of the source directory) * The context to use as a root path when copying files. * - * @param {object|Array} configs + * @param {CopyFilesOptions|CopyFilesOptions[]} configs * @returns {Encore} */ copyFiles(configs) { @@ -669,7 +677,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ configureSplitChunks(callback) { @@ -691,7 +699,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback>} callback * @returns {Encore} */ configureWatchOptions(callback) { @@ -718,7 +726,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ configureDevServerOptions(callback) { @@ -794,7 +802,7 @@ class Encore { * }) * ``` * - * @param {Function} postCssLoaderOptionsCallback + * @param {OptionsCallback} postCssLoaderOptionsCallback * @returns {Encore} */ enablePostCssLoader(postCssLoaderOptionsCallback = () => {}) { @@ -834,8 +842,8 @@ class Encore { * Options parameters for resolve-url-loader * // https://www.npmjs.com/package/resolve-url-loader#options * - * @param {Function} sassLoaderOptionsCallback - * @param {object} encoreOptions + * @param {OptionsCallback} sassLoaderOptionsCallback + * @param {{resolveUrlLoader?: boolean, resolveUrlLoaderOptions?: object}} encoreOptions * @returns {Encore} */ enableSassLoader(sassLoaderOptionsCallback = () => {}, encoreOptions = {}) { @@ -861,7 +869,7 @@ class Encore { * }); * ``` * - * @param {Function} lessLoaderOptionsCallback + * @param {OptionsCallback} lessLoaderOptionsCallback * @returns {Encore} */ enableLessLoader(lessLoaderOptionsCallback = () => {}) { @@ -886,7 +894,7 @@ class Encore { * }); * ``` * - * @param {Function} stylusLoaderOptionsCallback + * @param {OptionsCallback} stylusLoaderOptionsCallback * @returns {Encore} */ enableStylusLoader(stylusLoaderOptionsCallback = () => {}) { @@ -931,7 +939,7 @@ class Encore { * ``` * * Supported options: - * - {Condition} exclude (default=/(node_modules|bower_components)/) + * - {webpack.RuleSetCondition} exclude (default=/(node_modules|bower_components)/) * A Webpack Condition passed to the JS/JSX rule that * determines which files and folders should not be * processed by Babel (https://webpack.js.org/configuration/module/#condition). @@ -966,8 +974,8 @@ class Encore { * It should contain the version of core-js you added to your project * if useBuiltIns isn't set to false. * - * @param {Function|null} callback - * @param {object} encoreOptions + * @param {OptionsCallback|null} callback + * @param {{exclude?: webpack.RuleSetCondition, includeNodeModules?: string[], useBuiltIns?: 'usage' | 'entry' | false, corejs?: number|string|{ version: string, proposals: boolean }|null}} encoreOptions * @returns {Encore} */ configureBabel(callback, encoreOptions = {}) { @@ -992,7 +1000,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ configureBabelPresetEnv(callback) { @@ -1013,7 +1021,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ configureCssLoader(callback) { @@ -1055,8 +1063,8 @@ class Encore { * }); * ``` * - * @param {object} buildDependencies - * @param {Function} cacheCallback + * @param {Record} buildDependencies + * @param {OptionsCallback} cacheCallback * @returns {Encore} */ enableBuildCache(buildDependencies, cacheCallback = (cache) => {}) { @@ -1083,8 +1091,8 @@ class Encore { * ); * ``` * - * @param {Function} loaderOptionsCallback - * @param {Function} pluginOptionsCallback + * @param {OptionsCallback} loaderOptionsCallback + * @param {OptionsCallback} pluginOptionsCallback * @returns {Encore} */ configureMiniCssExtractPlugin(loaderOptionsCallback, pluginOptionsCallback = () => {}) { @@ -1121,7 +1129,7 @@ class Encore { * Encore.enablePreactPreset({ preactCompat: true }) * ``` * - * @param {object} options + * @param {{preactCompat?: boolean}} options * @returns {Encore} */ enablePreactPreset(options = {}) { @@ -1149,7 +1157,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ enableTypeScriptLoader(callback = () => {}) { @@ -1164,7 +1172,7 @@ class Encore { * * This is a build optimization API to reduce build times. * - * @param {Function} forkedTypeScriptTypesCheckOptionsCallback + * @param {OptionsCallback} forkedTypeScriptTypesCheckOptionsCallback * @returns {Encore} */ enableForkedTypeScriptTypesChecking(forkedTypeScriptTypesCheckOptionsCallback = () => {}) { @@ -1252,8 +1260,8 @@ class Encore { * Configure Babel to use the preset "@vue/babel-preset-jsx", * in order to enable JSX usage in Vue components. * - * @param {Function} vueLoaderOptionsCallback - * @param {object} encoreOptions + * @param {OptionsCallback} vueLoaderOptionsCallback + * @param {{useJsx?: boolean, version?: number, runtimeCompilerBuild?: boolean}} encoreOptions * @returns {Encore} */ enableVueLoader(vueLoaderOptionsCallback = () => {}, encoreOptions = {}) { @@ -1279,7 +1287,7 @@ class Encore { * ``` * * @param {boolean} enabled - * @param {Function} notifierPluginOptionsCallback + * @param {OptionsCallback} notifierPluginOptionsCallback * @returns {Encore} */ enableBuildNotifications(enabled = true, notifierPluginOptionsCallback = () => {}) { @@ -1304,7 +1312,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ enableHandlebarsLoader(callback = () => {}) { @@ -1351,7 +1359,7 @@ class Encore { * }); * ``` * - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ configureStyleLoader(callback) { @@ -1383,7 +1391,7 @@ class Encore { * which is overridden for both fonts and images. See configureImageRule() * and configureFontRule() to control those filenames. * - * @param {object} filenames + * @param {{js?: string, css?: string, images?: string, fonts?: string}} filenames * @returns {Encore} */ configureFilenames(filenames) { @@ -1437,8 +1445,8 @@ class Encore { * }); * ``` * - * @param {object} options - * @param {string|object|Function} ruleCallback + * @param {{filename?: string, maxSize?: number|null, type?: string, enabled?: boolean}} options + * @param {OptionsCallback} ruleCallback * @returns {Encore} */ configureImageRule(options = {}, ruleCallback = (rule) => {}) { @@ -1454,8 +1462,8 @@ class Encore { * * See configureImageRule() for more details. * - * @param {object} options - * @param {string|object|Function} ruleCallback + * @param {{filename?: string, maxSize?: number|null, type?: string, enabled?: boolean}} options + * @param {OptionsCallback} ruleCallback * @returns {Encore} */ configureFontRule(options = {}, ruleCallback = (rule) => {}) { @@ -1479,7 +1487,7 @@ class Encore { * ``` * * @param {string} name - * @param {Function} callback + * @param {OptionsCallback} callback * @returns {Encore} */ configureLoaderRule(name, callback) { @@ -1501,7 +1509,7 @@ class Encore { * }) * ``` * - * @param {Function} cleanOptionsCallback + * @param {OptionsCallback[0], undefined>>} cleanOptionsCallback * @returns {Encore} */ cleanupOutputBeforeBuild(cleanOptionsCallback = () => {}) { @@ -1539,7 +1547,7 @@ class Encore { * ``` * * @param {boolean} enabled - * @param {string|Array} algorithms + * @param {string|string[]} algorithms * @returns {Encore} */ enableIntegrityHashes(enabled = true, algorithms = ['sha384']) { @@ -1647,7 +1655,7 @@ class Encore { * ) * ``` * - * Be aware than using this method will also reset the current + * Be aware that using this method will also reset the current * webpack configuration. * * @param {string} environment @@ -1672,7 +1680,7 @@ class Encore { /** * Check if Encore was either called through - * the CLI utility or after being manually intialized + * the CLI utility or after being manually initialized * using Encore.configureRuntimeEnvironment. * * @returns {boolean} @@ -1684,7 +1692,7 @@ class Encore { /** * Clear the runtime environment. * - * Be aware than using this method will also reset the + * Be aware that using this method will also reset the * current webpack configuration. * * @returns {void} diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index 63bf5f9c..f1bcd244 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -13,6 +13,18 @@ * @import RuntimeConfig from './config/RuntimeConfig' */ +/** + * @import webpack from 'webpack' + */ + +/** + * @import { OptionsCallback } from './utils/apply-options-callback.js' + */ + +/** + * @import { CopyFilesOptions } from '../index.js' + */ + const path = require('path'); const fs = require('fs'); const crypto = require('crypto'); @@ -72,12 +84,14 @@ class WebpackConfig { this.cleanupOutput = false; this.usePersistentCache = false; this.extractCss = true; + /** @type {{filename: string, maxSize: number|null, type: string, enabled: boolean}} */ this.imageRuleOptions = { type: 'asset/resource', maxSize: null, filename: 'images/[name].[hash:8][ext]', enabled: true, }; + /** @type {{filename: string, maxSize: number|null, type: string, enabled: boolean}} */ this.fontRuleOptions = { type: 'asset/resource', maxSize: null, @@ -101,6 +115,9 @@ class WebpackConfig { // Features/Loaders options this.copyFilesConfigs = []; + /** + * @type {{resolveUrlLoader: boolean, resolveUrlLoaderOptions: object}} + */ this.sassOptions = { resolveUrlLoader: true, resolveUrlLoaderOptions: {} @@ -108,6 +125,7 @@ class WebpackConfig { this.preactOptions = { preactCompat: false }; + /** @type {{exclude: webpack.RuleSetCondition, useBuiltIns: 'usage'|'entry'|false, corejs: number|string|{ version: string, proposals: boolean }|null}} */ this.babelOptions = { exclude: /(node_modules|bower_components)/, useBuiltIns: false, @@ -119,27 +137,47 @@ class WebpackConfig { version: null, runtimeCompilerBuild: null }; + /** @type {Record} */ this.persistentCacheBuildDependencies = {}; // Features/Loaders options callbacks + /** @type {OptionsCallback} */ this.imageRuleCallback = () => {}; + /** @type {OptionsCallback} */ this.fontRuleCallback = () => {}; + /** @type {OptionsCallback} */ this.postCssLoaderOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.sassLoaderOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.lessLoaderOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.stylusLoaderOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.babelConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.babelPresetEnvOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.cssLoaderConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.styleLoaderConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.splitChunksConfigurationCallback = () => {}; + /** @type {OptionsCallback>} */ this.watchOptionsConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.devServerOptionsConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.vueLoaderOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.tsConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.handlebarsConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.miniCssExtractLoaderConfigurationCallback = () => {}; + /** @type {OptionsCallback} */ this.miniCssExtractPluginConfigurationCallback = () => {}; + /** @type {Record>} */ this.loaderConfigurationCallbacks = { javascript: () => {}, css: () => {}, @@ -155,14 +193,23 @@ class WebpackConfig { }; // Plugins callbacks + /** @type {OptionsCallback[0], undefined>>} */ this.cleanOptionsCallback = () => {}; + /** @type {OptionsCallback[0]>} */ this.definePluginOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.forkedTypeScriptTypesCheckOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.friendlyErrorsPluginOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.manifestPluginOptionsCallback = () => {}; + /** @type {OptionsCallback>} */ this.terserPluginOptionsCallback = () => {}; + /** @type {OptionsCallback>} */ this.cssMinimizerPluginOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.notifierPluginOptionsCallback = () => {}; + /** @type {OptionsCallback} */ this.persistentCacheCallback = () => {}; } @@ -242,6 +289,9 @@ class WebpackConfig { this.manifestKeyPrefix = manifestKeyPrefix; } + /** + * @param {OptionsCallback[0]>} definePluginOptionsCallback + */ configureDefinePlugin(definePluginOptionsCallback = () => {}) { if (typeof definePluginOptionsCallback !== 'function') { throw new Error('Argument 1 to configureDefinePlugin() must be a callback function'); @@ -250,6 +300,9 @@ class WebpackConfig { this.definePluginOptionsCallback = definePluginOptionsCallback; } + /** + * @param {OptionsCallback} friendlyErrorsPluginOptionsCallback + */ configureFriendlyErrorsPlugin(friendlyErrorsPluginOptionsCallback = () => {}) { if (typeof friendlyErrorsPluginOptionsCallback !== 'function') { throw new Error('Argument 1 to configureFriendlyErrorsPlugin() must be a callback function'); @@ -258,6 +311,9 @@ class WebpackConfig { this.friendlyErrorsPluginOptionsCallback = friendlyErrorsPluginOptionsCallback; } + /** + * @param {OptionsCallback} manifestPluginOptionsCallback + */ configureManifestPlugin(manifestPluginOptionsCallback = () => {}) { if (typeof manifestPluginOptionsCallback !== 'function') { throw new Error('Argument 1 to configureManifestPlugin() must be a callback function'); @@ -266,6 +322,9 @@ class WebpackConfig { this.manifestPluginOptionsCallback = manifestPluginOptionsCallback; } + /** + * @param {OptionsCallback>} terserPluginOptionsCallback + */ configureTerserPlugin(terserPluginOptionsCallback = () => {}) { if (typeof terserPluginOptionsCallback !== 'function') { throw new Error('Argument 1 to configureTerserPlugin() must be a callback function'); @@ -274,6 +333,9 @@ class WebpackConfig { this.terserPluginOptionsCallback = terserPluginOptionsCallback; } + /** + * @param {OptionsCallback>} cssMinimizerPluginOptionsCallback + */ configureCssMinimizerPlugin(cssMinimizerPluginOptionsCallback = () => {}) { if (typeof cssMinimizerPluginOptionsCallback !== 'function') { throw new Error('Argument 1 to configureCssMinimizerPlugin() must be a callback function'); @@ -356,6 +418,9 @@ class WebpackConfig { Object.assign(this.aliases, aliases); } + /** + * @param {webpack.Externals} externals + */ addExternals(externals = []) { if (!Array.isArray(externals)) { externals = [externals]; @@ -372,6 +437,10 @@ class WebpackConfig { this.useSourceMaps = enabled; } + /** + * @param {OptionsCallback|null} callback + * @param {{exclude?: webpack.RuleSetCondition, includeNodeModules?: string[], useBuiltIns?: 'usage' | 'entry' | false, corejs?: number|string|{ version: string, proposals: boolean }|null}} options + */ configureBabel(callback, options = {}) { if (callback) { if (typeof callback !== 'function') { @@ -433,6 +502,9 @@ class WebpackConfig { } } + /** + * @param {OptionsCallback} callback + */ configureBabelPresetEnv(callback) { if (typeof callback !== 'function') { throw new Error('Argument 1 to configureBabelPresetEnv() must be a callback function.'); @@ -445,6 +517,9 @@ class WebpackConfig { this.babelPresetEnvOptionsCallback = callback; } + /** + * @param {OptionsCallback} callback + */ configureCssLoader(callback) { if (typeof callback !== 'function') { throw new Error('Argument 1 to configureCssLoader() must be a callback function.'); @@ -453,6 +528,9 @@ class WebpackConfig { this.cssLoaderConfigurationCallback = callback; } + /** + * @param {OptionsCallback} callback + */ configureStyleLoader(callback) { if (typeof callback !== 'function') { throw new Error('Argument 1 to configureStyleLoader() must be a callback function.'); @@ -461,6 +539,10 @@ class WebpackConfig { this.styleLoaderConfigurationCallback = callback; } + /** + * @param {OptionsCallback} loaderOptionsCallback + * @param {OptionsCallback} pluginOptionsCallback + */ configureMiniCssExtractPlugin(loaderOptionsCallback, pluginOptionsCallback = () => {}) { if (typeof loaderOptionsCallback !== 'function') { throw new Error('Argument 1 to configureMiniCssExtractPluginLoader() must be a callback function.'); @@ -486,6 +568,9 @@ class WebpackConfig { this.shouldSplitEntryChunks = true; } + /** + * @param {OptionsCallback} callback + */ configureSplitChunks(callback) { if (typeof callback !== 'function') { throw new Error('Argument 1 to configureSplitChunks() must be a callback function.'); @@ -494,6 +579,9 @@ class WebpackConfig { this.splitChunksConfigurationCallback = callback; } + /** + * @param {OptionsCallback>} callback + */ configureWatchOptions(callback) { if (typeof callback !== 'function') { throw new Error('Argument 1 to configureWatchOptions() must be a callback function.'); @@ -502,6 +590,9 @@ class WebpackConfig { this.watchOptionsConfigurationCallback = callback; } + /** + * @param {OptionsCallback} callback + */ configureDevServerOptions(callback) { if (typeof callback !== 'function') { throw new Error('Argument 1 to configureDevServerOptions() must be a callback function.'); @@ -510,6 +601,10 @@ class WebpackConfig { this.devServerOptionsConfigurationCallback = callback; } + /** + * @param {string} name + * @param {object} options + */ addCacheGroup(name, options) { if (typeof name !== 'string') { throw new Error('Argument 1 to addCacheGroup() must be a string.'); @@ -540,6 +635,9 @@ class WebpackConfig { this.cacheGroups[name] = options; } + /** + * @param {CopyFilesOptions|CopyFilesOptions[]} configs + */ copyFiles(configs = []) { if (!Array.isArray(configs)) { configs = [configs]; @@ -588,6 +686,9 @@ class WebpackConfig { } } + /** + * @param {OptionsCallback} postCssLoaderOptionsCallback + */ enablePostCssLoader(postCssLoaderOptionsCallback = () => {}) { this.usePostCssLoader = true; @@ -598,6 +699,10 @@ class WebpackConfig { this.postCssLoaderOptionsCallback = postCssLoaderOptionsCallback; } + /** + * @param {OptionsCallback} sassLoaderOptionsCallback + * @param {{resolveUrlLoader?: boolean, resolveUrlLoaderOptions?: object}} options + */ enableSassLoader(sassLoaderOptionsCallback = () => {}, options = {}) { this.useSassLoader = true; @@ -616,6 +721,9 @@ class WebpackConfig { } } + /** + * @param {OptionsCallback} lessLoaderOptionsCallback + */ enableLessLoader(lessLoaderOptionsCallback = () => {}) { this.useLessLoader = true; @@ -626,6 +734,9 @@ class WebpackConfig { this.lessLoaderOptionsCallback = lessLoaderOptionsCallback; } + /** + * @param {OptionsCallback} stylusLoaderOptionsCallback + */ enableStylusLoader(stylusLoaderOptionsCallback = () => {}) { this.useStylusLoader = true; @@ -656,6 +767,10 @@ class WebpackConfig { }); } + /** + * @param {Record} buildDependencies + * @param {OptionsCallback} callback + */ enableBuildCache(buildDependencies, callback = (cache) => {}) { if (typeof buildDependencies !== 'object') { throw new Error('Argument 1 to enableBuildCache() must be an object.'); @@ -695,6 +810,9 @@ class WebpackConfig { this.useSvelte = true; } + /** + * @param {OptionsCallback} callback + */ enableTypeScriptLoader(callback = () => {}) { if (this.useBabelTypeScriptPreset) { throw new Error('Encore.enableTypeScriptLoader() can not be called when Encore.enableBabelTypeScriptPreset() has been called.'); @@ -709,6 +827,9 @@ class WebpackConfig { this.tsConfigurationCallback = callback; } + /** + * @param {OptionsCallback} forkedTypeScriptTypesCheckOptionsCallback + */ enableForkedTypeScriptTypesChecking(forkedTypeScriptTypesCheckOptionsCallback = () => {}) { if (this.useBabelTypeScriptPreset) { throw new Error('Encore.enableForkedTypeScriptTypesChecking() can not be called when Encore.enableBabelTypeScriptPreset() has been called.'); @@ -736,6 +857,10 @@ class WebpackConfig { this.babelTypeScriptPresetOptions = options; } + /** + * @param {OptionsCallback} vueLoaderOptionsCallback + * @param {object} vueOptions + */ enableVueLoader(vueLoaderOptionsCallback = () => {}, vueOptions = {}) { this.useVueLoader = true; @@ -762,6 +887,10 @@ class WebpackConfig { } } + /** + * @param {boolean} enabled + * @param {OptionsCallback} notifierPluginOptionsCallback + */ enableBuildNotifications(enabled = true, notifierPluginOptionsCallback = () => {}) { if (typeof notifierPluginOptionsCallback !== 'function') { throw new Error('Argument 2 to enableBuildNotifications() must be a callback function.'); @@ -771,6 +900,9 @@ class WebpackConfig { this.notifierPluginOptionsCallback = notifierPluginOptionsCallback; } + /** + * @param {OptionsCallback} callback + */ enableHandlebarsLoader(callback = () => {}) { this.useHandlebarsLoader = true; @@ -801,6 +933,10 @@ class WebpackConfig { this.configuredFilenames = configuredFilenames; } + /** + * @param {{filename?: string, maxSize?: number|null, type?: string, enabled?: boolean}} options + * @param {OptionsCallback} ruleCallback + */ configureImageRule(options = {}, ruleCallback = () => {}) { for (const optionKey of Object.keys(options)) { if (!(optionKey in this.imageRuleOptions)) { @@ -821,6 +957,10 @@ class WebpackConfig { this.imageRuleCallback = ruleCallback; } + /** + * @param {{filename?: string, maxSize?: number|null, type?: string, enabled?: boolean}} options + * @param {OptionsCallback} ruleCallback + */ configureFontRule(options = {}, ruleCallback = () => {}) { for (const optionKey of Object.keys(options)) { if (!(optionKey in this.fontRuleOptions)) { @@ -841,6 +981,9 @@ class WebpackConfig { this.fontRuleCallback = ruleCallback; } + /** + * @param {OptionsCallback[0], undefined>>} cleanOptionsCallback + */ cleanupOutputBeforeBuild(cleanOptionsCallback = () => {}) { if (typeof cleanOptionsCallback !== 'function') { throw new Error('Argument 1 to cleanupOutputBeforeBuild() must be a callback function'); @@ -872,6 +1015,10 @@ class WebpackConfig { }); } + /** + * @param {string} name + * @param {OptionsCallback} callback + */ configureLoaderRule(name, callback) { logger.warning('Be careful when using Encore.configureLoaderRule(), this is a low-level method that can potentially break Encore and Webpack when not used carefully.'); @@ -897,6 +1044,10 @@ class WebpackConfig { this.loaderConfigurationCallbacks[name] = callback; } + /** + * @param {boolean} enabled + * @param {string|string[]} algorithms + */ enableIntegrityHashes(enabled = true, algorithms = ['sha384']) { if (!Array.isArray(algorithms)) { algorithms = [algorithms]; diff --git a/lib/config-generator.js b/lib/config-generator.js index 31fd4c5f..c202cfc2 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -260,7 +260,7 @@ class ConfigGenerator { } /** - * @returns {import('webpack').CleanOptions|boolean} + * @returns {ConstructorParameters[0]|boolean} */ buildCleanConfig() { if (!this.webpackConfig.cleanupOutput) { diff --git a/lib/utils/apply-options-callback.js b/lib/utils/apply-options-callback.js index cf1f11ba..c9eb0096 100644 --- a/lib/utils/apply-options-callback.js +++ b/lib/utils/apply-options-callback.js @@ -7,8 +7,19 @@ * file that was distributed with this source code. */ +/** + * @typedef {function(this: T, T): T|void} OptionsCallback + * @template {object} T + */ + 'use strict'; +/** + * @template {object} T + * @param {OptionsCallback} optionsCallback + * @param {T} options + * @returns {T} + */ module.exports = function(optionsCallback, options) { const result = optionsCallback.call(options, options); diff --git a/lib/utils/package-up.js b/lib/utils/package-up.js index 06097c01..f69457ae 100644 --- a/lib/utils/package-up.js +++ b/lib/utils/package-up.js @@ -16,13 +16,18 @@ const { fileURLToPath } = require('url'); /** * Inlined version of the package "package-up" (ESM only). * - * @param {string} cwd The directory to start searching from. + * @param {object} options + * @param {string} options.cwd The directory to start searching from. * @returns {string|undefined} The path to the nearest package.json file or undefined if not found. */ module.exports = function({ cwd }) { return findUpSync('package.json', { cwd, type: 'file' }); }; +/** + * @param {string|URL} urlOrPath + * @returns {string} + */ function toPath(urlOrPath) { return urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath; } @@ -32,7 +37,7 @@ function toPath(urlOrPath) { * * @param {string} name The name of the file to find * @param {object} options - * @param {string} options.cwd The directory to start searching from. + * @param {string=} options.cwd The directory to start searching from. * @returns {string|undefined} The path to the file found or undefined if not found. */ function findUpSync(name, { cwd = process.cwd() } = {}) {