@jsenv/plugin-preact 1.9.0 → 1.9.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/plugin-preact",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,7 +30,7 @@
30
30
  "@jsenv/sourcemap": "1.4.3",
31
31
  "@jsenv/url-meta": "8.5.7",
32
32
  "@prefresh/babel-plugin": "0.5.3",
33
- "@prefresh/core": "1.5.10",
33
+ "@prefresh/core": "1.5.11",
34
34
  "@prefresh/utils": "1.2.1",
35
35
  "babel-plugin-transform-hook-names": "1.0.2"
36
36
  },
@@ -11,6 +11,48 @@ import {
11
11
  } from "@jsenv/ast";
12
12
  import { createMagicSource } from "@jsenv/sourcemap";
13
13
  import { URL_META } from "@jsenv/url-meta";
14
+ import { fileURLToPath } from "node:url";
15
+
16
+ // Babel resolves bare plugin names from the project root, where our own
17
+ // dependencies are not guaranteed to be installed (they are hoisted only when
18
+ // the app happens to depend on them too). Resolving them from here and handing
19
+ // babel an absolute path makes it work whatever the node_modules layout is.
20
+ const babelPluginFileCache = new Map();
21
+ const babelPluginFile = (specifier) => {
22
+ const fromCache = babelPluginFileCache.get(specifier);
23
+ if (fromCache) {
24
+ return fromCache;
25
+ }
26
+ const file = fileURLToPath(import.meta.resolve(specifier));
27
+ babelPluginFileCache.set(specifier, file);
28
+ return file;
29
+ };
30
+
31
+ // "@prefresh/babel-plugin" rewrites "createContext()" into a memoized version of
32
+ // itself and calls path.skip() before path.replaceWith() so that babel does not
33
+ // enter the "createContext()" call it just generated.
34
+ // Babel 8 requeue(), called by replaceWith(), resets shouldSkip, so that call is
35
+ // visited again and the rewrite recurses until the stack blows up.
36
+ // Re-skipping once the visitor is done restores the babel 7 behaviour.
37
+ let prefreshBabelPluginPromise;
38
+ const loadPrefreshBabelPlugin = () => {
39
+ prefreshBabelPluginPromise ||= import("@prefresh/babel-plugin").then(
40
+ ({ default: prefreshBabelPlugin }) =>
41
+ (babel, options) => {
42
+ const plugin = prefreshBabelPlugin(babel, options);
43
+ const { CallExpression } = plugin.visitor;
44
+ plugin.visitor.CallExpression = function (path, state) {
45
+ const nodeBeforeVisit = path.node;
46
+ CallExpression.call(this, path, state);
47
+ if (path.node !== nodeBeforeVisit) {
48
+ path.skip();
49
+ }
50
+ };
51
+ return plugin;
52
+ },
53
+ );
54
+ return prefreshBabelPluginPromise;
55
+ };
14
56
 
15
57
  export const jsenvPluginPreact = ({
16
58
  jsxTranspilation = true,
@@ -123,9 +165,11 @@ export const jsenvPluginPreact = ({
123
165
  ...(jsxEnabled
124
166
  ? [
125
167
  [
126
- urlInfo.context.dev
127
- ? "@babel/plugin-transform-react-jsx-development"
128
- : "@babel/plugin-transform-react-jsx",
168
+ babelPluginFile(
169
+ urlInfo.context.dev
170
+ ? "@babel/plugin-transform-react-jsx-development"
171
+ : "@babel/plugin-transform-react-jsx",
172
+ ),
129
173
  {
130
174
  runtime: "automatic",
131
175
  importSource: "preact",
@@ -136,8 +180,10 @@ export const jsenvPluginPreact = ({
136
180
  ],
137
181
  ]
138
182
  : []),
139
- ...(hookNamesEnabled ? ["babel-plugin-transform-hook-names"] : []),
140
- ...(refreshEnabled ? ["@prefresh/babel-plugin"] : []),
183
+ ...(hookNamesEnabled
184
+ ? [babelPluginFile("babel-plugin-transform-hook-names")]
185
+ : []),
186
+ ...(refreshEnabled ? [await loadPrefreshBabelPlugin()] : []),
141
187
  ],
142
188
  input: urlInfo.content,
143
189
  inputIsJsModule: true,