Skip to content

Commit

Permalink
improve buildHttp
Browse files Browse the repository at this point in the history
allow multiple configurations to write to the same lockfile
add allowedUris for allowlisting
add schema validation
  • Loading branch information
sokra committed Oct 19, 2021
1 parent 8e28305 commit ae52a74
Show file tree
Hide file tree
Showing 16 changed files with 599 additions and 249 deletions.
240 changes: 141 additions & 99 deletions declarations/WebpackOptions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ export type WasmLoadingType =
* An entry point without name.
*/
export type EntryUnnamed = EntryItem;
/**
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
*/
export type Experiments = ExperimentsCommon & ExperimentsExtra;
/**
* Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`.
*/
Expand Down Expand Up @@ -693,6 +697,11 @@ export type EntryDynamicNormalized = () => Promise<EntryStaticNormalized>;
* The entry point(s) of the compilation.
*/
export type EntryNormalized = EntryDynamicNormalized | EntryStaticNormalized;
/**
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
*/
export type ExperimentsNormalized = ExperimentsCommon &
ExperimentsNormalizedExtra;
/**
* The dependency used for the external.
*/
Expand All @@ -703,6 +712,18 @@ export type ExternalItemValue =
| {
[k: string]: any;
};
/**
* List of allowed URIs for building http resources.
*/
export type HttpUriAllowedUris = HttpUriOptionsAllowedUris;
/**
* List of allowed URIs (resp. the beginning of them).
*/
export type HttpUriOptionsAllowedUris = (
| RegExp
| string
| ((uri: string) => boolean)
)[];
/**
* Ignore specific warnings.
*/
Expand Down Expand Up @@ -1098,104 +1119,6 @@ export interface LibraryCustomUmdObject {
*/
root?: string[] | string;
}
/**
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
*/
export interface Experiments {
/**
* Allow module type 'asset' to generate assets.
*/
asset?: boolean;
/**
* Support WebAssembly as asynchronous EcmaScript Module.
*/
asyncWebAssembly?: boolean;
/**
* Build http(s): urls using a lockfile and resource content cache.
*/
buildHttp?: boolean | HttpUriOptions;
/**
* Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.
*/
cacheUnaffected?: boolean;
/**
* Apply defaults of next major version.
*/
futureDefaults?: boolean;
/**
* Enable module and chunk layers.
*/
layers?: boolean;
/**
* Compile entrypoints and import()s only when they are accessed.
*/
lazyCompilation?:
| boolean
| {
/**
* A custom backend.
*/
backend?:
| ((
compiler: import("../lib/Compiler"),
client: string,
callback: (err?: Error, api?: any) => void
) => void)
| ((
compiler: import("../lib/Compiler"),
client: string
) => Promise<any>);
/**
* A custom client.
*/
client?: string;
/**
* Enable/disable lazy compilation for entries.
*/
entries?: boolean;
/**
* Enable/disable lazy compilation for import() modules.
*/
imports?: boolean;
/**
* Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.
*/
test?: RegExp | string | ((module: import("../lib/Module")) => boolean);
};
/**
* Allow output javascript files as module source type.
*/
outputModule?: boolean;
/**
* Support WebAssembly as synchronous EcmaScript Module (outdated).
*/
syncWebAssembly?: boolean;
/**
* Allow using top-level-await in EcmaScript Modules.
*/
topLevelAwait?: boolean;
}
/**
* Options for building http resources.
*/
export interface HttpUriOptions {
/**
* Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.
*/
cacheLocation?: false | string;
/**
* When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error.
*/
frozen?: boolean;
/**
* Location of the lockfile.
*/
lockfileLocation?: string;
/**
* When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed.
*/
upgrade?: boolean;
}
/**
* Enable presets of externals for specific targets.
*/
Expand Down Expand Up @@ -2793,6 +2716,43 @@ export interface EntryStaticNormalized {
*/
[k: string]: EntryDescriptionNormalized;
}
/**
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
*/
export interface ExperimentsCommon {
/**
* Allow module type 'asset' to generate assets.
*/
asset?: boolean;
/**
* Support WebAssembly as asynchronous EcmaScript Module.
*/
asyncWebAssembly?: boolean;
/**
* Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.
*/
cacheUnaffected?: boolean;
/**
* Apply defaults of next major version.
*/
futureDefaults?: boolean;
/**
* Enable module and chunk layers.
*/
layers?: boolean;
/**
* Allow output javascript files as module source type.
*/
outputModule?: boolean;
/**
* Support WebAssembly as synchronous EcmaScript Module (outdated).
*/
syncWebAssembly?: boolean;
/**
* Allow using top-level-await in EcmaScript Modules.
*/
topLevelAwait?: boolean;
}
/**
* Data object passed as argument when a function is set for 'externals'.
*/
Expand Down Expand Up @@ -2826,6 +2786,31 @@ export interface ExternalItemFunctionData {
*/
request?: string;
}
/**
* Options for building http resources.
*/
export interface HttpUriOptions {
/**
* List of allowed URIs (resp. the beginning of them).
*/
allowedUris: HttpUriOptionsAllowedUris;
/**
* Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.
*/
cacheLocation?: false | string;
/**
* When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error.
*/
frozen?: boolean;
/**
* Location of the lockfile.
*/
lockfileLocation?: string;
/**
* When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed.
*/
upgrade?: boolean;
}
/**
* Parser options for javascript modules.
*/
Expand Down Expand Up @@ -2940,6 +2925,37 @@ export interface JavascriptParserOptions {
wrappedContextRegExp?: RegExp;
[k: string]: any;
}
/**
* Options for compiling entrypoints and import()s only when they are accessed.
*/
export interface LazyCompilationOptions {
/**
* A custom backend.
*/
backend?:
| ((
compiler: import("../lib/Compiler"),
client: string,
callback: (err?: Error, api?: any) => void
) => void)
| ((compiler: import("../lib/Compiler"), client: string) => Promise<any>);
/**
* A custom client.
*/
client?: string;
/**
* Enable/disable lazy compilation for entries.
*/
entries?: boolean;
/**
* Enable/disable lazy compilation for import() modules.
*/
imports?: boolean;
/**
* Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.
*/
test?: RegExp | string | ((module: import("../lib/Module")) => boolean);
}
/**
* Options affecting the normal modules (`NormalModuleFactory`).
*/
Expand Down Expand Up @@ -3193,7 +3209,7 @@ export interface WebpackOptionsNormalized {
/**
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
*/
experiments: Experiments;
experiments: ExperimentsNormalized;
/**
* Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`.
*/
Expand Down Expand Up @@ -3295,6 +3311,32 @@ export interface WebpackOptionsNormalized {
*/
watchOptions: WatchOptions;
}
/**
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
*/
export interface ExperimentsExtra {
/**
* Build http(s): urls using a lockfile and resource content cache.
*/
buildHttp?: HttpUriAllowedUris | HttpUriOptions;
/**
* Compile entrypoints and import()s only when they are accessed.
*/
lazyCompilation?: boolean | LazyCompilationOptions;
}
/**
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
*/
export interface ExperimentsNormalizedExtra {
/**
* Build http(s): urls using a lockfile and resource content cache.
*/
buildHttp?: HttpUriOptions;
/**
* Compile entrypoints and import()s only when they are accessed.
*/
lazyCompilation?: LazyCompilationOptions;
}
/**
* If an dependency matches exactly a property of the object, the property value is used as dependency.
*/
Expand Down
12 changes: 12 additions & 0 deletions declarations/plugins/schemes/HttpUriPlugin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,23 @@
*/

export type HttpUriPluginOptions = HttpUriOptions;
/**
* List of allowed URIs (resp. the beginning of them).
*/
export type HttpUriOptionsAllowedUris = (
| RegExp
| string
| ((uri: string) => boolean)
)[];

/**
* Options for building http resources.
*/
export interface HttpUriOptions {
/**
* List of allowed URIs (resp. the beginning of them).
*/
allowedUris: HttpUriOptionsAllowedUris;
/**
* Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.
*/
Expand Down
7 changes: 6 additions & 1 deletion examples/build-http/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ module.exports = {
// loggingDebug: /HttpUriPlugin/
// },
experiments: {
buildHttp: true
buildHttp: [
"https://cdn.esm.sh/",
"https://cdn.skypack.dev/",
"https://jspm.dev/",
/^https:\/\/unpkg\.com\/.+\?module$/
]
}
};
2 changes: 0 additions & 2 deletions lib/WebpackOptionsApply.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,6 @@ class WebpackOptionsApply extends OptionsApply {
if (options.experiments.buildHttp) {
const HttpUriPlugin = require("./schemes/HttpUriPlugin");
const httpOptions = options.experiments.buildHttp;
if (httpOptions === true)
throw new Error("Unexpected due to normalization");
new HttpUriPlugin(httpOptions).apply(compiler);
}

Expand Down
9 changes: 5 additions & 4 deletions lib/config/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const {
/** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */
/** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */
/** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */
/** @typedef {import("../../declarations/WebpackOptions").ExperimentsNormalized} ExperimentsNormalized */
/** @typedef {import("../../declarations/WebpackOptions").ExternalsPresets} ExternalsPresets */
/** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */
/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
Expand Down Expand Up @@ -257,7 +258,7 @@ const applyWebpackOptionsDefaults = options => {
};

/**
* @param {Experiments} experiments options
* @param {ExperimentsNormalized} experiments options
* @param {Object} options options
* @param {boolean} options.production is production
* @param {boolean} options.development is development mode
Expand All @@ -270,14 +271,14 @@ const applyExperimentsDefaults = (experiments, { production, development }) => {
D(experiments, "outputModule", false);
D(experiments, "asset", false);
D(experiments, "layers", false);
D(experiments, "lazyCompilation", false);
D(experiments, "buildHttp", false);
D(experiments, "lazyCompilation", undefined);
D(experiments, "buildHttp", undefined);
D(experiments, "futureDefaults", false);
D(experiments, "cacheUnaffected", experiments.futureDefaults);

if (typeof experiments.buildHttp === "object") {
D(experiments.buildHttp, "frozen", production);
D(experiments.buildHttp, "upgrade", development);
D(experiments.buildHttp, "upgrade", false);
}
};

Expand Down
7 changes: 6 additions & 1 deletion lib/config/normalization.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,12 @@ const getNormalizedWebpackOptions = config => {
experiments: nestedConfig(config.experiments, experiments => ({
...experiments,
buildHttp: optionalNestedConfig(experiments.buildHttp, options =>
options === true ? {} : options
Array.isArray(options) ? { allowedUris: options } : options
),
lazyCompilation: optionalNestedConfig(
experiments.lazyCompilation,
options =>
options === true ? {} : options === false ? undefined : options
)
})),
externals: config.externals,
Expand Down

0 comments on commit ae52a74

Please sign in to comment.