@elementor/externalize-wordpress-assets-webpack-plugin 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/index.d.mts +13 -16
- package/dist/index.d.ts +13 -16
- package/dist/index.js +63 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/index.test.ts.snap +61 -27
- package/src/__tests__/index.test.ts +18 -15
- package/src/index.ts +1 -116
- package/src/plugin.ts +74 -0
- package/src/types.ts +6 -0
- package/src/utils.ts +43 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.3.0](https://github.com/elementor/elementor-packages/compare/@elementor/externalize-wordpress-assets-webpack-plugin@0.2.1...@elementor/externalize-wordpress-assets-webpack-plugin@0.3.0) (2023-07-11)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **webpack-plugins:** simplify logic ([#78](https://github.com/elementor/elementor-packages/issues/78)) ([e4cadc0](https://github.com/elementor/elementor-packages/commit/e4cadc06be61450437274610e65b9d92eb245844))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## 0.2.1 (2023-07-02)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @elementor/externalize-wordpress-assets-webpack-plugin
|
package/dist/index.d.mts
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
import { ExternalsPlugin, Compiler } from 'webpack';
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
externalsMap: ExternalsMap;
|
|
10
|
-
};
|
|
3
|
+
type Global = string | string[];
|
|
4
|
+
type RequestToGlobalMap = Array<{
|
|
5
|
+
request: string | RegExp;
|
|
6
|
+
global: Global;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
11
9
|
type Options = {
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
type: string;
|
|
11
|
+
global?: (entryName: string) => Global;
|
|
12
|
+
map: RequestToGlobalMap;
|
|
14
13
|
};
|
|
15
14
|
declare class ExternalizeWordPressAssetsWebpackPlugin {
|
|
15
|
+
options: Options;
|
|
16
16
|
externalPlugin: ExternalsPlugin;
|
|
17
|
-
options:
|
|
18
|
-
constructor(options: Options);
|
|
17
|
+
constructor(options: Pick<Options, 'map' | 'global'>);
|
|
19
18
|
apply(compiler: Compiler): void;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
kebabToCamelCase(kebabCase: string): string;
|
|
23
|
-
normalizeOptions(options: Options): NormalizedOptions;
|
|
19
|
+
externalsPluginCallback(request: string | undefined, callback: (err?: undefined, result?: Global) => void): void;
|
|
20
|
+
exposeEntry(compiler: Compiler): void;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
export { ExternalizeWordPressAssetsWebpackPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
import { ExternalsPlugin, Compiler } from 'webpack';
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
externalsMap: ExternalsMap;
|
|
10
|
-
};
|
|
3
|
+
type Global = string | string[];
|
|
4
|
+
type RequestToGlobalMap = Array<{
|
|
5
|
+
request: string | RegExp;
|
|
6
|
+
global: Global;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
11
9
|
type Options = {
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
type: string;
|
|
11
|
+
global?: (entryName: string) => Global;
|
|
12
|
+
map: RequestToGlobalMap;
|
|
14
13
|
};
|
|
15
14
|
declare class ExternalizeWordPressAssetsWebpackPlugin {
|
|
15
|
+
options: Options;
|
|
16
16
|
externalPlugin: ExternalsPlugin;
|
|
17
|
-
options:
|
|
18
|
-
constructor(options: Options);
|
|
17
|
+
constructor(options: Pick<Options, 'map' | 'global'>);
|
|
19
18
|
apply(compiler: Compiler): void;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
kebabToCamelCase(kebabCase: string): string;
|
|
23
|
-
normalizeOptions(options: Options): NormalizedOptions;
|
|
19
|
+
externalsPluginCallback(request: string | undefined, callback: (err?: undefined, result?: Global) => void): void;
|
|
20
|
+
exposeEntry(compiler: Compiler): void;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
export { ExternalizeWordPressAssetsWebpackPlugin };
|
package/dist/index.js
CHANGED
|
@@ -23,88 +23,87 @@ __export(src_exports, {
|
|
|
23
23
|
ExternalizeWordPressAssetsWebpackPlugin: () => ExternalizeWordPressAssetsWebpackPlugin
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
|
|
27
|
+
// src/plugin.ts
|
|
26
28
|
var import_webpack = require("webpack");
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
startsWith: {
|
|
33
|
-
"@elementor/": "__UNSTABLE__elementorPackages",
|
|
34
|
-
"@wordpress/": "wp"
|
|
29
|
+
|
|
30
|
+
// src/utils.ts
|
|
31
|
+
function transformRequestToGlobal(request, map) {
|
|
32
|
+
if (!request) {
|
|
33
|
+
return null;
|
|
35
34
|
}
|
|
36
|
-
|
|
35
|
+
for (const item of map) {
|
|
36
|
+
let { request: requestRegex, global } = item;
|
|
37
|
+
if (!(requestRegex instanceof RegExp)) {
|
|
38
|
+
requestRegex = new RegExp(`^${requestRegex}$`);
|
|
39
|
+
}
|
|
40
|
+
const matches = request.match(requestRegex);
|
|
41
|
+
if (matches) {
|
|
42
|
+
return replaceGlobal(global, matches);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function replaceGlobal(global, matches) {
|
|
48
|
+
let result = typeof global === "string" ? [global] : [...global];
|
|
49
|
+
matches.forEach((value, index) => {
|
|
50
|
+
result = result.map((item) => item.replace(`$${index}`, kebabToCamelCase(value)));
|
|
51
|
+
});
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
function kebabToCamelCase(kebabCase) {
|
|
55
|
+
return kebabCase.replace(
|
|
56
|
+
/-(\w)/g,
|
|
57
|
+
(_, w) => w.toUpperCase()
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/plugin.ts
|
|
37
62
|
var ExternalizeWordPressAssetsWebpackPlugin = class {
|
|
38
|
-
externalPlugin;
|
|
39
63
|
options;
|
|
64
|
+
externalPlugin;
|
|
40
65
|
constructor(options) {
|
|
41
|
-
this.options =
|
|
66
|
+
this.options = {
|
|
67
|
+
map: options.map,
|
|
68
|
+
global: options.global,
|
|
69
|
+
type: "window"
|
|
70
|
+
};
|
|
42
71
|
this.externalPlugin = new import_webpack.ExternalsPlugin(
|
|
43
|
-
|
|
44
|
-
({ request }, callback) =>
|
|
45
|
-
const externalRequest = this.requestToExternal(request);
|
|
46
|
-
if (externalRequest) {
|
|
47
|
-
return callback(void 0, externalRequest);
|
|
48
|
-
}
|
|
49
|
-
return callback();
|
|
50
|
-
}
|
|
72
|
+
this.options.type,
|
|
73
|
+
({ request }, callback) => this.externalsPluginCallback(request, callback)
|
|
51
74
|
);
|
|
52
75
|
}
|
|
53
76
|
apply(compiler) {
|
|
54
77
|
this.externalPlugin.apply(compiler);
|
|
55
78
|
compiler.hooks.environment.tap(this.constructor.name, () => {
|
|
56
|
-
this.
|
|
79
|
+
this.exposeEntry(compiler);
|
|
57
80
|
});
|
|
58
81
|
}
|
|
59
|
-
|
|
60
|
-
|
|
82
|
+
externalsPluginCallback(request, callback) {
|
|
83
|
+
const global = transformRequestToGlobal(request, this.options.map);
|
|
84
|
+
if (!global) {
|
|
85
|
+
callback();
|
|
61
86
|
return;
|
|
62
87
|
}
|
|
63
|
-
|
|
64
|
-
if (Object.keys(exact).includes(request)) {
|
|
65
|
-
return exact[request];
|
|
66
|
-
}
|
|
67
|
-
for (const [prefix, globalKey] of Object.entries(startsWith)) {
|
|
68
|
-
if (request.startsWith(prefix)) {
|
|
69
|
-
return [globalKey, this.kebabToCamelCase(request.replace(prefix, ""))];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
exportAsWindowItem(compiler) {
|
|
74
|
-
compiler.options.output.enabledLibraryTypes?.push("window");
|
|
75
|
-
compiler.options.entry = Object.fromEntries(
|
|
76
|
-
Object.entries(compiler.options.entry).map(([name, entry]) => [
|
|
77
|
-
name,
|
|
78
|
-
{
|
|
79
|
-
...entry,
|
|
80
|
-
library: {
|
|
81
|
-
name: [this.options.globalKey, this.kebabToCamelCase(name)],
|
|
82
|
-
type: "window"
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
])
|
|
86
|
-
);
|
|
88
|
+
callback(void 0, global);
|
|
87
89
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
...
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
startsWith: {
|
|
103
|
-
...baseExternalsMap.startsWith,
|
|
104
|
-
...options?.externalsMap?.startsWith || {}
|
|
90
|
+
exposeEntry(compiler) {
|
|
91
|
+
compiler.options.output.enabledLibraryTypes?.push(this.options.type);
|
|
92
|
+
const transformEntryNameToGlobal = this.options.global;
|
|
93
|
+
const entry = compiler.options.entry;
|
|
94
|
+
if (!transformEntryNameToGlobal) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
compiler.options.entry = Object.entries(entry).reduce((carry, [name, entryItem]) => ({
|
|
98
|
+
...carry,
|
|
99
|
+
[name]: {
|
|
100
|
+
...entryItem,
|
|
101
|
+
library: {
|
|
102
|
+
name: transformEntryNameToGlobal(kebabToCamelCase(name)),
|
|
103
|
+
type: this.options.type
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
|
-
};
|
|
106
|
+
}), {});
|
|
108
107
|
}
|
|
109
108
|
};
|
|
110
109
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { ExternalsPlugin, Compiler } from 'webpack';\
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/plugin.ts","../src/utils.ts"],"sourcesContent":["export { default as ExternalizeWordPressAssetsWebpackPlugin } from './plugin';\n","import { ExternalsPlugin, Compiler } from 'webpack';\nimport { kebabToCamelCase, transformRequestToGlobal } from './utils';\nimport { RequestToGlobalMap, Global } from './types';\n\ntype Options = {\n\ttype: string,\n\tglobal?: ( entryName: string ) => Global,\n\tmap: RequestToGlobalMap\n};\n\nexport default class ExternalizeWordPressAssetsWebpackPlugin {\n\toptions: Options;\n\n\texternalPlugin: ExternalsPlugin;\n\n\tconstructor( options: Pick<Options, 'map' | 'global'> ) {\n\t\tthis.options = {\n\t\t\tmap: options.map,\n\t\t\tglobal: options.global,\n\t\t\ttype: 'window',\n\t\t};\n\n\t\tthis.externalPlugin = new ExternalsPlugin(\n\t\t\tthis.options.type,\n\t\t\t( { request }, callback ) => this.externalsPluginCallback( request, callback )\n\t\t);\n\t}\n\n\tapply( compiler: Compiler ) {\n\t\tthis.externalPlugin.apply( compiler );\n\n\t\tcompiler.hooks.environment.tap( this.constructor.name, () => {\n\t\t\tthis.exposeEntry( compiler );\n\t\t} );\n\t}\n\n\texternalsPluginCallback(\n\t\trequest: string | undefined,\n\t\tcallback: ( err?: undefined, result?: Global ) => void\n\t) {\n\t\tconst global = transformRequestToGlobal( request, this.options.map );\n\n\t\tif ( ! global ) {\n\t\t\tcallback();\n\n\t\t\treturn;\n\t\t}\n\n\t\tcallback( undefined, global );\n\t}\n\n\texposeEntry( compiler: Compiler ) {\n\t\tcompiler.options.output.enabledLibraryTypes?.push( this.options.type );\n\n\t\tconst transformEntryNameToGlobal = this.options.global;\n\t\tconst entry = compiler.options.entry;\n\n\t\tif ( ! transformEntryNameToGlobal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcompiler.options.entry = Object.entries( entry )\n\t\t\t.reduce( ( carry, [ name, entryItem ] ) => ( {\n\t\t\t\t...carry,\n\t\t\t\t[ name ]: {\n\t\t\t\t\t...entryItem,\n\t\t\t\t\tlibrary: {\n\t\t\t\t\t\tname: transformEntryNameToGlobal( kebabToCamelCase( name ) ),\n\t\t\t\t\t\ttype: this.options.type,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t} ), {} );\n\t}\n}\n","import { RequestToGlobalMap } from './types';\n\nexport function transformRequestToGlobal( request: string | undefined, map: RequestToGlobalMap ) {\n\tif ( ! request ) {\n\t\treturn null;\n\t}\n\n\tfor ( const item of map ) {\n\t\tlet { request: requestRegex, global } = item;\n\n\t\tif ( ! ( requestRegex instanceof RegExp ) ) {\n\t\t\trequestRegex = new RegExp( `^${ requestRegex }$` );\n\t\t}\n\n\t\tconst matches = request.match( requestRegex );\n\n\t\tif ( matches ) {\n\t\t\treturn replaceGlobal( global, matches );\n\t\t}\n\t}\n\n\treturn null;\n}\n\nexport function replaceGlobal( global: string | string[], matches: RegExpMatchArray ) {\n\tlet result = typeof global === 'string' ? [ global ] : [ ...global ];\n\n\tmatches.forEach( ( value, index ) => {\n\t\t// Replace regex backreferences with capture groups.\n\t\t// The user can set ['something', '$1', 'a', '$2'] in the global, and the backreferences will\n\t\t// be replaced by the matched groups in the regex.\n\t\tresult = result.map( ( item ) => item.replace( `$${ index }`, kebabToCamelCase( value ) ) );\n\t} );\n\n\treturn result;\n}\n\nexport function kebabToCamelCase( kebabCase: string ) {\n\treturn kebabCase.replace(\n\t\t/-(\\w)/g,\n\t\t( _, w: string ) => w.toUpperCase()\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,qBAA0C;;;ACEnC,SAAS,yBAA0B,SAA6B,KAA0B;AAChG,MAAK,CAAE,SAAU;AAChB,WAAO;AAAA,EACR;AAEA,aAAY,QAAQ,KAAM;AACzB,QAAI,EAAE,SAAS,cAAc,OAAO,IAAI;AAExC,QAAK,EAAI,wBAAwB,SAAW;AAC3C,qBAAe,IAAI,OAAQ,IAAK,YAAa,GAAI;AAAA,IAClD;AAEA,UAAM,UAAU,QAAQ,MAAO,YAAa;AAE5C,QAAK,SAAU;AACd,aAAO,cAAe,QAAQ,OAAQ;AAAA,IACvC;AAAA,EACD;AAEA,SAAO;AACR;AAEO,SAAS,cAAe,QAA2B,SAA4B;AACrF,MAAI,SAAS,OAAO,WAAW,WAAW,CAAE,MAAO,IAAI,CAAE,GAAG,MAAO;AAEnE,UAAQ,QAAS,CAAE,OAAO,UAAW;AAIpC,aAAS,OAAO,IAAK,CAAE,SAAU,KAAK,QAAS,IAAK,KAAM,IAAI,iBAAkB,KAAM,CAAE,CAAE;AAAA,EAC3F,CAAE;AAEF,SAAO;AACR;AAEO,SAAS,iBAAkB,WAAoB;AACrD,SAAO,UAAU;AAAA,IAChB;AAAA,IACA,CAAE,GAAG,MAAe,EAAE,YAAY;AAAA,EACnC;AACD;;;ADhCA,IAAqB,0CAArB,MAA6D;AAAA,EAC5D;AAAA,EAEA;AAAA,EAEA,YAAa,SAA2C;AACvD,SAAK,UAAU;AAAA,MACd,KAAK,QAAQ;AAAA,MACb,QAAQ,QAAQ;AAAA,MAChB,MAAM;AAAA,IACP;AAEA,SAAK,iBAAiB,IAAI;AAAA,MACzB,KAAK,QAAQ;AAAA,MACb,CAAE,EAAE,QAAQ,GAAG,aAAc,KAAK,wBAAyB,SAAS,QAAS;AAAA,IAC9E;AAAA,EACD;AAAA,EAEA,MAAO,UAAqB;AAC3B,SAAK,eAAe,MAAO,QAAS;AAEpC,aAAS,MAAM,YAAY,IAAK,KAAK,YAAY,MAAM,MAAM;AAC5D,WAAK,YAAa,QAAS;AAAA,IAC5B,CAAE;AAAA,EACH;AAAA,EAEA,wBACC,SACA,UACC;AACD,UAAM,SAAS,yBAA0B,SAAS,KAAK,QAAQ,GAAI;AAEnE,QAAK,CAAE,QAAS;AACf,eAAS;AAET;AAAA,IACD;AAEA,aAAU,QAAW,MAAO;AAAA,EAC7B;AAAA,EAEA,YAAa,UAAqB;AACjC,aAAS,QAAQ,OAAO,qBAAqB,KAAM,KAAK,QAAQ,IAAK;AAErE,UAAM,6BAA6B,KAAK,QAAQ;AAChD,UAAM,QAAQ,SAAS,QAAQ;AAE/B,QAAK,CAAE,4BAA6B;AACnC;AAAA,IACD;AAEA,aAAS,QAAQ,QAAQ,OAAO,QAAS,KAAM,EAC7C,OAAQ,CAAE,OAAO,CAAE,MAAM,SAAU,OAAS;AAAA,MAC5C,GAAG;AAAA,MACH,CAAE,IAAK,GAAG;AAAA,QACT,GAAG;AAAA,QACH,SAAS;AAAA,UACR,MAAM,2BAA4B,iBAAkB,IAAK,CAAE;AAAA,UAC3D,MAAM,KAAK,QAAQ;AAAA,QACpB;AAAA,MACD;AAAA,IACD,IAAK,CAAC,CAAE;AAAA,EACV;AACD;","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,86 +1,83 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/plugin.ts
|
|
2
2
|
import { ExternalsPlugin } from "webpack";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
startsWith: {
|
|
9
|
-
"@elementor/": "__UNSTABLE__elementorPackages",
|
|
10
|
-
"@wordpress/": "wp"
|
|
3
|
+
|
|
4
|
+
// src/utils.ts
|
|
5
|
+
function transformRequestToGlobal(request, map) {
|
|
6
|
+
if (!request) {
|
|
7
|
+
return null;
|
|
11
8
|
}
|
|
12
|
-
|
|
9
|
+
for (const item of map) {
|
|
10
|
+
let { request: requestRegex, global } = item;
|
|
11
|
+
if (!(requestRegex instanceof RegExp)) {
|
|
12
|
+
requestRegex = new RegExp(`^${requestRegex}$`);
|
|
13
|
+
}
|
|
14
|
+
const matches = request.match(requestRegex);
|
|
15
|
+
if (matches) {
|
|
16
|
+
return replaceGlobal(global, matches);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function replaceGlobal(global, matches) {
|
|
22
|
+
let result = typeof global === "string" ? [global] : [...global];
|
|
23
|
+
matches.forEach((value, index) => {
|
|
24
|
+
result = result.map((item) => item.replace(`$${index}`, kebabToCamelCase(value)));
|
|
25
|
+
});
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
function kebabToCamelCase(kebabCase) {
|
|
29
|
+
return kebabCase.replace(
|
|
30
|
+
/-(\w)/g,
|
|
31
|
+
(_, w) => w.toUpperCase()
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/plugin.ts
|
|
13
36
|
var ExternalizeWordPressAssetsWebpackPlugin = class {
|
|
14
|
-
externalPlugin;
|
|
15
37
|
options;
|
|
38
|
+
externalPlugin;
|
|
16
39
|
constructor(options) {
|
|
17
|
-
this.options =
|
|
40
|
+
this.options = {
|
|
41
|
+
map: options.map,
|
|
42
|
+
global: options.global,
|
|
43
|
+
type: "window"
|
|
44
|
+
};
|
|
18
45
|
this.externalPlugin = new ExternalsPlugin(
|
|
19
|
-
|
|
20
|
-
({ request }, callback) =>
|
|
21
|
-
const externalRequest = this.requestToExternal(request);
|
|
22
|
-
if (externalRequest) {
|
|
23
|
-
return callback(void 0, externalRequest);
|
|
24
|
-
}
|
|
25
|
-
return callback();
|
|
26
|
-
}
|
|
46
|
+
this.options.type,
|
|
47
|
+
({ request }, callback) => this.externalsPluginCallback(request, callback)
|
|
27
48
|
);
|
|
28
49
|
}
|
|
29
50
|
apply(compiler) {
|
|
30
51
|
this.externalPlugin.apply(compiler);
|
|
31
52
|
compiler.hooks.environment.tap(this.constructor.name, () => {
|
|
32
|
-
this.
|
|
53
|
+
this.exposeEntry(compiler);
|
|
33
54
|
});
|
|
34
55
|
}
|
|
35
|
-
|
|
36
|
-
|
|
56
|
+
externalsPluginCallback(request, callback) {
|
|
57
|
+
const global = transformRequestToGlobal(request, this.options.map);
|
|
58
|
+
if (!global) {
|
|
59
|
+
callback();
|
|
37
60
|
return;
|
|
38
61
|
}
|
|
39
|
-
|
|
40
|
-
if (Object.keys(exact).includes(request)) {
|
|
41
|
-
return exact[request];
|
|
42
|
-
}
|
|
43
|
-
for (const [prefix, globalKey] of Object.entries(startsWith)) {
|
|
44
|
-
if (request.startsWith(prefix)) {
|
|
45
|
-
return [globalKey, this.kebabToCamelCase(request.replace(prefix, ""))];
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
exportAsWindowItem(compiler) {
|
|
50
|
-
compiler.options.output.enabledLibraryTypes?.push("window");
|
|
51
|
-
compiler.options.entry = Object.fromEntries(
|
|
52
|
-
Object.entries(compiler.options.entry).map(([name, entry]) => [
|
|
53
|
-
name,
|
|
54
|
-
{
|
|
55
|
-
...entry,
|
|
56
|
-
library: {
|
|
57
|
-
name: [this.options.globalKey, this.kebabToCamelCase(name)],
|
|
58
|
-
type: "window"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
])
|
|
62
|
-
);
|
|
62
|
+
callback(void 0, global);
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
...
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
startsWith: {
|
|
79
|
-
...baseExternalsMap.startsWith,
|
|
80
|
-
...options?.externalsMap?.startsWith || {}
|
|
64
|
+
exposeEntry(compiler) {
|
|
65
|
+
compiler.options.output.enabledLibraryTypes?.push(this.options.type);
|
|
66
|
+
const transformEntryNameToGlobal = this.options.global;
|
|
67
|
+
const entry = compiler.options.entry;
|
|
68
|
+
if (!transformEntryNameToGlobal) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
compiler.options.entry = Object.entries(entry).reduce((carry, [name, entryItem]) => ({
|
|
72
|
+
...carry,
|
|
73
|
+
[name]: {
|
|
74
|
+
...entryItem,
|
|
75
|
+
library: {
|
|
76
|
+
name: transformEntryNameToGlobal(kebabToCamelCase(name)),
|
|
77
|
+
type: this.options.type
|
|
81
78
|
}
|
|
82
79
|
}
|
|
83
|
-
};
|
|
80
|
+
}), {});
|
|
84
81
|
}
|
|
85
82
|
};
|
|
86
83
|
export {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/utils.ts"],"sourcesContent":["import { ExternalsPlugin, Compiler } from 'webpack';\nimport { kebabToCamelCase, transformRequestToGlobal } from './utils';\nimport { RequestToGlobalMap, Global } from './types';\n\ntype Options = {\n\ttype: string,\n\tglobal?: ( entryName: string ) => Global,\n\tmap: RequestToGlobalMap\n};\n\nexport default class ExternalizeWordPressAssetsWebpackPlugin {\n\toptions: Options;\n\n\texternalPlugin: ExternalsPlugin;\n\n\tconstructor( options: Pick<Options, 'map' | 'global'> ) {\n\t\tthis.options = {\n\t\t\tmap: options.map,\n\t\t\tglobal: options.global,\n\t\t\ttype: 'window',\n\t\t};\n\n\t\tthis.externalPlugin = new ExternalsPlugin(\n\t\t\tthis.options.type,\n\t\t\t( { request }, callback ) => this.externalsPluginCallback( request, callback )\n\t\t);\n\t}\n\n\tapply( compiler: Compiler ) {\n\t\tthis.externalPlugin.apply( compiler );\n\n\t\tcompiler.hooks.environment.tap( this.constructor.name, () => {\n\t\t\tthis.exposeEntry( compiler );\n\t\t} );\n\t}\n\n\texternalsPluginCallback(\n\t\trequest: string | undefined,\n\t\tcallback: ( err?: undefined, result?: Global ) => void\n\t) {\n\t\tconst global = transformRequestToGlobal( request, this.options.map );\n\n\t\tif ( ! global ) {\n\t\t\tcallback();\n\n\t\t\treturn;\n\t\t}\n\n\t\tcallback( undefined, global );\n\t}\n\n\texposeEntry( compiler: Compiler ) {\n\t\tcompiler.options.output.enabledLibraryTypes?.push( this.options.type );\n\n\t\tconst transformEntryNameToGlobal = this.options.global;\n\t\tconst entry = compiler.options.entry;\n\n\t\tif ( ! transformEntryNameToGlobal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcompiler.options.entry = Object.entries( entry )\n\t\t\t.reduce( ( carry, [ name, entryItem ] ) => ( {\n\t\t\t\t...carry,\n\t\t\t\t[ name ]: {\n\t\t\t\t\t...entryItem,\n\t\t\t\t\tlibrary: {\n\t\t\t\t\t\tname: transformEntryNameToGlobal( kebabToCamelCase( name ) ),\n\t\t\t\t\t\ttype: this.options.type,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t} ), {} );\n\t}\n}\n","import { RequestToGlobalMap } from './types';\n\nexport function transformRequestToGlobal( request: string | undefined, map: RequestToGlobalMap ) {\n\tif ( ! request ) {\n\t\treturn null;\n\t}\n\n\tfor ( const item of map ) {\n\t\tlet { request: requestRegex, global } = item;\n\n\t\tif ( ! ( requestRegex instanceof RegExp ) ) {\n\t\t\trequestRegex = new RegExp( `^${ requestRegex }$` );\n\t\t}\n\n\t\tconst matches = request.match( requestRegex );\n\n\t\tif ( matches ) {\n\t\t\treturn replaceGlobal( global, matches );\n\t\t}\n\t}\n\n\treturn null;\n}\n\nexport function replaceGlobal( global: string | string[], matches: RegExpMatchArray ) {\n\tlet result = typeof global === 'string' ? [ global ] : [ ...global ];\n\n\tmatches.forEach( ( value, index ) => {\n\t\t// Replace regex backreferences with capture groups.\n\t\t// The user can set ['something', '$1', 'a', '$2'] in the global, and the backreferences will\n\t\t// be replaced by the matched groups in the regex.\n\t\tresult = result.map( ( item ) => item.replace( `$${ index }`, kebabToCamelCase( value ) ) );\n\t} );\n\n\treturn result;\n}\n\nexport function kebabToCamelCase( kebabCase: string ) {\n\treturn kebabCase.replace(\n\t\t/-(\\w)/g,\n\t\t( _, w: string ) => w.toUpperCase()\n\t);\n}\n"],"mappings":";AAAA,SAAS,uBAAiC;;;ACEnC,SAAS,yBAA0B,SAA6B,KAA0B;AAChG,MAAK,CAAE,SAAU;AAChB,WAAO;AAAA,EACR;AAEA,aAAY,QAAQ,KAAM;AACzB,QAAI,EAAE,SAAS,cAAc,OAAO,IAAI;AAExC,QAAK,EAAI,wBAAwB,SAAW;AAC3C,qBAAe,IAAI,OAAQ,IAAK,YAAa,GAAI;AAAA,IAClD;AAEA,UAAM,UAAU,QAAQ,MAAO,YAAa;AAE5C,QAAK,SAAU;AACd,aAAO,cAAe,QAAQ,OAAQ;AAAA,IACvC;AAAA,EACD;AAEA,SAAO;AACR;AAEO,SAAS,cAAe,QAA2B,SAA4B;AACrF,MAAI,SAAS,OAAO,WAAW,WAAW,CAAE,MAAO,IAAI,CAAE,GAAG,MAAO;AAEnE,UAAQ,QAAS,CAAE,OAAO,UAAW;AAIpC,aAAS,OAAO,IAAK,CAAE,SAAU,KAAK,QAAS,IAAK,KAAM,IAAI,iBAAkB,KAAM,CAAE,CAAE;AAAA,EAC3F,CAAE;AAEF,SAAO;AACR;AAEO,SAAS,iBAAkB,WAAoB;AACrD,SAAO,UAAU;AAAA,IAChB;AAAA,IACA,CAAE,GAAG,MAAe,EAAE,YAAY;AAAA,EACnC;AACD;;;ADhCA,IAAqB,0CAArB,MAA6D;AAAA,EAC5D;AAAA,EAEA;AAAA,EAEA,YAAa,SAA2C;AACvD,SAAK,UAAU;AAAA,MACd,KAAK,QAAQ;AAAA,MACb,QAAQ,QAAQ;AAAA,MAChB,MAAM;AAAA,IACP;AAEA,SAAK,iBAAiB,IAAI;AAAA,MACzB,KAAK,QAAQ;AAAA,MACb,CAAE,EAAE,QAAQ,GAAG,aAAc,KAAK,wBAAyB,SAAS,QAAS;AAAA,IAC9E;AAAA,EACD;AAAA,EAEA,MAAO,UAAqB;AAC3B,SAAK,eAAe,MAAO,QAAS;AAEpC,aAAS,MAAM,YAAY,IAAK,KAAK,YAAY,MAAM,MAAM;AAC5D,WAAK,YAAa,QAAS;AAAA,IAC5B,CAAE;AAAA,EACH;AAAA,EAEA,wBACC,SACA,UACC;AACD,UAAM,SAAS,yBAA0B,SAAS,KAAK,QAAQ,GAAI;AAEnE,QAAK,CAAE,QAAS;AACf,eAAS;AAET;AAAA,IACD;AAEA,aAAU,QAAW,MAAO;AAAA,EAC7B;AAAA,EAEA,YAAa,UAAqB;AACjC,aAAS,QAAQ,OAAO,qBAAqB,KAAM,KAAK,QAAQ,IAAK;AAErE,UAAM,6BAA6B,KAAK,QAAQ;AAChD,UAAM,QAAQ,SAAS,QAAQ;AAE/B,QAAK,CAAE,4BAA6B;AACnC;AAAA,IACD;AAEA,aAAS,QAAQ,QAAQ,OAAO,QAAS,KAAM,EAC7C,OAAQ,CAAE,OAAO,CAAE,MAAM,SAAU,OAAS;AAAA,MAC5C,GAAG;AAAA,MACH,CAAE,IAAK,GAAG;AAAA,QACT,GAAG;AAAA,QACH,SAAS;AAAA,UACR,MAAM,2BAA4B,iBAAkB,IAAK,CAAE;AAAA,UAC3D,MAAM,KAAK,QAAQ;AAAA,QACpB;AAAA,MACD;AAAA,IACD,IAAK,CAAC,CAAE;AAAA,EACV;AACD;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/externalize-wordpress-assets-webpack-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"webpack": "5.x"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "7fd9a516887f8bdb3479c54a48dafcb12bb41db7"
|
|
38
38
|
}
|
|
@@ -2,15 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`@elementor/externalize-wordpress-assets-webpack-plugin should externalize Elementor & WordPress assets 1`] = `
|
|
4
4
|
""use strict";
|
|
5
|
-
|
|
6
|
-
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
7
|
-
* This devtool is neither made for production nor for readable output files.
|
|
8
|
-
* It uses "eval()" calls to create a separate source file in the browser devtools.
|
|
9
|
-
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
|
10
|
-
* or disable the default devtool with "devtool: false".
|
|
11
|
-
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
|
12
|
-
*/
|
|
13
|
-
(self["webpackChunk"] = self["webpackChunk"] || []).push([["app"],{
|
|
5
|
+
(self["webpackChunk"] = self["webpackChunk"] || []).push([["my-app-test"],{
|
|
14
6
|
|
|
15
7
|
/***/ "./.":
|
|
16
8
|
/*!***********!*\\
|
|
@@ -18,14 +10,46 @@ exports[`@elementor/externalize-wordpress-assets-webpack-plugin should externali
|
|
|
18
10
|
\\***********/
|
|
19
11
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
20
12
|
|
|
21
|
-
|
|
13
|
+
__webpack_require__.r(__webpack_exports__);
|
|
14
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
15
|
+
/* harmony export */ test: () => (/* binding */ test)
|
|
16
|
+
/* harmony export */ });
|
|
17
|
+
/* harmony import */ var _elementor_editor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @elementor/editor */ "@elementor/editor");
|
|
18
|
+
/* harmony import */ var _elementor_editor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor__WEBPACK_IMPORTED_MODULE_0__);
|
|
19
|
+
/* harmony import */ var _elementor_editor_panels__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @elementor/editor-panels */ "@elementor/editor-panels");
|
|
20
|
+
/* harmony import */ var _elementor_editor_panels__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_elementor_editor_panels__WEBPACK_IMPORTED_MODULE_1__);
|
|
21
|
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
|
22
|
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_2__);
|
|
23
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react */ "react");
|
|
24
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
|
|
25
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react-dom */ "react-dom");
|
|
26
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_4__);
|
|
27
|
+
/* harmony import */ var _other_package_name__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @other/package-name */ "@other/package-name");
|
|
28
|
+
/* harmony import */ var _other_package_name__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_other_package_name__WEBPACK_IMPORTED_MODULE_5__);
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
_elementor_editor__WEBPACK_IMPORTED_MODULE_0___default()();
|
|
38
|
+
_elementor_editor_panels__WEBPACK_IMPORTED_MODULE_1___default()();
|
|
39
|
+
_wordpress_element__WEBPACK_IMPORTED_MODULE_2___default()();
|
|
40
|
+
react__WEBPACK_IMPORTED_MODULE_3___default()();
|
|
41
|
+
react_dom__WEBPACK_IMPORTED_MODULE_4___default()();
|
|
42
|
+
_other_package_name__WEBPACK_IMPORTED_MODULE_5___default()();
|
|
43
|
+
|
|
44
|
+
const test = 'This is test for exporting something';
|
|
45
|
+
|
|
22
46
|
|
|
23
47
|
/***/ }),
|
|
24
48
|
|
|
25
49
|
/***/ "react":
|
|
26
|
-
|
|
27
|
-
!*** external "React" ***!
|
|
28
|
-
|
|
50
|
+
/*!**************************!*\\
|
|
51
|
+
!*** external ["React"] ***!
|
|
52
|
+
\\**************************/
|
|
29
53
|
/***/ ((module) => {
|
|
30
54
|
|
|
31
55
|
module.exports = window["React"];
|
|
@@ -33,32 +57,42 @@ module.exports = window["React"];
|
|
|
33
57
|
/***/ }),
|
|
34
58
|
|
|
35
59
|
/***/ "react-dom":
|
|
36
|
-
|
|
37
|
-
!*** external "ReactDOM" ***!
|
|
38
|
-
|
|
60
|
+
/*!*****************************!*\\
|
|
61
|
+
!*** external ["ReactDOM"] ***!
|
|
62
|
+
\\*****************************/
|
|
39
63
|
/***/ ((module) => {
|
|
40
64
|
|
|
41
65
|
module.exports = window["ReactDOM"];
|
|
42
66
|
|
|
43
67
|
/***/ }),
|
|
44
68
|
|
|
45
|
-
/***/ "@
|
|
46
|
-
|
|
47
|
-
!*** external "
|
|
48
|
-
|
|
69
|
+
/***/ "@elementor/editor":
|
|
70
|
+
/*!***********************************************!*\\
|
|
71
|
+
!*** external ["elementorPackages","editor"] ***!
|
|
72
|
+
\\***********************************************/
|
|
49
73
|
/***/ ((module) => {
|
|
50
74
|
|
|
51
|
-
module.exports = window["
|
|
75
|
+
module.exports = window["elementorPackages"]["editor"];
|
|
52
76
|
|
|
53
77
|
/***/ }),
|
|
54
78
|
|
|
55
|
-
/***/ "@elementor/editor":
|
|
56
|
-
|
|
57
|
-
!*** external ["
|
|
58
|
-
|
|
79
|
+
/***/ "@elementor/editor-panels":
|
|
80
|
+
/*!*****************************************************!*\\
|
|
81
|
+
!*** external ["elementorPackages","editorPanels"] ***!
|
|
82
|
+
\\*****************************************************/
|
|
59
83
|
/***/ ((module) => {
|
|
60
84
|
|
|
61
|
-
module.exports = window["
|
|
85
|
+
module.exports = window["elementorPackages"]["editorPanels"];
|
|
86
|
+
|
|
87
|
+
/***/ }),
|
|
88
|
+
|
|
89
|
+
/***/ "@other/package-name":
|
|
90
|
+
/*!*************************************!*\\
|
|
91
|
+
!*** external ["otherPackageName"] ***!
|
|
92
|
+
\\*************************************/
|
|
93
|
+
/***/ ((module) => {
|
|
94
|
+
|
|
95
|
+
module.exports = window["otherPackageName"];
|
|
62
96
|
|
|
63
97
|
/***/ }),
|
|
64
98
|
|
|
@@ -76,7 +110,7 @@ module.exports = window["wp"]["element"];
|
|
|
76
110
|
/******/ __webpack_require__ => { // webpackRuntimeModules
|
|
77
111
|
/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
|
|
78
112
|
/******/ var __webpack_exports__ = (__webpack_exec__("./."));
|
|
79
|
-
/******/ (window.
|
|
113
|
+
/******/ (window.elementorPackages = window.elementorPackages || {}).myAppTest = __webpack_exports__;
|
|
80
114
|
/******/ }
|
|
81
115
|
]);"
|
|
82
116
|
`;
|
|
@@ -13,17 +13,21 @@ jest.mock( 'fs', () => jest.requireActual( 'memfs' ) );
|
|
|
13
13
|
describe( '@elementor/externalize-wordpress-assets-webpack-plugin', () => {
|
|
14
14
|
beforeEach( () => {
|
|
15
15
|
const fileContent = `
|
|
16
|
-
import
|
|
16
|
+
import editor from '@elementor/editor';
|
|
17
|
+
import editorPanels from '@elementor/editor-panels';
|
|
17
18
|
import wp from '@wordpress/element';
|
|
18
19
|
import React from 'react';
|
|
19
20
|
import ReactDOM from 'react-dom';
|
|
20
21
|
import other from '@other/package-name';
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
editor();
|
|
24
|
+
editorPanels();
|
|
23
25
|
wp();
|
|
24
26
|
React();
|
|
25
27
|
ReactDOM();
|
|
26
28
|
other();
|
|
29
|
+
|
|
30
|
+
export const test = 'This is test for exporting something';
|
|
27
31
|
`;
|
|
28
32
|
|
|
29
33
|
fs.writeFileSync( path.resolve( '/app.js' ), fileContent );
|
|
@@ -37,25 +41,24 @@ describe( '@elementor/externalize-wordpress-assets-webpack-plugin', () => {
|
|
|
37
41
|
// Arrange.
|
|
38
42
|
const compiler = webpack( {
|
|
39
43
|
mode: 'development',
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
},
|
|
44
|
+
devtool: false,
|
|
45
|
+
entry: { 'my-app-test': path.resolve( '/app.js' ) },
|
|
43
46
|
context: path.resolve( '/app.js' ),
|
|
44
|
-
optimization: {
|
|
45
|
-
runtimeChunk: 'single',
|
|
46
|
-
},
|
|
47
|
+
optimization: { runtimeChunk: 'single' },
|
|
47
48
|
output: {
|
|
48
49
|
filename: '[name].js',
|
|
49
50
|
path: path.resolve( '/dist' ),
|
|
50
51
|
},
|
|
51
52
|
plugins: [
|
|
52
53
|
new ExternalizeWordPressAssetsWebpackPlugin( {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
},
|
|
58
|
-
|
|
54
|
+
global: ( entryName ) => [ 'elementorPackages', entryName ],
|
|
55
|
+
map: [
|
|
56
|
+
{ request: 'react', global: 'React' },
|
|
57
|
+
{ request: 'react-dom', global: 'ReactDOM' },
|
|
58
|
+
{ request: /^@elementor\/(.+)$/, global: [ 'elementorPackages', '$1' ] },
|
|
59
|
+
{ request: /^@wordpress\/(.+)$/, global: [ 'wp', '$1' ] },
|
|
60
|
+
{ request: '@other/package-name', global: 'otherPackageName' },
|
|
61
|
+
],
|
|
59
62
|
} ),
|
|
60
63
|
],
|
|
61
64
|
} );
|
|
@@ -70,7 +73,7 @@ describe( '@elementor/externalize-wordpress-assets-webpack-plugin', () => {
|
|
|
70
73
|
expect( stats?.hasErrors() ).toBe( false );
|
|
71
74
|
expect( stats?.hasWarnings() ).toBe( false );
|
|
72
75
|
|
|
73
|
-
const fileContent = fs.readFileSync( path.resolve( `/dist/app.js` ), { encoding: 'utf8' } );
|
|
76
|
+
const fileContent = fs.readFileSync( path.resolve( `/dist/my-app-test.js` ), { encoding: 'utf8' } );
|
|
74
77
|
|
|
75
78
|
expect( fileContent ).toMatchSnapshot();
|
|
76
79
|
|
package/src/index.ts
CHANGED
|
@@ -1,116 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type ExternalsMap = {
|
|
4
|
-
exact: Record<string, string>;
|
|
5
|
-
startsWith: Record<string, string>;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
type NormalizedOptions = {
|
|
9
|
-
globalKey: string,
|
|
10
|
-
externalsMap: ExternalsMap
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type Options = {
|
|
14
|
-
globalKey: string,
|
|
15
|
-
externalsMap?: Partial<ExternalsMap>
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const baseExternalsMap: ExternalsMap = {
|
|
19
|
-
exact: {
|
|
20
|
-
react: 'React',
|
|
21
|
-
'react-dom': 'ReactDOM',
|
|
22
|
-
},
|
|
23
|
-
startsWith: {
|
|
24
|
-
'@elementor/': '__UNSTABLE__elementorPackages',
|
|
25
|
-
'@wordpress/': 'wp',
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export class ExternalizeWordPressAssetsWebpackPlugin {
|
|
30
|
-
externalPlugin: ExternalsPlugin;
|
|
31
|
-
|
|
32
|
-
options: NormalizedOptions;
|
|
33
|
-
|
|
34
|
-
constructor( options: Options ) {
|
|
35
|
-
this.options = this.normalizeOptions( options );
|
|
36
|
-
|
|
37
|
-
this.externalPlugin = new ExternalsPlugin(
|
|
38
|
-
'window',
|
|
39
|
-
( { request }, callback ) => {
|
|
40
|
-
const externalRequest = this.requestToExternal( request );
|
|
41
|
-
|
|
42
|
-
if ( externalRequest ) {
|
|
43
|
-
return callback( undefined, externalRequest );
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return callback();
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
apply( compiler: Compiler ) {
|
|
52
|
-
this.externalPlugin.apply( compiler );
|
|
53
|
-
|
|
54
|
-
compiler.hooks.environment.tap( this.constructor.name, () => {
|
|
55
|
-
this.exportAsWindowItem( compiler );
|
|
56
|
-
} );
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
requestToExternal( request?: string ) {
|
|
60
|
-
if ( ! request ) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const { exact, startsWith } = this.options.externalsMap;
|
|
65
|
-
|
|
66
|
-
if ( Object.keys( exact ).includes( request ) ) {
|
|
67
|
-
return exact[ request ];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
for ( const [ prefix, globalKey ] of Object.entries( startsWith ) ) {
|
|
71
|
-
if ( request.startsWith( prefix ) ) {
|
|
72
|
-
return [ globalKey, this.kebabToCamelCase( request.replace( prefix, '' ) ) ];
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
exportAsWindowItem( compiler: Compiler ) {
|
|
78
|
-
compiler.options.output.enabledLibraryTypes?.push( 'window' );
|
|
79
|
-
|
|
80
|
-
compiler.options.entry = Object.fromEntries(
|
|
81
|
-
Object.entries( compiler.options.entry ).map( ( [ name, entry ] ) => [
|
|
82
|
-
name,
|
|
83
|
-
{
|
|
84
|
-
...entry,
|
|
85
|
-
library: {
|
|
86
|
-
name: [ this.options.globalKey, this.kebabToCamelCase( name ) ],
|
|
87
|
-
type: 'window',
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
] )
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
kebabToCamelCase( kebabCase: string ) {
|
|
95
|
-
return kebabCase.replace(
|
|
96
|
-
/-(\w)/g,
|
|
97
|
-
( _, w: string ) => w.toUpperCase()
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
normalizeOptions( options: Options ): NormalizedOptions {
|
|
102
|
-
return {
|
|
103
|
-
...( options || {} ),
|
|
104
|
-
externalsMap: {
|
|
105
|
-
exact: {
|
|
106
|
-
...baseExternalsMap.exact,
|
|
107
|
-
...( options?.externalsMap?.exact || {} ),
|
|
108
|
-
},
|
|
109
|
-
startsWith: {
|
|
110
|
-
...baseExternalsMap.startsWith,
|
|
111
|
-
...( options?.externalsMap?.startsWith || {} ),
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
}
|
|
1
|
+
export { default as ExternalizeWordPressAssetsWebpackPlugin } from './plugin';
|
package/src/plugin.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ExternalsPlugin, Compiler } from 'webpack';
|
|
2
|
+
import { kebabToCamelCase, transformRequestToGlobal } from './utils';
|
|
3
|
+
import { RequestToGlobalMap, Global } from './types';
|
|
4
|
+
|
|
5
|
+
type Options = {
|
|
6
|
+
type: string,
|
|
7
|
+
global?: ( entryName: string ) => Global,
|
|
8
|
+
map: RequestToGlobalMap
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default class ExternalizeWordPressAssetsWebpackPlugin {
|
|
12
|
+
options: Options;
|
|
13
|
+
|
|
14
|
+
externalPlugin: ExternalsPlugin;
|
|
15
|
+
|
|
16
|
+
constructor( options: Pick<Options, 'map' | 'global'> ) {
|
|
17
|
+
this.options = {
|
|
18
|
+
map: options.map,
|
|
19
|
+
global: options.global,
|
|
20
|
+
type: 'window',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
this.externalPlugin = new ExternalsPlugin(
|
|
24
|
+
this.options.type,
|
|
25
|
+
( { request }, callback ) => this.externalsPluginCallback( request, callback )
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
apply( compiler: Compiler ) {
|
|
30
|
+
this.externalPlugin.apply( compiler );
|
|
31
|
+
|
|
32
|
+
compiler.hooks.environment.tap( this.constructor.name, () => {
|
|
33
|
+
this.exposeEntry( compiler );
|
|
34
|
+
} );
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
externalsPluginCallback(
|
|
38
|
+
request: string | undefined,
|
|
39
|
+
callback: ( err?: undefined, result?: Global ) => void
|
|
40
|
+
) {
|
|
41
|
+
const global = transformRequestToGlobal( request, this.options.map );
|
|
42
|
+
|
|
43
|
+
if ( ! global ) {
|
|
44
|
+
callback();
|
|
45
|
+
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
callback( undefined, global );
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
exposeEntry( compiler: Compiler ) {
|
|
53
|
+
compiler.options.output.enabledLibraryTypes?.push( this.options.type );
|
|
54
|
+
|
|
55
|
+
const transformEntryNameToGlobal = this.options.global;
|
|
56
|
+
const entry = compiler.options.entry;
|
|
57
|
+
|
|
58
|
+
if ( ! transformEntryNameToGlobal ) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
compiler.options.entry = Object.entries( entry )
|
|
63
|
+
.reduce( ( carry, [ name, entryItem ] ) => ( {
|
|
64
|
+
...carry,
|
|
65
|
+
[ name ]: {
|
|
66
|
+
...entryItem,
|
|
67
|
+
library: {
|
|
68
|
+
name: transformEntryNameToGlobal( kebabToCamelCase( name ) ),
|
|
69
|
+
type: this.options.type,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
} ), {} );
|
|
73
|
+
}
|
|
74
|
+
}
|
package/src/types.ts
ADDED
package/src/utils.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { RequestToGlobalMap } from './types';
|
|
2
|
+
|
|
3
|
+
export function transformRequestToGlobal( request: string | undefined, map: RequestToGlobalMap ) {
|
|
4
|
+
if ( ! request ) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
for ( const item of map ) {
|
|
9
|
+
let { request: requestRegex, global } = item;
|
|
10
|
+
|
|
11
|
+
if ( ! ( requestRegex instanceof RegExp ) ) {
|
|
12
|
+
requestRegex = new RegExp( `^${ requestRegex }$` );
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const matches = request.match( requestRegex );
|
|
16
|
+
|
|
17
|
+
if ( matches ) {
|
|
18
|
+
return replaceGlobal( global, matches );
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function replaceGlobal( global: string | string[], matches: RegExpMatchArray ) {
|
|
26
|
+
let result = typeof global === 'string' ? [ global ] : [ ...global ];
|
|
27
|
+
|
|
28
|
+
matches.forEach( ( value, index ) => {
|
|
29
|
+
// Replace regex backreferences with capture groups.
|
|
30
|
+
// The user can set ['something', '$1', 'a', '$2'] in the global, and the backreferences will
|
|
31
|
+
// be replaced by the matched groups in the regex.
|
|
32
|
+
result = result.map( ( item ) => item.replace( `$${ index }`, kebabToCamelCase( value ) ) );
|
|
33
|
+
} );
|
|
34
|
+
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function kebabToCamelCase( kebabCase: string ) {
|
|
39
|
+
return kebabCase.replace(
|
|
40
|
+
/-(\w)/g,
|
|
41
|
+
( _, w: string ) => w.toUpperCase()
|
|
42
|
+
);
|
|
43
|
+
}
|