Add typings for various library template plugins

This commit is contained in:
Florent Cailhol 2018-05-09 11:32:06 +02:00
parent eda273d579
commit ed9d0246d5
5 changed files with 141 additions and 44 deletions

View File

@ -8,11 +8,21 @@
const { ConcatSource } = require("webpack-sources");
const Template = require("./Template");
/** @typedef {import("./Compilation")} Compilation */
class AmdMainTemplatePlugin {
/**
* @param {string} name the library name
*/
constructor(name) {
/** @type {string} */
this.name = name;
}
/**
* @param {Compilation} compilation the compilation instance
* @returns {void}
*/
apply(compilation) {
const { mainTemplate, chunkTemplate } = compilation;

View File

@ -6,15 +6,28 @@
const { ConcatSource } = require("webpack-sources");
/** @typedef {import("./Compilation")} Compilation */
/**
* @param {string[]} accessor the accessor to convert to path
* @returns {string} the path
*/
const accessorToObjectAccess = accessor => {
return accessor.map(a => `[${JSON.stringify(a)}]`).join("");
};
class ExportPropertyMainTemplatePlugin {
/**
* @param {string|string[]} property the name of the property to export
*/
constructor(property) {
this.property = property;
}
/**
* @param {Compilation} compilation the compilation instance
* @returns {void}
*/
apply(compilation) {
const { mainTemplate, chunkTemplate } = compilation;

View File

@ -6,30 +6,45 @@
const SetVarMainTemplatePlugin = require("./SetVarMainTemplatePlugin");
/** @typedef {import("./Compiler")} Compiler */
/**
* @param {string[]} accessor the accessor to convert to path
* @returns {string} the path
*/
const accessorToObjectAccess = accessor => {
return accessor
.map(a => {
return `[${JSON.stringify(a)}]`;
})
.join("");
return accessor.map(a => `[${JSON.stringify(a)}]`).join("");
};
const accessorAccess = (base, accessor, joinWith) => {
accessor = [].concat(accessor);
return accessor
.map((a, idx) => {
a = base
? base + accessorToObjectAccess(accessor.slice(0, idx + 1))
: accessor[0] + accessorToObjectAccess(accessor.slice(1, idx + 1));
if (idx === accessor.length - 1) return a;
/**
* @param {string=} base the path prefix
* @param {string|string[]} accessor the accessor
* @param {string=} joinWith the element separator
* @returns {string} the path
*/
const accessorAccess = (base, accessor, joinWith = "; ") => {
const accessors = Array.isArray(accessor) ? accessor : [accessor];
return accessors
.map((_, idx) => {
const a = base
? base + accessorToObjectAccess(accessors.slice(0, idx + 1))
: accessors[0] + accessorToObjectAccess(accessors.slice(1, idx + 1));
if (idx === accessors.length - 1) return a;
if (idx === 0 && typeof base === "undefined")
return `${a} = typeof ${a} === "object" ? ${a} : {}`;
return `${a} = ${a} || {}`;
})
.join(joinWith || "; ");
.join(joinWith);
};
class LibraryTemplatePlugin {
/**
* @param {string} name name of library
* @param {string} target type of library
* @param {boolean} umdNamedDefine setting this to true will name the UMD module
* @param {string|TODO} auxiliaryComment comment in the UMD wrapper
* @param {string|string[]} exportProperty which export should be exposed as library
*/
constructor(name, target, umdNamedDefine, auxiliaryComment, exportProperty) {
this.name = name;
this.target = target;
@ -38,10 +53,14 @@ class LibraryTemplatePlugin {
this.exportProperty = exportProperty;
}
/**
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
compiler.hooks.thisCompilation.tap("LibraryTemplatePlugin", compilation => {
if (this.exportProperty) {
var ExportPropertyMainTemplatePlugin = require("./ExportPropertyMainTemplatePlugin");
const ExportPropertyMainTemplatePlugin = require("./ExportPropertyMainTemplatePlugin");
new ExportPropertyMainTemplatePlugin(this.exportProperty).apply(
compilation
);
@ -49,66 +68,80 @@ class LibraryTemplatePlugin {
switch (this.target) {
case "var":
new SetVarMainTemplatePlugin(
`var ${accessorAccess(false, this.name)}`
`var ${accessorAccess(undefined, this.name)}`,
false
).apply(compilation);
break;
case "assign":
new SetVarMainTemplatePlugin(
accessorAccess(undefined, this.name)
accessorAccess(undefined, this.name),
false
).apply(compilation);
break;
case "this":
case "self":
case "window":
if (this.name)
if (this.name) {
new SetVarMainTemplatePlugin(
accessorAccess(this.target, this.name)
accessorAccess(this.target, this.name),
false
).apply(compilation);
else
} else {
new SetVarMainTemplatePlugin(this.target, true).apply(compilation);
}
break;
case "global":
if (this.name)
if (this.name) {
new SetVarMainTemplatePlugin(
accessorAccess(
compilation.runtimeTemplate.outputOptions.globalObject,
this.name
)
),
false
).apply(compilation);
else
} else {
new SetVarMainTemplatePlugin(
compilation.runtimeTemplate.outputOptions.globalObject,
true
).apply(compilation);
}
break;
case "commonjs":
if (this.name)
if (this.name) {
new SetVarMainTemplatePlugin(
accessorAccess("exports", this.name)
accessorAccess("exports", this.name),
false
).apply(compilation);
else new SetVarMainTemplatePlugin("exports", true).apply(compilation);
} else {
new SetVarMainTemplatePlugin("exports", true).apply(compilation);
}
break;
case "commonjs2":
case "commonjs-module":
new SetVarMainTemplatePlugin("module.exports").apply(compilation);
new SetVarMainTemplatePlugin("module.exports", false).apply(
compilation
);
break;
case "amd":
var AmdMainTemplatePlugin = require("./AmdMainTemplatePlugin");
case "amd": {
const AmdMainTemplatePlugin = require("./AmdMainTemplatePlugin");
new AmdMainTemplatePlugin(this.name).apply(compilation);
break;
}
case "umd":
case "umd2":
var UmdMainTemplatePlugin = require("./UmdMainTemplatePlugin");
case "umd2": {
const UmdMainTemplatePlugin = require("./UmdMainTemplatePlugin");
new UmdMainTemplatePlugin(this.name, {
optionalAmdExternalAsGlobal: this.target === "umd2",
namedDefine: this.umdNamedDefine,
auxiliaryComment: this.auxiliaryComment
}).apply(compilation);
break;
case "jsonp":
var JsonpExportMainTemplatePlugin = require("./web/JsonpExportMainTemplatePlugin");
}
case "jsonp": {
const JsonpExportMainTemplatePlugin = require("./web/JsonpExportMainTemplatePlugin");
new JsonpExportMainTemplatePlugin(this.name).apply(compilation);
break;
}
default:
throw new Error(`${this.target} is not a valid Library target`);
}

View File

@ -6,12 +6,24 @@
const { ConcatSource } = require("webpack-sources");
/** @typedef {import("./Compilation")} Compilation */
class SetVarMainTemplatePlugin {
/**
* @param {string} varExpression the accessor where the library is exported
* @param {boolean} copyObject specify copying the exports
*/
constructor(varExpression, copyObject) {
/** @type {string} */
this.varExpression = varExpression;
/** @type {boolean} */
this.copyObject = copyObject;
}
/**
* @param {Compilation} compilation the compilation instance
* @returns {void}
*/
apply(compilation) {
const { mainTemplate, chunkTemplate } = compilation;

View File

@ -7,22 +7,47 @@
const { ConcatSource, OriginalSource } = require("webpack-sources");
const Template = require("./Template");
function accessorToObjectAccess(accessor) {
return accessor.map(a => `[${JSON.stringify(a)}]`).join("");
}
/** @typedef {import("./Compilation")} Compilation */
function accessorAccess(base, accessor) {
accessor = [].concat(accessor);
return accessor
.map((a, idx) => {
a = base + accessorToObjectAccess(accessor.slice(0, idx + 1));
if (idx === accessor.length - 1) return a;
/**
* @param {string[]} accessor the accessor to convert to path
* @returns {string} the path
*/
const accessorToObjectAccess = accessor => {
return accessor.map(a => `[${JSON.stringify(a)}]`).join("");
};
/**
* @param {string=} base the path prefix
* @param {string|string[]} accessor the accessor
* @param {string=} joinWith the element separator
* @returns {string} the path
*/
const accessorAccess = (base, accessor, joinWith = "; ") => {
const accessors = Array.isArray(accessor) ? accessor : [accessor];
return accessors
.map((_, idx) => {
const a = base
? base + accessorToObjectAccess(accessors.slice(0, idx + 1))
: accessors[0] + accessorToObjectAccess(accessors.slice(1, idx + 1));
if (idx === accessors.length - 1) return a;
if (idx === 0 && typeof base === "undefined")
return `${a} = typeof ${a} === "object" ? ${a} : {}`;
return `${a} = ${a} || {}`;
})
.join(", ");
}
.join(joinWith);
};
/**
* @typedef {string | string[] | {[k: string]: string | string[]}} UmdMainTemplatePluginName
* @typedef {{optionalAmdExternalAsGlobal: boolean, namedDefine: boolean, auxiliaryComment: TODO}} UmdMainTemplatePluginOption
*/
class UmdMainTemplatePlugin {
/**
* @param {UmdMainTemplatePluginName} name the name of the UMD library
* @param {UmdMainTemplatePluginOption} options the plugin option
*/
constructor(name, options) {
if (typeof name === "object" && !Array.isArray(name)) {
this.name = name.root || name.amd || name.commonjs;
@ -40,6 +65,10 @@ class UmdMainTemplatePlugin {
this.auxiliaryComment = options.auxiliaryComment;
}
/**
* @param {Compilation} compilation the compilation instance
* @returns {void}
*/
apply(compilation) {
const { mainTemplate, chunkTemplate, runtimeTemplate } = compilation;