Skip to content

Commit e5b99c2

Browse files
authored
Merge pull request #70 from wjq990112/main
fix(#66): signals as refs
2 parents ad30cba + 5142e4f commit e5b99c2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3135
-14
lines changed

playground/pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/src/App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createSignal, onCleanup, onMount } from 'solid-js';
22

33
export function App() {
44
const [count, setCount] = createSignal(0);
5+
const [, setEl] = createSignal<HTMLElement>();
56

67
function increment() {
78
setCount(c => c + 1);
@@ -19,7 +20,7 @@ export function App() {
1920

2021
return (
2122
<>
22-
<h1>Count: {count()}</h1>
23+
<h1 ref={setEl}>Count: {count()}</h1>
2324
<button type="button" onClick={increment}>
2425
Increment
2526
</button>

pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/babel/core/transform-jsx.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ function extractJSXExpressionFromRef(
7777
let replacement: t.Expression;
7878
if (unwrappedIdentifier) {
7979
const arg = expr.scope.generateUidIdentifier('arg');
80+
const binding = expr.scope.getBinding(unwrappedIdentifier.name);
81+
const cannotAssignKind = ['const', 'module'];
82+
const isConst = binding && cannotAssignKind.includes(binding.kind);
83+
8084
replacement = t.arrowFunctionExpression(
8185
[arg],
8286
t.blockStatement([
@@ -91,11 +95,17 @@ function extractJSXExpressionFromRef(
9195
t.callExpression(unwrappedIdentifier, [arg]),
9296
),
9397
]),
94-
t.blockStatement([
95-
t.expressionStatement(
96-
t.assignmentExpression('=', unwrappedIdentifier, arg),
97-
),
98-
]),
98+
// fix the new usage of `ref` attribute,
99+
// if use `Signals as refs`, the `else` branch will throw an error with `Cannot assign to "setter" because it is a constant` message
100+
// issue: https://github.com/solidjs/solid-refresh/issues/66
101+
// docs: https://docs.solidjs.com/concepts/refs#signals-as-refs
102+
isConst
103+
? null
104+
: t.blockStatement([
105+
t.expressionStatement(
106+
t.assignmentExpression('=', unwrappedIdentifier, arg),
107+
),
108+
]),
99109
),
100110
]),
101111
);

tests/client-hydratable/__snapshots__/esm.test.ts.snap

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,119 @@ if (import.meta.hot) {
11701170
}"
11711171
`;
11721172
1173+
exports[`esm (client, hydratable) > fix build > refs > should work with a function 1`] = `
1174+
"import { template as _$template } from "solid-js/web";
1175+
import { createComponent as _$createComponent } from "solid-js/web";
1176+
import { getNextElement as _$getNextElement } from "solid-js/web";
1177+
import { use as _$use } from "solid-js/web";
1178+
var _tmpl$ = /*#__PURE__*/_$template(\`<div>Comp\`);
1179+
import { $$component as _$$component } from "solid-refresh";
1180+
import { $$refresh as _$$refresh } from "solid-refresh";
1181+
import { $$registry as _$$registry } from "solid-refresh";
1182+
const _REGISTRY = _$$registry();
1183+
const Comp_1 = _$$component(_REGISTRY, "Comp_1", _props => /*@refresh jsx-skip*/(() => {
1184+
var _el$ = _$getNextElement(_tmpl$);
1185+
var _ref$ = _props.v0;
1186+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : _props.v0 = _el$;
1187+
return _el$;
1188+
})(), {
1189+
location: "example.jsx:4:19",
1190+
signature: "6f76290"
1191+
});
1192+
const Comp = _$$component(_REGISTRY, "Comp", () => {
1193+
let el;
1194+
return /*@refresh jsx-skip*/_$createComponent(Comp_1, {
1195+
v0: _el => el = _el
1196+
});
1197+
}, {
1198+
location: "example.jsx:2:23",
1199+
signature: "726057ca"
1200+
});
1201+
if (import.meta.hot) {
1202+
_$$refresh("esm", import.meta.hot, _REGISTRY);
1203+
}"
1204+
`;
1205+
1206+
exports[`esm (client, hydratable) > fix build > refs > should work with a mutable variable 1`] = `
1207+
"import { template as _$template } from "solid-js/web";
1208+
import { createComponent as _$createComponent } from "solid-js/web";
1209+
import { getNextElement as _$getNextElement } from "solid-js/web";
1210+
import { use as _$use } from "solid-js/web";
1211+
var _tmpl$ = /*#__PURE__*/_$template(\`<div>Comp\`);
1212+
import { $$component as _$$component } from "solid-refresh";
1213+
import { $$refresh as _$$refresh } from "solid-refresh";
1214+
import { $$registry as _$$registry } from "solid-refresh";
1215+
const _REGISTRY = _$$registry();
1216+
const Comp_1 = _$$component(_REGISTRY, "Comp_1", _props => /*@refresh jsx-skip*/(() => {
1217+
var _el$ = _$getNextElement(_tmpl$);
1218+
var _ref$ = _props.v0;
1219+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : _props.v0 = _el$;
1220+
return _el$;
1221+
})(), {
1222+
location: "example.jsx:4:19",
1223+
signature: "6f76290"
1224+
});
1225+
const Comp = _$$component(_REGISTRY, "Comp", () => {
1226+
let el;
1227+
return /*@refresh jsx-skip*/_$createComponent(Comp_1, {
1228+
v0: _arg => {
1229+
if (typeof el === "function") {
1230+
el(_arg);
1231+
} else {
1232+
el = _arg;
1233+
}
1234+
}
1235+
});
1236+
}, {
1237+
location: "example.jsx:2:23",
1238+
signature: "d3db0f89"
1239+
});
1240+
if (import.meta.hot) {
1241+
_$$refresh("esm", import.meta.hot, _REGISTRY);
1242+
}"
1243+
`;
1244+
1245+
exports[`esm (client, hydratable) > fix build > signals as refs > should work 1`] = `
1246+
"import { template as _$template } from "solid-js/web";
1247+
import { createComponent as _$createComponent } from "solid-js/web";
1248+
import { getNextElement as _$getNextElement } from "solid-js/web";
1249+
import { use as _$use } from "solid-js/web";
1250+
var _tmpl$ = /*#__PURE__*/_$template(\`<div>Comp\`);
1251+
import { $$component as _$$component } from "solid-refresh";
1252+
import { $$refresh as _$$refresh } from "solid-refresh";
1253+
import { $$registry as _$$registry } from "solid-refresh";
1254+
import { createSignal } from 'solid-js';
1255+
const _REGISTRY = _$$registry();
1256+
const Comp_1 = _$$component(_REGISTRY, "Comp_1", _props => /*@refresh jsx-skip*/(() => {
1257+
var _el$ = _$getNextElement(_tmpl$);
1258+
var _ref$ = _props.v0;
1259+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : _props.v0 = _el$;
1260+
return _el$;
1261+
})(), {
1262+
location: "example.jsx:6:19",
1263+
signature: "6f76290"
1264+
});
1265+
const Comp = _$$component(_REGISTRY, "Comp", () => {
1266+
const [el, setEl] = createSignal();
1267+
return /*@refresh jsx-skip*/_$createComponent(Comp_1, {
1268+
v0: _arg => {
1269+
if (typeof setEl === "function") {
1270+
setEl(_arg);
1271+
}
1272+
}
1273+
});
1274+
}, {
1275+
location: "example.jsx:4:23",
1276+
signature: "57db44c6",
1277+
dependencies: () => ({
1278+
createSignal
1279+
})
1280+
});
1281+
if (import.meta.hot) {
1282+
_$$refresh("esm", import.meta.hot, _REGISTRY);
1283+
}"
1284+
`;
1285+
11731286
exports[`esm (client, hydratable) > fix render > @refresh reload > should work 1`] = `
11741287
"import { createComponent as _$createComponent } from "solid-js/web";
11751288
import { $$decline as _$$decline } from "solid-refresh";

tests/client-hydratable/__snapshots__/rspack-esm.test.ts.snap

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,119 @@ if (import.meta.webpackHot) {
11701170
}"
11711171
`;
11721172
1173+
exports[`rspack-esm (client, hydratable) > fix build > refs > should work with a function 1`] = `
1174+
"import { template as _$template } from "solid-js/web";
1175+
import { createComponent as _$createComponent } from "solid-js/web";
1176+
import { getNextElement as _$getNextElement } from "solid-js/web";
1177+
import { use as _$use } from "solid-js/web";
1178+
var _tmpl$ = /*#__PURE__*/_$template(\`<div>Comp\`);
1179+
import { $$component as _$$component } from "solid-refresh";
1180+
import { $$refresh as _$$refresh } from "solid-refresh";
1181+
import { $$registry as _$$registry } from "solid-refresh";
1182+
const _REGISTRY = _$$registry();
1183+
const Comp_1 = _$$component(_REGISTRY, "Comp_1", _props => /*@refresh jsx-skip*/(() => {
1184+
var _el$ = _$getNextElement(_tmpl$);
1185+
var _ref$ = _props.v0;
1186+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : _props.v0 = _el$;
1187+
return _el$;
1188+
})(), {
1189+
location: "example.jsx:4:19",
1190+
signature: "6f76290"
1191+
});
1192+
const Comp = _$$component(_REGISTRY, "Comp", () => {
1193+
let el;
1194+
return /*@refresh jsx-skip*/_$createComponent(Comp_1, {
1195+
v0: _el => el = _el
1196+
});
1197+
}, {
1198+
location: "example.jsx:2:23",
1199+
signature: "726057ca"
1200+
});
1201+
if (import.meta.webpackHot) {
1202+
_$$refresh("rspack-esm", import.meta.webpackHot, _REGISTRY);
1203+
}"
1204+
`;
1205+
1206+
exports[`rspack-esm (client, hydratable) > fix build > refs > should work with a mutable variable 1`] = `
1207+
"import { template as _$template } from "solid-js/web";
1208+
import { createComponent as _$createComponent } from "solid-js/web";
1209+
import { getNextElement as _$getNextElement } from "solid-js/web";
1210+
import { use as _$use } from "solid-js/web";
1211+
var _tmpl$ = /*#__PURE__*/_$template(\`<div>Comp\`);
1212+
import { $$component as _$$component } from "solid-refresh";
1213+
import { $$refresh as _$$refresh } from "solid-refresh";
1214+
import { $$registry as _$$registry } from "solid-refresh";
1215+
const _REGISTRY = _$$registry();
1216+
const Comp_1 = _$$component(_REGISTRY, "Comp_1", _props => /*@refresh jsx-skip*/(() => {
1217+
var _el$ = _$getNextElement(_tmpl$);
1218+
var _ref$ = _props.v0;
1219+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : _props.v0 = _el$;
1220+
return _el$;
1221+
})(), {
1222+
location: "example.jsx:4:19",
1223+
signature: "6f76290"
1224+
});
1225+
const Comp = _$$component(_REGISTRY, "Comp", () => {
1226+
let el;
1227+
return /*@refresh jsx-skip*/_$createComponent(Comp_1, {
1228+
v0: _arg => {
1229+
if (typeof el === "function") {
1230+
el(_arg);
1231+
} else {
1232+
el = _arg;
1233+
}
1234+
}
1235+
});
1236+
}, {
1237+
location: "example.jsx:2:23",
1238+
signature: "d3db0f89"
1239+
});
1240+
if (import.meta.webpackHot) {
1241+
_$$refresh("rspack-esm", import.meta.webpackHot, _REGISTRY);
1242+
}"
1243+
`;
1244+
1245+
exports[`rspack-esm (client, hydratable) > fix build > signals as refs > should work 1`] = `
1246+
"import { template as _$template } from "solid-js/web";
1247+
import { createComponent as _$createComponent } from "solid-js/web";
1248+
import { getNextElement as _$getNextElement } from "solid-js/web";
1249+
import { use as _$use } from "solid-js/web";
1250+
var _tmpl$ = /*#__PURE__*/_$template(\`<div>Comp\`);
1251+
import { $$component as _$$component } from "solid-refresh";
1252+
import { $$refresh as _$$refresh } from "solid-refresh";
1253+
import { $$registry as _$$registry } from "solid-refresh";
1254+
import { createSignal } from 'solid-js';
1255+
const _REGISTRY = _$$registry();
1256+
const Comp_1 = _$$component(_REGISTRY, "Comp_1", _props => /*@refresh jsx-skip*/(() => {
1257+
var _el$ = _$getNextElement(_tmpl$);
1258+
var _ref$ = _props.v0;
1259+
typeof _ref$ === "function" ? _$use(_ref$, _el$) : _props.v0 = _el$;
1260+
return _el$;
1261+
})(), {
1262+
location: "example.jsx:6:19",
1263+
signature: "6f76290"
1264+
});
1265+
const Comp = _$$component(_REGISTRY, "Comp", () => {
1266+
const [el, setEl] = createSignal();
1267+
return /*@refresh jsx-skip*/_$createComponent(Comp_1, {
1268+
v0: _arg => {
1269+
if (typeof setEl === "function") {
1270+
setEl(_arg);
1271+
}
1272+
}
1273+
});
1274+
}, {
1275+
location: "example.jsx:4:23",
1276+
signature: "57db44c6",
1277+
dependencies: () => ({
1278+
createSignal
1279+
})
1280+
});
1281+
if (import.meta.webpackHot) {
1282+
_$$refresh("rspack-esm", import.meta.webpackHot, _REGISTRY);
1283+
}"
1284+
`;
1285+
11731286
exports[`rspack-esm (client, hydratable) > fix render > @refresh reload > should work 1`] = `
11741287
"import { createComponent as _$createComponent } from "solid-js/web";
11751288
import { $$decline as _$$decline } from "solid-refresh";

0 commit comments

Comments
 (0)