From ad66bed9da8de03b3b8b409a0fb35dcae5037df2 Mon Sep 17 00:00:00 2001 From: Benjamin Lim Date: Tue, 7 Feb 2017 14:48:59 +0800 Subject: [PATCH] feat: add Watching, MultiCompiler, and MultiWatching types to webpack function return type - add Compiler, Watching classes - add Plugin abstract class - change plugins to extend Plugin BREAKING CHANGE: - change Plugin apply param type from Webpack to Compiler - remove plugin static types - remove Webpack and Optimize interfaces --- .../html-webpack-plugin-tests.ts | 52 +- html-webpack-plugin/index.d.ts | 164 +++--- .../html-webpack-template-tests.ts | 120 ++--- html-webpack-template/index.d.ts | 136 +++-- lodash-webpack-plugin/index.d.ts | 7 +- .../lodash-webpack-plugin-tests.ts | 52 +- webpack-notifier/index.d.ts | 24 +- webpack-notifier/webpack-notifier-tests.ts | 20 +- webpack-stream/index.d.ts | 56 +- webpack-stream/tsconfig.json | 4 +- webpack-stream/tslint.json | 1 + webpack-stream/webpack-stream-tests.ts | 4 +- webpack/index.d.ts | 487 ++++++++---------- webpack/webpack-tests.ts | 3 +- 14 files changed, 504 insertions(+), 626 deletions(-) create mode 100644 webpack-stream/tslint.json diff --git a/html-webpack-plugin/html-webpack-plugin-tests.ts b/html-webpack-plugin/html-webpack-plugin-tests.ts index 485f6a81bf..a84d19bea5 100644 --- a/html-webpack-plugin/html-webpack-plugin-tests.ts +++ b/html-webpack-plugin/html-webpack-plugin-tests.ts @@ -1,34 +1,24 @@ -import HtmlWebpackPlugin = require("html-webpack-plugin"); -import { Configuration } from "webpack"; +import * as HtmlWebpackPlugin from 'html-webpack-plugin'; -const a: Configuration = { - plugins: [ - new HtmlWebpackPlugin() - ] -}; +new HtmlWebpackPlugin(); -const b: Configuration = { - plugins: [ - new HtmlWebpackPlugin({ - title: "test" - }) - ] -}; +const optionsArray: HtmlWebpackPlugin.Options[] = [ + { + title: 'test', + }, + { + minify: { + caseSensitive: true, + }, + }, + { + chunksSortMode: function compare(a, b) { + return 1; + }, + }, + { + arbitrary: 'data', + }, +]; -const minify: HtmlWebpackPlugin.MinifyConfig = { - caseSensitive: true -}; - -new HtmlWebpackPlugin({ - minify -}); - -new HtmlWebpackPlugin({ - chunksSortMode: function compare(a, b) { - return 1; - } -}); - -new HtmlWebpackPlugin({ - arbitrary: "data" -}); +const plugins: HtmlWebpackPlugin[] = optionsArray.map(options => new HtmlWebpackPlugin(options)); diff --git a/html-webpack-plugin/index.d.ts b/html-webpack-plugin/index.d.ts index f34d46c8c2..792c7a2dc0 100644 --- a/html-webpack-plugin/index.d.ts +++ b/html-webpack-plugin/index.d.ts @@ -3,106 +3,86 @@ // Definitions by: Simon Hartcher , Benjamin Lim // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -import { Plugin, Webpack } from "webpack"; -import { Options } from "html-minifier"; +import { Plugin } from 'webpack'; +import { Options as HtmlMinifierOptions } from 'html-minifier'; export = HtmlWebpackPlugin; -declare class HtmlWebpackPlugin implements Plugin { - constructor(options?: HtmlWebpackPlugin.Config); - apply(thisArg: Webpack, ...args: any[]): void; +declare class HtmlWebpackPlugin extends Plugin { + constructor(options?: HtmlWebpackPlugin.Options); } declare namespace HtmlWebpackPlugin { - export type MinifyConfig = Options; + type MinifyOptions = HtmlMinifierOptions; - /** - * It is assumed that each [chunk] contains at least the properties "id" - * (containing the chunk id) and "parents" (array containing the ids of the - * parent chunks). - */ - export interface Chunk { // TODO: Import from webpack? - id: string; - parents: string[]; - [propName: string]: any; // TODO: Narrow type - } + /** + * It is assumed that each [chunk] contains at least the properties "id" + * (containing the chunk id) and "parents" (array containing the ids of the + * parent chunks). + * + * @todo define in webpack + */ + interface Chunk { + id: string; + parents: string[]; + [propName: string]: any; + } - export type ChunkComparator = (a: Chunk, b: Chunk) => number; + type ChunkComparator = (a: Chunk, b: Chunk) => number; - export interface Config { - /** - * The title to use for the generated HTML document. - */ - title?: string; + interface Options { + /** `true | false` if `true` (default) try to emit the file only if it was changed. */ + cache?: boolean; + /** + * Allows to control how chunks should be sorted before they are included to the html. + * Allowed values: `'none' | 'auto' | 'dependency' | {function}` - default: `'auto'` + */ + chunksSortMode?: 'none' | 'auto' | 'dependency' | ChunkComparator; + /** Allows you to add only some chunks (e.g. only the unit-test chunk) */ + chunks?: string[]; + /** Allows you to skip some chunks (e.g. don't add the unit-test chunk) */ + excludeChunks?: string[]; + /** Adds the given favicon path to the output html. */ + favicon?: string; + /** + * The file to write the HTML to. + * Defaults to index.html. You can specify a subdirectory here too (eg: `assets/admin.html`). + */ + filename?: string; + /** + * `true | false` if `true` then append a unique webpack compilation hash to all included scripts and css files. + * This is useful for cache busting. + */ + hash?: boolean; + /** + * `true | 'head' | 'body' | false` + * Inject all assets into the given template or templateContent. + * When passing true or 'body' all javascript resources will be placed at the bottom of the body element. + * 'head' will place the scripts in the head element. + */ + inject?: 'body' | 'head' | boolean; + /** + * `{...} | false` Pass a html-minifier options object to minify the output. + * https://github.com/kangax/html-minifier#options-quick-reference + */ + minify?: false | MinifyOptions; + /** `true | false` if `true` (default) errors details will be written into the html page. */ + showErrors?: boolean; + /** Webpack require path to the template. Please see the docs for details. */ + template?: string; + /** The title to use for the generated HTML document. */ + title?: string; + /** `true | false` If `true` render the link tags as self-closing, XHTML compliant. Default is `false` */ + xhtml?: boolean; + /** + * In addition to the options actually used by this plugin, you can use this hash to pass arbitrary data through + * to your template. + */ + [option: string]: any; + } - /** - * The file to write the HTML to. Defaults to index.html. You can specify a subdirectory here too (eg: `assets/admin.html`). - */ - filename?: string; - - /** - * Webpack require path to the template. Please see the docs for details. - */ - template?: string; - - /** - * `true | 'head' | 'body' | false` - * - * Inject all assets into the given template or templateContent - When passing true or 'body' all javascript resources will be placed at the bottom of the body element. 'head' will place the scripts in the head element. - */ - inject?: boolean | "head" | "body"; - - /** - * Adds the given favicon path to the output html. - */ - favicon?: string; - - /** - * `{...} | false` Pass a html-minifier options object to minify the output. - * - * https://github.com/kangax/html-minifier#options-quick-reference - */ - minify?: MinifyConfig | false; - - /** - * `true | false` if `true` then append a unique webpack compilation hash to all included scripts and css files. This is useful for cache busting. - */ - hash?: boolean; - - /** - * `true | false` if `true` (default) try to emit the file only if it was changed. - */ - cache?: boolean; - - /** - * `true | false` if `true` (default) errors details will be written into the html page. - */ - showErrors?: boolean; - - /** - * Allows you to add only some chunks (e.g. only the unit-test chunk) - */ - chunks?: string[]; - - /** - * Allows to control how chunks should be sorted before they are included to the html. Allowed values: `'none' | 'auto' | 'dependency' | {function}` - default: `'auto'` - */ - chunksSortMode?: "none" | "auto" | "dependency" | ChunkComparator; - - /** - * Allows you to skip some chunks (e.g. don't add the unit-test chunk) - */ - excludeChunks?: string[]; - - /** - * `true | false` If `true` render the link tags as self-closing, XHTML compliant. Default is `false` - */ - xhtml?: boolean; - - /** - * In addition to the options actually used by this plugin, you can use - * this hash to pass arbitrary data through to your template. - */ - [option: string]: any; - } + /** @deprecated use MinifyOptions */ + type MinifyConfig = MinifyOptions; + /** @deprecated use Options */ + type Config = Options; } diff --git a/html-webpack-template/html-webpack-template-tests.ts b/html-webpack-template/html-webpack-template-tests.ts index c24a9506d3..4407af69eb 100644 --- a/html-webpack-template/html-webpack-template-tests.ts +++ b/html-webpack-template/html-webpack-template-tests.ts @@ -1,65 +1,65 @@ -import HtmlWebpackPlugin = require('html-webpack-plugin'); -import template = require('html-webpack-template'); +import * as HtmlWebpackPlugin from 'html-webpack-plugin'; +import * as template from 'html-webpack-template'; -const configs: Array = [ - { - // Required - inject: false, - template, - // template: 'node_modules/html-webpack-template/index.ejs', +const optionsArray: template.Options[] = [ + { + /** Required */ + inject: false, + template, + // template: 'node_modules/html-webpack-template/index.ejs', - // Optional - appMountId: 'app', - appMountIds: [ - 'root0', - 'root1', - ], - baseHref: 'http://example.com/awesome', - devServer: 'http://localhost:3001', - googleAnalytics: { - trackingId: 'UA-XXXX-XX', - pageViewOnLoad: true, - }, - links: [ - 'https://fonts.googleapis.com/css?family=Roboto', - { - href: '/apple-touch-icon.png', - rel: 'apple-touch-icon', - sizes: '180x180', - }, - { - href: '/favicon-32x32.png', - rel: 'icon', - sizes: '32x32', - type: 'image/png', - }, - ], - meta: [ - { - description: 'A better default template for html-webpack-plugin.', - }, - ], - mobile: true, - inlineManifestWebpackName: 'webpackManifest', - scripts: [ - 'http://example.com/somescript.js', - { - src: '/myModule.js', - type: 'module', - }, - ], - window: { - env: { - apiHost: 'http://myapi.com/api/v1', - }, - }, + /** Optional */ + appMountId: 'app', + appMountIds: [ + 'root0', + 'root1', + ], + baseHref: 'http://example.com/awesome', + devServer: 'http://localhost:3001', + googleAnalytics: { + trackingId: 'UA-XXXX-XX', + pageViewOnLoad: true, + }, + links: [ + 'https://fonts.googleapis.com/css?family=Roboto', + { + href: '/apple-touch-icon.png', + rel: 'apple-touch-icon', + sizes: '180x180', + }, + { + href: '/favicon-32x32.png', + rel: 'icon', + sizes: '32x32', + type: 'image/png', + }, + ], + meta: [ + { + description: 'A better default template for html-webpack-plugin.', + }, + ], + mobile: true, + inlineManifestWebpackName: 'webpackManifest', + scripts: [ + 'http://example.com/somescript.js', + { + src: '/myModule.js', + type: 'module', + }, + ], + window: { + env: { + apiHost: 'http://myapi.com/api/v1', + }, + }, - // And any other config options from html-webpack-plugin: - // https://github.com/ampedandwired/html-webpack-plugin#configuration - title: 'My App', - }, + /** + * And any other config options from html-webpack-plugin: + * https://github.com/ampedandwired/html-webpack-plugin#configuration + */ + title: 'My App', + }, ]; -const plugins: Array = configs.map(config => - new HtmlWebpackPlugin(config) -); +const plugins: HtmlWebpackPlugin[] = optionsArray.map(options => new HtmlWebpackPlugin(options)); diff --git a/html-webpack-template/index.d.ts b/html-webpack-template/index.d.ts index e224e96296..f1b57fa331 100644 --- a/html-webpack-template/index.d.ts +++ b/html-webpack-template/index.d.ts @@ -3,94 +3,74 @@ // Definitions by: Benjamin Lim // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -import { Config as HtmlWebpackPluginConfig } from 'html-webpack-plugin'; +import { Options as HtmlWebpackPluginOptions } from 'html-webpack-plugin'; export = HtmlWebpackTemplate; declare const HtmlWebpackTemplate: string; declare namespace HtmlWebpackTemplate { - export interface GoogleAnalyticsConfig { - trackingId: string; - // Log a pageview event after the analytics code loads. - pageViewOnLoad?: boolean; - } + interface GoogleAnalyticsOptions { + /** Log a pageview event after the analytics code loads. */ + pageViewOnLoad?: boolean; + trackingId: string; + } - export interface Attributes { - [name: string]: any; - } + interface Attributes { + [name: string]: any; + } - type Resource = string | Attributes; + type Resource = string | Attributes; - /** - * string: value is assigned to the href attribute and the rel attribute is - * set to "stylesheet" - * - * object: properties and values are used as the attribute names and values, - * respectively: - */ - export type Link = Resource; + /** + * string: value is assigned to the href attribute and the rel attribute is set to "stylesheet" + * object: properties and values are used as the attribute names and values, respectively. + */ + type Link = Resource; - /** - * string: value is assigned to the src attribute and the type attribute is - * set to "text/javascript"; - * - * object: properties and values are used as the attribute names and values, - * respectively. - */ - export type Script = Resource; + /** + * string: value is assigned to the src attribute and the type attribute is set to "text/javascript". + * object: properties and values are used as the attribute names and values, respectively. + */ + type Script = Resource; - export interface Config extends HtmlWebpackPluginConfig { - /** - * Set to false. Controls asset addition to the template. This template - * takes care of that. - */ - inject: false; + interface Options extends HtmlWebpackPluginOptions { + /** The
element id on which you plan to mount a JavaScript app. */ + appMountId?: string; + /** An array of application element ids. */ + appMountIds?: string[]; + /** + * Adjust the URL for relative URLs in the document (MDN). + * https://developer.mozilla.org/en/docs/Web/HTML/Element/base + */ + baseHref?: string; + /** Insert the webpack-dev-server hot reload script at this host:port/path; e.g., http://localhost:3000. */ + devServer?: string; + /** Track usage of your site via Google Analytics. */ + googleAnalytics?: GoogleAnalyticsOptions; + /** Set to false. Controls asset addition to the template. This template takes care of that. */ + inject: false; + /** + * For use with inline-manifest-webpack-plugin. + * https://github.com/szrenwei/inline-manifest-webpack-plugin + */ + inlineManifestWebpackName?: string; + /** Array of elements. */ + links?: Link[]; + /** Array of objects containing key value pairs to be included as meta tags. */ + meta?: Attributes[]; + /** Sets appropriate meta tag for page scaling. */ + mobile?: boolean; + /** Array of external script imports to include on page. */ + scripts?: Script[]; + /** Specify this module's index.ejs file. */ + template: string; + /** Object that defines data you need to bootstrap a JavaScript app. */ + window?: {}; + } - // Specify this module's index.ejs file. - template: string; - - // The
element id on which you plan to mount a JavaScript app. - appMountId?: string; - - // An array of application element ids. - appMountIds?: string[]; - - /** - * Adjust the URL for relative URLs in the document (MDN). - * https://developer.mozilla.org/en/docs/Web/HTML/Element/base - */ - baseHref?: string; - - /** - * Insert the webpack-dev-server hot reload script at this - * host:port/path; e.g., http://localhost:3000. - */ - devServer?: string; - - // Track usage of your site via Google Analytics. - googleAnalytics?: GoogleAnalyticsConfig; - - // Array of elements. - links?: Link[]; - - // Array of objects containing key value pairs to be included as meta tags. - meta?: Attributes[]; - - // Sets appropriate meta tag for page scaling. - mobile?: boolean; - - /** - * For use with inline-manifest-webpack-plugin. - * - * https://github.com/szrenwei/inline-manifest-webpack-plugin - */ - inlineManifestWebpackName?: string; - - // Array of external script imports to include on page. - scripts?: Script[]; - - // Object that defines data you need to bootstrap a JavaScript app. - window?: {}; - } + /** @deprecated use GoogleAnalyticsOptions */ + type GoogleAnalyticsConfig = GoogleAnalyticsOptions; + /** @deprecated use Options */ + type Config = Options; } diff --git a/lodash-webpack-plugin/index.d.ts b/lodash-webpack-plugin/index.d.ts index 26d633e79f..7b2c3ebe67 100644 --- a/lodash-webpack-plugin/index.d.ts +++ b/lodash-webpack-plugin/index.d.ts @@ -3,17 +3,16 @@ // Definitions by: Benjamin Lim // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -import { Plugin, Webpack } from 'webpack'; +import { Plugin } from 'webpack'; export = LodashModuleReplacementPlugin; -declare class LodashModuleReplacementPlugin implements Plugin { +declare class LodashModuleReplacementPlugin extends Plugin { constructor(options?: LodashModuleReplacementPlugin.Options); - apply(thisArg: Webpack, ...args: any[]): void; } declare namespace LodashModuleReplacementPlugin { - export interface Options { + interface Options { caching?: boolean; chaining?: boolean; cloning?: boolean; diff --git a/lodash-webpack-plugin/lodash-webpack-plugin-tests.ts b/lodash-webpack-plugin/lodash-webpack-plugin-tests.ts index cd893f09f0..d6483e3d03 100644 --- a/lodash-webpack-plugin/lodash-webpack-plugin-tests.ts +++ b/lodash-webpack-plugin/lodash-webpack-plugin-tests.ts @@ -1,27 +1,31 @@ -import * as LodashModuleReplacementPlugin from 'lodash-webpack-plugin' +import * as LodashModuleReplacementPlugin from 'lodash-webpack-plugin'; -new LodashModuleReplacementPlugin() +new LodashModuleReplacementPlugin(); -new LodashModuleReplacementPlugin({ - collections: true, - paths: true, -}) +const optionsArray: LodashModuleReplacementPlugin.Options[] = [ + { + collections: true, + paths: true, + }, + { + caching: true, + chaining: true, + cloning: true, + coercions: true, + collections: true, + currying: true, + deburring: true, + exotics: true, + flattening: true, + guards: true, + memoizing: true, + metadata: true, + paths: true, + placeholders: true, + shorthands: true, + unicode: true, + }, +]; -new LodashModuleReplacementPlugin({ - caching: true, - chaining: true, - cloning: true, - coercions: true, - collections: true, - currying: true, - deburring: true, - exotics: true, - flattening: true, - guards: true, - memoizing: true, - metadata: true, - paths: true, - placeholders: true, - shorthands: true, - unicode: true, -}) +const plugins: LodashModuleReplacementPlugin[] = optionsArray + .map(options => new LodashModuleReplacementPlugin(options)); diff --git a/webpack-notifier/index.d.ts b/webpack-notifier/index.d.ts index 8caff77388..1b8e92651f 100644 --- a/webpack-notifier/index.d.ts +++ b/webpack-notifier/index.d.ts @@ -3,21 +3,23 @@ // Definitions by: Benjamin Lim // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -import { Plugin, Webpack } from 'webpack'; +import { Plugin } from 'webpack'; export = WebpackNotifierPlugin; -declare class WebpackNotifierPlugin implements Plugin { - constructor(options?: WebpackNotifierPlugin.Config); - apply(thisArg: Webpack, ...args: any[]): void; +declare class WebpackNotifierPlugin extends Plugin { + constructor(options?: WebpackNotifierPlugin.Options); } declare namespace WebpackNotifierPlugin { - export interface Config { - title?: string; - contentImage?: string; - excludeWarnings?: boolean; - alwaysNotify?: boolean; - skipFirstNotification?: boolean; - } + interface Options { + alwaysNotify?: boolean; + contentImage?: string; + excludeWarnings?: boolean; + skipFirstNotification?: boolean; + title?: string; + } + + /** @deprecated use Options */ + type Config = Options; } diff --git a/webpack-notifier/webpack-notifier-tests.ts b/webpack-notifier/webpack-notifier-tests.ts index 9ec1dede26..f71fe5800f 100644 --- a/webpack-notifier/webpack-notifier-tests.ts +++ b/webpack-notifier/webpack-notifier-tests.ts @@ -1,14 +1,14 @@ -import WebpackNotifierPlugin = require('webpack-notifier'); import { Plugin } from 'webpack'; +import * as WebpackNotifierPlugin from 'webpack-notifier'; -const configs: Array = [ - { - title: 'Webpack', - contentImage: 'logo.png', - excludeWarnings: true, - alwaysNotify: true, - skipFirstNotification: true, - }, +const optionsArray: WebpackNotifierPlugin.Options[] = [ + { + title: 'Webpack', + contentImage: 'logo.png', + excludeWarnings: true, + alwaysNotify: true, + skipFirstNotification: true, + }, ]; -const plugins: Array = configs.map(config => new WebpackNotifierPlugin(config)); +const plugins: Plugin[] = optionsArray.map(options => new WebpackNotifierPlugin(options)); diff --git a/webpack-stream/index.d.ts b/webpack-stream/index.d.ts index 9a36906a03..74b8d01544 100644 --- a/webpack-stream/index.d.ts +++ b/webpack-stream/index.d.ts @@ -1,48 +1,26 @@ -// Type definitions for webpack-stream v3.2.0 +// Type definitions for webpack-stream 3.2 // Project: https://github.com/shama/webpack-stream -// Definitions by: Ian Clanton-Thuon +// Definitions by: Ian Clanton-Thuon , Benjamin Lim // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -/// /// -declare module "webpack-stream" { - import webpack = require("webpack"); +import * as webpack from 'webpack'; - interface WebpackStreamStatic { - /** - * Run webpack with the default configuration. - */ - (): NodeJS.ReadWriteStream; +export = webpackStream; - /** - * Run webpack with the specified configuration. - * - * @param {config} Webpack configuration - */ - (config: webpack.Configuration): NodeJS.ReadWriteStream; +/** + * Run webpack with the specified configuration and webpack instance + * + * @param {webpack.Configuration} config - Webpack configuration + * @param {webpack} wp - A webpack object + * @param {webpack.Compiler.Handler} callback - A callback with the webpack stats and error objects. + */ +declare function webpackStream( + config?: webpack.Configuration, + wp?: typeof webpack, + callback?: webpack.Compiler.Handler, +): NodeJS.ReadWriteStream; - /** - * Run webpack with the specified configuration and webpack instance - * - * @param {config} Webpack configuration - * @param {webpack} A webpack object - */ - (config: webpack.Configuration, webpack: webpack.Webpack): NodeJS.ReadWriteStream; - - /** - * Run webpack with the specified configuration and webpack instance - * - * @param {config} Webpack configuration - * @param {webpack} A webpack object - * @param {callback} A callback with the webpack stats and error objects. - */ - (config: webpack.Configuration, - webpack: webpack.Webpack, - callback?: (err: Error, stats: webpack.compiler.Stats) => void): NodeJS.ReadWriteStream; - } - - var webpackStream: WebpackStreamStatic; - - export = webpackStream; +declare namespace webpackStream { } diff --git a/webpack-stream/tsconfig.json b/webpack-stream/tsconfig.json index e1986eac35..65fc295fdf 100644 --- a/webpack-stream/tsconfig.json +++ b/webpack-stream/tsconfig.json @@ -6,7 +6,7 @@ ], "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../" @@ -19,4 +19,4 @@ "index.d.ts", "webpack-stream-tests.ts" ] -} \ No newline at end of file +} diff --git a/webpack-stream/tslint.json b/webpack-stream/tslint.json new file mode 100644 index 0000000000..377cc837d4 --- /dev/null +++ b/webpack-stream/tslint.json @@ -0,0 +1 @@ +{ "extends": "../tslint.json" } diff --git a/webpack-stream/webpack-stream-tests.ts b/webpack-stream/webpack-stream-tests.ts index 9f13f53b02..b6e4cce807 100644 --- a/webpack-stream/webpack-stream-tests.ts +++ b/webpack-stream/webpack-stream-tests.ts @@ -1,5 +1,5 @@ -import webpackStream = require("webpack-stream"); -import webpack = require("webpack"); +import * as webpack from 'webpack'; +import * as webpackStream from 'webpack-stream'; let output: NodeJS.ReadWriteStream; diff --git a/webpack/index.d.ts b/webpack/index.d.ts index 9ffc5388d7..a5cbc78b0f 100644 --- a/webpack/index.d.ts +++ b/webpack/index.d.ts @@ -5,8 +5,22 @@ /// +import * as Tapable from 'tapable'; import * as UglifyJS from 'uglify-js'; -import * as tapable from 'tapable'; + +export = webpack; + +declare function webpack( + options: webpack.Configuration, + handler: webpack.Compiler.Handler +): webpack.Compiler.Watching | webpack.Compiler; +declare function webpack(options?: webpack.Configuration): webpack.Compiler; + +declare function webpack( + options: webpack.Configuration[], + handler: webpack.MultiCompiler.Handler +): webpack.MultiWatching | webpack.MultiCompiler; +declare function webpack(options: webpack.Configuration[]): webpack.MultiCompiler; declare namespace webpack { interface Configuration { @@ -324,9 +338,6 @@ declare namespace webpack { type ExternalsFunctionElement = (context: any, request: any, callback: (error: any, result: any) => void) => any; - /** @deprecated use webpack.Compiler.WatchOptions */ - type WatchOptions = webpack.Compiler.WatchOptions; - interface Node { console?: boolean; global?: boolean; @@ -483,10 +494,18 @@ declare namespace webpack { */ maxEntrypointSize?: number; } - type WatchOptions = Compiler.WatchOptions; + type WatchOptions = ICompiler.WatchOptions; } - namespace Compiler { + // tslint:disable-next-line:interface-name + interface ICompiler { + run(handler: ICompiler.Handler): void; + watch(watchOptions: ICompiler.WatchOptions, handler: ICompiler.Handler): Watching; + } + + namespace ICompiler { + type Handler = (err: Error, stats: compiler.Stats) => void; + interface WatchOptions { /** * Add a delay before rebuilding once the first file changed. This allows webpack to aggregate any other @@ -505,251 +524,210 @@ declare namespace webpack { } } - interface Plugin extends tapable.Plugin { - apply(thisArg: Webpack, ...args: any[]): void; + interface Watching { + close(callback: () => void): void; + invalidate(): void; } - type UglifyCommentFunction = (astNode: any, comment: any) => boolean; + class Compiler extends Tapable implements ICompiler { + constructor(); - interface UglifyPluginOptions extends UglifyJS.MinifyOptions { - beautify?: boolean; - comments?: boolean | RegExp | UglifyCommentFunction; - sourceMap?: boolean; - test?: Condition | Condition[]; - include?: Condition | Condition[]; - exclude?: Condition | Condition[]; + name: string; + options: Configuration; + outputFileSystem: any; + run(handler: Compiler.Handler): void; + watch(watchOptions: Compiler.WatchOptions, handler: Compiler.Handler): Compiler.Watching; } - interface Webpack { - (config: Configuration, callback?: compiler.CompilerCallback): compiler.Compiler; - /** - * optimize namespace - */ - optimize: Optimize; - /** - * dependencies namespace - */ - dependencies: {}; - /** - * Replace resources that matches resourceRegExp with newResource. - * If newResource is relative, it is resolve relative to the previous resource. - * If newResource is a function, it is expected to overwrite the ‘request’ attribute of the supplied object. - */ - NormalModuleReplacementPlugin: NormalModuleReplacementPluginStatic; - /** - * Replaces the default resource, recursive flag or regExp generated by parsing with newContentResource, - * newContentRecursive resp. newContextRegExp if the resource (directory) matches resourceRegExp. - * If newContentResource is relative, it is resolve relative to the previous resource. - * If newContentResource is a function, it is expected to overwrite the ‘request’ attribute of the supplied object. - */ - ContextReplacementPlugin: ContextReplacementPluginStatic; - /** - * Don’t generate modules for requests matching the provided RegExp. - */ - IgnorePlugin: IgnorePluginStatic; - /** - * A request for a normal module, which is resolved and built even before a require to it occurs. - * This can boost performance. Try to profile the build first to determine clever prefetching points. - */ - PrefetchPlugin: PrefetchPluginStatic; - /** - * Adds a banner to the top of each generated chunk. - */ - BannerPlugin: BannerPluginStatic; - /** - * Define free variables. Useful for having development builds with debug logging or adding global constants. - */ - DefinePlugin: DefinePluginStatic; - /** - * Automatically loaded modules. - * Module (value) is loaded when the identifier (key) is used as free variable in a module. - * The identifier is filled with the exports of the loaded module. - */ - ProvidePlugin: ProvidePluginStatic; - /** - * Adds SourceMaps for assets. - */ - SourceMapDevToolPlugin: SourceMapDevToolPluginStatic; - /** - * Adds SourceMaps for assets, but wrapped inside eval statements. - * Much faster incremental build speed, but harder to debug. - */ - EvalSourceMapDevToolPlugin: EvalSourceMapDevToolPluginStatic; - /** - * Enables Hot Module Replacement. (This requires records data if not in dev-server mode, recordsPath) - * Generates Hot Update Chunks of each chunk in the records. - * It also enables the API and makes __webpack_hash__ available in the bundle. - */ - HotModuleReplacementPlugin: HotModuleReplacementPluginStatic; - /** - * Adds useful free vars to the bundle. - */ - ExtendedAPIPlugin: ExtendedAPIPluginStatic; - /** - * When there are errors while compiling this plugin skips the emitting phase (and recording phase), - * so there are no assets emitted that include errors. The emitted flag in the stats is false for all assets. - */ - NoEmitOnErrorsPlugin: NoEmitOnErrorsPluginStatic; - /** - * Alias for NoEmitOnErrorsPlugin - * @deprecated - */ - NoErrorsPlugin: NoEmitOnErrorsPluginStatic; - /** - * Does not watch specified files matching provided paths or RegExps. - */ - WatchIgnorePlugin: WatchIgnorePluginStatic; - /** - * Uses the module name as the module id inside the bundle, instead of a number. - * Helps with debugging, but increases bundle size. - */ - NamedModulesPlugin: NamedModulesPluginStatic; - /** - * Some loaders need context information and read them from the configuration. - * This need to be passed via loader options in the long-term. See loader documentation for relevant options. - * To keep compatibility with old loaders, these options can be passed via this plugin. - */ - LoaderOptionsPlugin: LoaderOptionsPluginStatic; + namespace Compiler { + type Handler = ICompiler.Handler; + type WatchOptions = ICompiler.WatchOptions; + + class Watching implements webpack.Watching { + constructor(compiler: Compiler, watchOptions: Watching.WatchOptions, handler: Watching.Handler); + + close(callback: () => void): void; + invalidate(): void; + } + + namespace Watching { + type WatchOptions = ICompiler.WatchOptions; + type Handler = ICompiler.Handler; + } } - interface Optimize { - /** - * Search for equal or similar files and deduplicate them in the output. - * This comes with some overhead for the entry chunk, but can reduce file size effectively. - * This is experimental and may crash, because of some missing implementations. (Report an issue) - */ - DedupePlugin: optimize.DedupePluginStatic; - /** - * Limit the chunk count to a defined value. Chunks are merged until it fits. - */ - LimitChunkCountPlugin: optimize.LimitChunkCountPluginStatic; - /** - * Merge small chunks that are lower than this min size (in chars). Size is approximated. - */ - MinChunkSizePlugin: optimize.MinChunkSizePluginStatic; - /** - * Assign the module and chunk ids by occurrence count. Ids that are used often get lower (shorter) ids. - * This make ids predictable, reduces to total file size and is recommended. - */ - OccurrenceOrderPlugin: optimize.OccurrenceOrderPluginStatic; - /** - * Minimize all JavaScript output of chunks. Loaders are switched into minimizing mode. - * You can pass an object containing UglifyJs options. - */ - UglifyJsPlugin: optimize.UglifyJsPluginStatic; - CommonsChunkPlugin: optimize.CommonsChunkPluginStatic; - /** - * A plugin for a more aggressive chunk merging strategy. - * Even similar chunks are merged if the total size is reduced enough. - * As an option modules that are not common in these chunks can be moved up the chunk tree to the parents. - */ - AggressiveMergingPlugin: optimize.AggressiveMergingPluginStatic; + abstract class MultiCompiler implements ICompiler { + run(handler: MultiCompiler.Handler): void; + watch(watchOptions: MultiCompiler.WatchOptions, handler: MultiCompiler.Handler): MultiWatching; } - interface NormalModuleReplacementPluginStatic { - new (resourceRegExp: any, newResource: any): Plugin; + namespace MultiCompiler { + type Handler = ICompiler.Handler; + type WatchOptions = ICompiler.WatchOptions; } - interface ContextReplacementPluginStatic { - new (resourceRegExp: any, newContentResource?: any, newContentRecursive?: any, newContentRegExp?: any): Plugin; + abstract class MultiWatching implements Watching { + close(callback: () => void): void; + invalidate(): void; } - interface IgnorePluginStatic { - new (requestRegExp: any, contextRegExp?: any): Plugin; + abstract class Plugin implements Tapable.Plugin { + apply(compiler: Compiler): void; } - interface PrefetchPluginStatic { + /** + * Plugins + */ + + class BannerPlugin extends Plugin { + constructor(banner: any, options: any); + } + + class ContextReplacementPlugin extends Plugin { + constructor(resourceRegExp: any, newContentResource?: any, newContentRecursive?: any, newContentRegExp?: any); + } + + class DefinePlugin extends Plugin { + constructor(definitions: {[key: string]: any}); + } + + class EvalSourceMapDevToolPlugin extends Plugin { + constructor(options?: false | string | EvalSourceMapDevToolPlugin.Options); + } + + namespace EvalSourceMapDevToolPlugin { + interface Options { + append?: false | string; + columns?: boolean; + lineToLine?: boolean | { + exclude?: Condition | Condition[]; + include?: Condition | Condition[]; + test?: Condition | Condition[]; + }; + module?: boolean; + moduleFilenameTemplate?: string; + sourceRoot?: string; + } + } + + class ExtendedAPIPlugin extends Plugin { + constructor(); + } + + class HotModuleReplacementPlugin extends Plugin { + constructor(options?: any); + } + + class IgnorePlugin extends Plugin { + constructor(requestRegExp: any, contextRegExp?: any); + } + + class LoaderOptionsPlugin extends Plugin { + constructor(options: any); + } + + class NamedModulesPlugin extends Plugin { + constructor(); + } + + class NoEmitOnErrorsPlugin extends Plugin { + constructor(); + } + + /** @deprecated use webpack.NoEmitOnErrorsPlugin */ + class NoErrorsPlugin extends Plugin { + constructor(); + } + + class NormalModuleReplacementPlugin extends Plugin { + constructor(resourceRegExp: any, newResource: any); + } + + class PrefetchPlugin extends Plugin { // tslint:disable-next-line:unified-signatures - new (context: any, request: any): Plugin; - new (request: any): Plugin; + constructor(context: any, request: any); + constructor(request: any); } - interface BannerPluginStatic { - new (banner: any, options: any): Plugin; + class ProvidePlugin extends Plugin { + constructor(definitions: {[key: string]: any}); } - interface DefinePluginStatic { - new (definitions: {[key: string]: any}): Plugin; + class SourceMapDevToolPlugin extends Plugin { + constructor(options?: null | false | string | SourceMapDevToolPlugin.Options); } - interface ProvidePluginStatic { - new (definitions: {[key: string]: any}): Plugin; - } - - interface SourceMapDevToolPluginStatic { - // if string | false | null, maps to the filename option - new (options?: string | false | null | SourceMapDevToolPluginOptions): Plugin; - } - - interface SourceMapDevToolPluginOptions { - // output filename pattern (false/null to append) - filename?: string | false | null; - // source map comment pattern (false to not append) - append?: false | string; - // template for the module filename inside the source map - moduleFilenameTemplate?: string; - // fallback used when the moduleFilenameTemplate produces a collision - fallbackModuleFilenameTemplate?: string; - // test/include/exclude files - test?: Condition | Condition[]; - include?: Condition | Condition[]; - exclude?: Condition | Condition[]; - // whether to include the footer comment with source information - noSources?: boolean; - // the source map sourceRoot ("The URL root from which all sources are relative.") - sourceRoot?: string | null; - // whether to generate per-module source map - module?: boolean; - // whether to include column information in the source map - columns?: boolean; - // whether to preserve line numbers between source and source map - lineToLine?: boolean | { - test?: Condition | Condition[]; - include?: Condition | Condition[]; + namespace SourceMapDevToolPlugin { + /** @todo extend EvalSourceMapDevToolPlugin.Options */ + interface Options { + append?: false | string; + columns?: boolean; exclude?: Condition | Condition[]; - }; - } - - interface EvalSourceMapDevToolPluginStatic { - // if string | false, maps to the append option - new (options?: string | false | EvalSourceMapDevToolPluginOptions): Plugin; - } - - interface EvalSourceMapDevToolPluginOptions { - append?: false | string; - moduleFilenameTemplate?: string; - sourceRoot?: string; - module?: boolean; - columns?: boolean; - lineToLine?: boolean | { - test?: Condition | Condition[]; + fallbackModuleFilenameTemplate?: string; + filename?: null | false | string; include?: Condition | Condition[]; - exclude?: Condition | Condition[]; - }; + lineToLine?: boolean | { + exclude?: Condition | Condition[]; + include?: Condition | Condition[]; + test?: Condition | Condition[]; + }; + module?: boolean; + moduleFilenameTemplate?: string; + noSources?: boolean; + sourceRoot?: null | string; + test?: Condition | Condition[]; + } } - interface HotModuleReplacementPluginStatic { - new (options?: any): Plugin; + class WatchIgnorePlugin extends Plugin { + constructor(paths: RegExp[]); } - interface ExtendedAPIPluginStatic { - new (): Plugin; + namespace optimize { + class AggressiveMergingPlugin extends Plugin { + constructor(options: any); + } + + class CommonsChunkPlugin extends Plugin { + constructor(options?: any); + } + + /** @deprecated */ + class DedupePlugin extends Plugin { + constructor(); + } + + class LimitChunkCountPlugin extends Plugin { + constructor(options: any); + } + + class MinChunkSizePlugin extends Plugin { + constructor(options: any); + } + + class OccurrenceOrderPlugin extends Plugin { + constructor(preferEntry: boolean); + } + + class UglifyJsPlugin extends Plugin { + constructor(options?: UglifyJsPlugin.Options); + } + + namespace UglifyJsPlugin { + type CommentFilter = (astNode: any, comment: any) => boolean; + + interface Options extends UglifyJS.MinifyOptions { + beautify?: boolean; + comments?: boolean | RegExp | CommentFilter; + exclude?: Condition | Condition[]; + include?: Condition | Condition[]; + sourceMap?: boolean; + test?: Condition | Condition[]; + } + } } - interface NoEmitOnErrorsPluginStatic { - new (): Plugin; - } - - interface WatchIgnorePluginStatic { - new (paths: RegExp[]): Plugin; - } - - interface NamedModulesPluginStatic { - new (): Plugin; - } - - interface LoaderOptionsPluginStatic { - new (options: any): Plugin; + namespace dependencies { } namespace loader { @@ -1012,7 +990,7 @@ declare namespace webpack { /** * Hacky access to the Compiler object of webpack. */ - _compiler: compiler.Compiler; + _compiler: Compiler; /** @@ -1022,51 +1000,12 @@ declare namespace webpack { } } - namespace optimize { - interface DedupePluginStatic { - new (): Plugin; - } - interface LimitChunkCountPluginStatic { - new (options: any): Plugin; - } - interface MinChunkSizePluginStatic { - new (options: any): Plugin; - } - interface OccurrenceOrderPluginStatic { - new (preferEntry: boolean): Plugin; - } - interface UglifyJsPluginStatic { - new (options?: UglifyPluginOptions): Plugin; - } - interface CommonsChunkPluginStatic { - new (options?: any): Plugin; - } - interface AggressiveMergingPluginStatic { - new (options: any): Plugin; - } - } - - namespace dependencies { - } - namespace compiler { - interface Compiler { - /** Builds the bundle(s). */ - run(callback: CompilerCallback): void; - /** - * Builds the bundle(s) then starts the watcher, which rebuilds bundles whenever their source files change. - * Returns a Watching instance. Note: since this will automatically run an initial build, so you only need to run watch (and not run). - */ - watch(watchOptions: webpack.Compiler.WatchOptions, handler: CompilerCallback): Watching; - //TODO: below are some of the undocumented properties. needs typings - outputFileSystem: any; - name: string; - options: Configuration; - } + /** @deprecated use webpack.Compiler */ + type Compiler = webpack.Compiler; - interface Watching { - close(callback: () => void): void; - } + /** @deprecated use webpack.Compiler.Watching */ + type Watching = webpack.Compiler.Watching; /** @deprecated use webpack.Compiler.WatchOptions */ type WatchOptions = webpack.Compiler.WatchOptions; @@ -1130,14 +1069,20 @@ declare namespace webpack { colors?: boolean; } - type CompilerCallback = (err: Error, stats: Stats) => void; + /** @deprecated use webpack.Compiler.Handler */ + type CompilerCallback = webpack.Compiler.Handler; } /** @deprecated use webpack.Options.Performance */ type PerformanceOptions = webpack.Options.Performance; + /** @deprecated use webpack.Options.WatchOptions */ + type WatchOptions = webpack.Options.WatchOptions; + /** @deprecated use webpack.EvalSourceMapDevToolPlugin.Options */ + type EvalSourceMapDevToolPluginOptions = webpack.EvalSourceMapDevToolPlugin.Options; + /** @deprecated use webpack.SourceMapDevToolPlugin.Options */ + type SourceMapDevToolPluginOptions = webpack.SourceMapDevToolPlugin.Options; + /** @deprecated use webpack.optimize.UglifyJsPlugin.CommentFilter */ + type UglifyCommentFunction = webpack.optimize.UglifyJsPlugin.CommentFilter; + /** @deprecated use webpack.optimize.UglifyJsPlugin.Options */ + type UglifyPluginOptions = webpack.optimize.UglifyJsPlugin.Options; } - -declare var webpack: webpack.Webpack; - -//export default webpack; -export = webpack; diff --git a/webpack/webpack-tests.ts b/webpack/webpack-tests.ts index 51da9aaad4..ffa69e90f2 100644 --- a/webpack/webpack-tests.ts +++ b/webpack/webpack-tests.ts @@ -207,8 +207,7 @@ declare var require: any; declare var path: any; configuration = { plugins: [ - /** @todo `this` should be typed as webpack.compiler.Compiler (which should be webpack.Compiler), not webpack.Webpack */ - function(this: any) { + function(this: webpack.Compiler) { this.plugin("done", function(stats: any) { require("fs").writeFileSync( path.join(__dirname, "...", "stats.json"),