-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebpack.config.js
More file actions
139 lines (123 loc) · 5.03 KB
/
Copy pathwebpack.config.js
File metadata and controls
139 lines (123 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
const defaultConfig = require("@wordpress/scripts/config/webpack.config");
const fs = require("fs");
const path = require("path");
/**
* Plugin to fix @wordpress/interactivity imports after each compilation.
* In dev mode: uses source files directly with ES6 imports.
* In prod mode: fixes the minified webpack output.
*/
class FixInteractivityPlugin {
apply(compiler) {
compiler.hooks.afterEmit.tap("FixInteractivityPlugin", () => {
const isProduction = compiler.options.mode === "production";
this.fixViewFiles(isProduction);
});
}
fixViewFiles(isProduction) {
const blocks = [
{ name: "alert", imports: ["store", "getContext"] },
{ name: "drawer", imports: ["store", "getContext"] },
{ name: "tooltip", imports: ["store", "getContext"] },
{ name: "sheet", imports: ["store", "getContext"] },
{ name: "accordion", imports: ["store", "getContext"] },
{ name: "sonner", imports: ["store", "getContext"] },
{ name: "tabs", imports: ["store", "getContext"] },
{ name: "pricing", imports: ["store", "getContext"] },
{ name: "live-purchase", imports: ["store", "getContext"] },
];
blocks.forEach(({ name, imports }) => {
const buildPath = path.join(__dirname, `build/blocks/${name}/view.js`);
const srcPath = path.join(__dirname, `src/blocks/${name}/view.js`);
if (!fs.existsSync(buildPath)) return;
let content = fs.readFileSync(buildPath, "utf8");
// Skip if already fixed
if (content.startsWith("import {")) return;
const importStatement = `import { ${imports.join(
", "
)} } from '@wordpress/interactivity';\n`;
if (isProduction) {
// Production: fix minified webpack output
content = content.replace(/\(\(\)=>\{import[^;]+;\s*/, "(()=>{");
content = importStatement + content;
// Drop the `const x = window.wp.interactivity` binding the dependency
// extraction inserts, now that the real ES import is back at the top.
//
// The terminator decides how much to drop. Minified output merges
// consecutive declarations, so a view file with its own module-level
// constants emits `const e=window.wp.interactivity,t="KEY",...`. Eating
// the whole match there would take the `const` keyword with it and
// leave `t="KEY"` as a bare assignment — which in strict mode throws
// `ReferenceError: t is not defined` at load, killing the block. A
// trailing comma therefore keeps `const `, while a `;` (or nothing)
// means the binding stood alone and the statement goes entirely.
content = content.replace(
/const\s+\w+\s*=\s*window\.wp\.interactivity(\s*[,;])?\s*/g,
(match, terminator) => {
if (terminator && terminator.trim() === ",") {
return "const ";
}
// Some blocks re-declare below and need the keyword preserved.
return ["drawer", "tooltip", "popover", "sheet"].includes(name)
? "const "
: "";
}
);
content = content.replace(/\(0,(\w+)\.store\)/g, "store");
content = content.replace(/\(0,(\w+)\.getContext\)/g, "getContext");
content = content.replace(
/\(0,(\w+)\.withSyncEvent\)/g,
"withSyncEvent"
);
} else {
// Development: use source file with ES6 import transformation
if (!fs.existsSync(srcPath)) return;
let srcContent = fs.readFileSync(srcPath, "utf8");
// Remove existing import and destructure pattern
srcContent = srcContent.replace(
/import\s*\{[^}]+\}\s*from\s*['"]@wordpress\/interactivity['"];?\s*/g,
""
);
// Add clean import at top and wrap in IIFE
content =
importStatement +
'(()=>{\n"use strict";\n' +
srcContent.trim() +
"\n})();";
}
fs.writeFileSync(buildPath, content, "utf8");
});
}
}
/**
* Resolve wp-scripts' auto-detected entries (block.json scripts + src/index),
* then add our standalone entries. wp-scripts exposes `entry` as a function;
* call it and merge.
*
* `blocks/tabs/view` is listed explicitly because tabs deliberately omits the
* `viewScript` field: that field makes WordPress enqueue the file as a classic
* script, which cannot execute the ES module import FixInteractivityPlugin
* rewrites it to. Plugin.php enqueues it as a script module instead.
*/
function buildEntry() {
const base =
typeof defaultConfig.entry === "function"
? defaultConfig.entry()
: defaultConfig.entry;
return {
...base,
"extensions/core-button-icon": path.resolve(
__dirname,
"src/extensions/core-button-icon/index.js"
),
"blocks/tabs/view": path.resolve(__dirname, "src/blocks/tabs/view.js"),
"blocks/pricing/view": path.resolve(
__dirname,
"src/blocks/pricing/view.js"
),
};
}
module.exports = {
...defaultConfig,
entry: buildEntry,
plugins: [...(defaultConfig.plugins || []), new FixInteractivityPlugin()],
};