-
-
Notifications
You must be signed in to change notification settings - Fork 937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requiring "solid-js/web" on electron (with nodeIntegration) makes it think I'm on the server #1102
Comments
This is the normal behavior in Node. Currently, on Node, importing Importing directly from I agree that this situation is pretty annoying for using reactivity on Node, but we need an actual proposal for behavior that still enables SSR work. |
The problem is that I can't use templating libs like |
But I actually don't get it - why can't Solid have two different requires, one for SSR and one for Browser? Why they need to be the same path? Is there a reason for that? |
I think the reason is "being isomorphic". Usually you have one file define a component, and that file needs to be loaded on both client and server for SSR. And it needs to I think Node conditions are a good way. I just don't like that you need to set a condition of |
I think I may be missing something: this code does not work on NodeJS, for example (pure node, no Electron): const h = require('solid-js/h');
const s = require('solid-js/web');
function A() {
return h('div', {}, 'Hello, world!')
}
s.renderToString(A) It fails with "Uncaught TypeError: Cannot read property 'has' of undefined". I found that the trouble is that Which is to say: as of now, |
It seems that Electron might define a Node condition |
You can split your UI and backend in electron, simulating the network's C/S artfs. then use solid at your UI part. |
Me too but I wanted it to be consistent with legacy. Pre esm and export conditions having the browser field was the pattern. Which makes sense. Package.json was built for npm, ie node. |
So, after talking in Discord, I decided to make some experiments with a greenfield Electron app. It actually doesn't work, even if I "patch" To run, just install packages and run with |
Also, updating what we were discussing on Discord here: I'm trying to use SolidJS to make some changes in an Atom plug-in, so I can't really change NODE_OPTIONS or things like that (because that's handled by Atom itself). I also can't use JSX because the plug-in is written in ClojureScript, and there's no way to return a JSX content inside ClojureScript, unfortunately... |
I haven't pulled this down but if I were to guess it's because solid-js/web references solid-js directly. So even with the client version of web we are getting the server version of solid's core. The server version is non-reactive which would explain no updates. Short of using conditions, you'd need to alias all the references. This is how we landed on conditions in the first place. Trying to get this stuff to play nice for isomorphic SSR was a pain. As it turns out going the opposite direction is similarly so. |
Also, is there a way to make Electron behave as if it's always a web version? I'm not sure why one would want to use SSR on Electron... |
Depends on the bundler being used.
But this I think we can do. It has to be how others solve this because we aren't the only ones with this issue for sure. Maybe not export conditions but stuff like the browser field predate this. Targets like Hmm.. this is dated, using webpack with This is documentation from webpack on how to set conditions: https://webpack.js.org/configuration/resolve/#resolveconditionnames. In which case we'd want Sorry lack of familiarity with electron specifically and the build process. But most bundlers have the ability to set these things. |
Yeah, makes sense. Another option would be to publish as a totally different NPM package. |
@edemaine That'd be fine for the reactive stuff. Like people want to just use reactivity. But like this case here we actually want web as well. So references in web have to change as well. So I don't think that actually helps a ton here, or testing envs or any of the typical Solid workflows. |
Sorry, to clarify, I meant you could
All the subdirectories would work as before, but with only the browser (and dev) exports that Of course, everything would break down if you installed both packages |
If possible, it would help me a lot. My case is quite complicated because I'm using Solid with ClojureScript. It uses closure compiler, which as far as I know don't handle NPM too well, but I'm running over Shadow-CLJS which do handle rewriting of NodeJS |
Oh I see so this is more than just straight Electron. Because that article I linked from 2017 I imagine would still work today. But if webpack isn't even involved and we we are talking about some bundling/building that doesn't have any of these sort of aliasing. Looking at common config though it looks like renderer is set with browser target at least in starters like: https://github.com/ahonn/shadow-electron-starter/blob/master/shadow-cljs.edn So I would have hoped this would just find the browser fields. Hmm. |
don't know what bundler are you using, but I put together this const { parse } = require("path");
const { readFile } = require("fs/promises");
const { transformAsync } = require("@babel/core");
const solid = require("babel-preset-solid");
const ts = require("@babel/preset-typescript");
const defaultOptions = {
hydratable: true,
generate: "dom",
};
const regexMap = {
"solid-js": /(?<=solid-js\/).*$/gm,
"solid-js/web": /(?<=solid-js\/web\/).*$/gm,
"solid-js/store": /(?<=solid-js\/store\/).*$/gm,
};
/** @type {() => import('esbuild').Plugin} */
function solidPlugin(options) {
const pluginOptions = Object.assign({}, defaultOptions, options);
return {
name: "esbuild:solid",
setup(build) {
build.onResolve({ filter: /solid-js/ }, ({ path, resolveDir }) => {
let newPath = require.resolve(path, {
paths: [resolveDir],
});
if (path === "solid-js/web") {
newPath = newPath.replace(regexMap[path], "dist/web.js");
} else if (path === "solid-js/store") {
newPath = newPath.replace(regexMap[path], "dist/store.js");
} else {
newPath = newPath.replace(regexMap[path], "dist/solid.js");
}
return {
path: newPath,
};
});
build.onLoad({ filter: /\.tsx$/ }, async (args) => {
const source = await readFile(args.path, { encoding: "utf-8" });
const { name, ext } = parse(args.path);
const filename = name + ext;
const { code } = await transformAsync(source, {
presets: [[solid, pluginOptions], ts],
filename,
sourceMaps: "inline",
});
return { contents: code, loader: "js" };
});
},
};
}
module.exports = { solidPlugin };
`` |
This section suggests webpack uses Would love an update or confirmation. But looks like we should already be setup right. |
Closing as stale. |
Describe the bug
I want to use SolidJS in an Electron. Using
require('solid-js/web').isServer
returnstrue
, which means I can't userender
and other web-related code.I can work-around by requiring
solid-js/web/dist/web.cjs
but seems fragile...Your Example Website or App
https://github.com/mauricioszabo/solid-electron-error
Steps to Reproduce the Bug or Issue
Inside an electron app with
nodeIntegration: true
try to requiresolid-js/web
. The contents ofisServer
istrue
Expected behavior
I expect
require('solid-js/web')
to always require "web" stuff, or at least have something likerequire('solid-js/browser')
that always points to browser, andrequire('solid-js/server')
that always points to serverScreenshots or Videos
No response
Platform
Additional context
No response
The text was updated successfully, but these errors were encountered: