Decided to try out use xstate with Svelte, basically porting the code you did in a recent workshop. I ran across a few bugs in setting up the build. First, I got a runtime exception for process being undefined at this line of code: var IS_PRODUCTION = process.env.NODE_ENV === 'production';. While this was easily overcome by adding a build step to the rollup config, e.g.,
replace({
'process.env.NODE_ENV': dev ? JSON.stringify('development') : JSON.stringify('production')
}),
I don't think that xstate probably wants to depend on process being present. Second, the following circular dependency warning is printed when using rollup:
(!) Circular dependency: node_modules/xstate/es/utils.js -> node_modules/xstate/es/StateNode.js -> node_modules/xstate/es/utils.js
(!) Circular dependency: node_modules/xstate/es/utils.js -> node_modules/xstate/es/StateNode.js -> node_modules/xstate/es/State.js -> node_modules/xstate/es/utils.js
(!) Circular dependency: node_modules/xstate/es/utils.js -> node_modules/xstate/es/StateNode.js -> node_modules/xstate/es/actions.js -> node_modules/xstate/es/utils.js
(!) Circular dependency: node_modules/xstate/es/utils.js -> node_modules/xstate/es/StateNode.js -> node_modules/xstate/es/StateTree.js -> node_modules/xstate/es/utils.js
In first case, would it be enough to check if process is present?
var IS_PRODUCTION = process && process.env.NODE_ENV === 'production'
I don't think that xstate probably wants to depend on process being present.
Actually this is a common practice for libraries and process.env.NODE_ENV is expected to be replaced by bundlers. Many libraries are doing it (i.e. react) and it's somewhat a standard way to strip things from production builds.
Adding additional check for process is bad as it will cause i.e. webpack & browserify to include unnecessary polyfills for the process object.
I agree with @Andarist about the process thing. Itβs a bug that svelte should fix in my opinion.
Checking for process would just hide the issue, you gonna end up with development code in production.
ok, thanks. I wonder if this is happens because of the way Svelte compiles code. To be fair version three just came out and I have noticed it is still a little rough around the edges.
I am also getting the problem in the same app of the typings not being found for xstate (a different issue of course). So a lot of little weird build issues. Are the circular dependencies warnings a mild issue?
ok, thanks. I wonder if this is happens because of the way Svelte compiles code.
Well, this is unfortunate - we have so many bundlers/compilers right now on the market, that it's often hard to "configure" a library so it could be used by each of them without any extra config on the user's side. In this particular case I would advise for reporting this to svelte team, so they could replace process.env.NODE_ENV appropriately based on their dev option (i think they have such) - as they aim for good DX and this issue will just come around many times for many people.
Are the circular dependencies warnings a mild issue?
Yeah - it still would be kinda good to remove this from xstate, but in ESM world circular dependencies are allowed, so no the problem per se.
The circular dependencies were removed.
EDIT: Adding the following was enough to patch this in my prototype for now:
<script>window.process = { env: 'development' }</script>
I think you have this covered already and I don't know if this will help, but since I've got the information handy β the ReferenceError: process is not defined error is also thrown when using xstate in the browser with ES Modules.
Here is a script to reproduce:
#!/usr/bin/env bash
rm -rf xstate-process-bug
mkdir xstate-process-bug
cd xstate-process-bug/
echo "import { Machine, interpret } from '//unpkg.com/[email protected]/es/index.js'; // or use your own interpreter!
// Stateless machine definition
// machine.transition(...) is a pure function used by the interpreter.
const toggleMachine = Machine({
initial: 'inactive',
states: {
inactive: { on: { TOGGLE: 'active' } },
active: { on: { TOGGLE: 'inactive' } }
}
});
// Machine instance with internal state
const toggleService = interpret(toggleMachine)
.onTransition(state => console.log(state.value))
.start();
// => 'inactive'
toggleService.send('TOGGLE');
// => 'active'
toggleService.send('TOGGLE');
// => 'inactive'
" > main.js
echo "<!doctype html>
<html>
<head>
<script type="module" src="main.js"></script>
</head>
<body>
<h1>See Console</h1>
</body>
</html>
" > index.html
npx http-server .
This will produce
xstate-process-bug
βββ index.html
βββ main.js
and start a web server to demonstrate.
@JamieMason if u want to consume xstate in module format directly in the browser without a build step then u have to use this file https://unpkg.com/[email protected]/dist/xstate.web.js . The one which u have used is intended to be consumed by bundlers
Ahh, thanks a lot @Andarist π
This is already fixed by svelte ?
@JamieMason if u want to consume xstate in module format directly in the browser without a build step then u have to use this file https://unpkg.com/[email protected]/dist/xstate.web.js . The one which u have used is intended to be consumed by bundlers
This works for me (using local import) !
Thank you very much.
This isn't a Svelte issue, it is a Rollup issue as it is the bundler in this case. The replace plugin mentioned above was the generally accepted solution to this particular issue, although, now a more robust solution for environment variables exists: https://www.npmjs.com/package/rollup-plugin-inject-process-env
Hope this helps.
Most helpful comment
This isn't a Svelte issue, it is a Rollup issue as it is the bundler in this case. The replace plugin mentioned above was the generally accepted solution to this particular issue, although, now a more robust solution for environment variables exists: https://www.npmjs.com/package/rollup-plugin-inject-process-env
Hope this helps.