Automattic / isolated-block-editor

Repackages Gutenberg's editor playground as a full-featured multi-instance editor that does not require WordPress.
337 stars 50 forks source link

Uncaught Error: Cannot unlock an object that was not locked before - With Vite #248

Open andreibrindas opened 11 months ago

andreibrindas commented 11 months ago

Hey, I have trouble getting this package to work with Vite.

I get this error:

Uncaught Error: Cannot unlock an object that was not locked before. at unlock (implementation.js:185:9) at index.js:25:31

Is this because the package is not compatible with Vite (when I ran it on Webpack it was ok)?

Or am I doing something terribly wrong?

Thanks a lot!

johngodley commented 11 months ago

You are using the wrong version of Gutenberg. Only the version specified here (16.9.0), or the versions in package.json, will work.

andreibrindas commented 11 months ago

Thanks a lot for the swift response.

Hmm, where can I see the version of Gutenberg I'm using? I've installed this package with this command npm i @automattic/isolated-block-editor, but I don't see a Gutenberg version set in package-lock file.

Edit: I've also tried to use it in a clean new Vite app and a clean new CRA app, still having the same problem

johngodley commented 11 months ago

I don't know what version of Gutenberg you are using. It depends how you are bundling it - are you loading Gutenberg yourself externally, or bundling everything together? There is no package-lock.json file as the instructions say to use Yarn.

andreibrindas commented 11 months ago

I would like to use the bundled version (if I understand correctly, that's the one that doesn't require PHP)

andreibrindas commented 11 months ago

Then I guess, my question is: how can I use the bundled version? Do I need to install Gutenberg in my project? Or do I have to build this repo and then import in my project?

Thanks!

johngodley commented 11 months ago

Instructions are provided here:

https://github.com/Automattic/isolated-block-editor/

If you use the wrong versions of the packages then you will get the above message.

You say it works using Webpack so I would suggest using that. If you have problems with Vite then that is something you will need to figure out.

crs1138 commented 6 months ago

@johngodley one could safely state that the instructions provided there are less than sufficient to answer these questions. How can I get this module working in React? Using NextJS with Vite. I can't even get the simple React component to render.

'use client';
import React from 'react';
import IsolatedBlockEditor from '@automattic/isolated-block-editor/build-module/index';
export default function GbPage() {
    return <IsolatedBlockEditor />;
}

The issues in this repo are littered by questions like this one and the best you can do is sending people to an incomplete README file? I'd happily lend my hand to submit a PR to improve the documentation but I'd need a bit more to go on to get to understand why is this not working and how to fix it.

johngodley commented 6 months ago

@crs1138 I'm sorry it's not of a sufficient standard. However, this is very much an experimental package based on a continually moving target and you will need to adapt things for your own needs without support. This is even more necessary when you are using things for which it has never been tested with (NextJs/Vite).

The issue reported here and in other places is one caused by Gutenberg itself, not by this repo. I have tried to explain this, but there is little I can do to make it better. A lot of these questions could be directed to the Gutenberg project itself, and this repo should not be seen as an alternative place to get help.

I don't know what issue you are showing above, but your code does not look like the minimum required by the example in the readme. There's also the working example in https://github.com/Automattic/isolated-block-editor/tree/trunk/src/browser where you can look for more details.

crs1138 commented 6 months ago

Thank you for your speedy answer. Now, I understand a bit better the limitation of the scope of this repo. I see the problem with the examples included in the repo that they are either for browser (html, js, css) or WP plugin.

It'd be extremely useful to have a working example that would allow us to integrate the isolated block editor as a package with a JS framework like React. This shouldn't be that difficult as the editor itself is written in React. However, the only information on how to install it as a package/module is extremely short and leaves us hanging with the aforementioned error.

image

johngodley commented 6 months ago

a working example that would allow us to integrate the isolated block editor as a package with a JS framework like React

The example in the readme and in https://github.com/Automattic/isolated-block-editor/tree/trunk/src/browser are examples of using it with React, and as the entire repo is based on React it's the only way of using it. Do you mean specifically with a build system?

crs1138 commented 6 months ago

I guess what I find confusing and not relating to my use-case is the textarea replacement part. Attaching and detaching of the block-editor. This does not apply to a use-case of someone who already has a React application and wants to add the block editor. What do you need the createRoot() for? And do I really need it?

EDIT: Also the part with window.wp – that is just for an instance with Wordpress running, but that's not the case in a React app.

image

johngodley commented 6 months ago

Attaching and detaching of the block-editor. This does not apply to a use-case of someone who already has a React application and wants to add the block editor

The example is using it replace a textarea with an editor. If you don't need to do that in your app then it's not necessary to do it.

What do you need the createRoot()

That is from React (https://react.dev/reference/react-dom/client/createRoot#createroot)

And do I really need it?

I don't know how you would make a React app without it.

Also the part with window.wp – that is just for an instance with Wordpress running, but that's not the case in a React app.

It's part of Gutenberg and the DependencyExtractionWebpackPlugin that is described in the readme. It's use is dependant on your situation, and not related to whether you are using React or WordPress.

If you have other questions can you put them in another issue so the people here don't get spammed by them?

eddhurst commented 6 months ago

I don't know what version of Gutenberg you are using. It depends how you are bundling it - are you loading Gutenberg yourself externally, or bundling everything together? There is no package-lock.json file as the instructions say to use Yarn.

To clarify, Gutenberg under the hood is actually @wordpress/block-editor?

I believe that OP and I are having the same issue.

Reproduction:

myPackageName@0.0.0 /Users/eddhurst/development/myPackageName
└─┬ @automattic/isolated-block-editor@2.29.0
  ├── @wordpress/block-editor@12.21.0
  ├─┬ @wordpress/block-library@8.30.0
  │ ├── @wordpress/block-editor@12.21.0 deduped
  │ └─┬ @wordpress/patterns@1.16.0
  │   ├── @wordpress/block-editor@12.23.0
  │   └─┬ @wordpress/core-data@6.32.0
  │     └── @wordpress/block-editor@12.23.0 deduped
  ├─┬ @wordpress/core-data@6.30.0
  │ └── @wordpress/block-editor@12.21.0 deduped
  ├─┬ @wordpress/edit-post@7.30.0
  │ ├── @wordpress/block-editor@12.21.0 deduped
  │ ├─┬ @wordpress/core-commands@0.22.0
  │ │ └── @wordpress/block-editor@12.21.0 deduped
  │ └─┬ @wordpress/widgets@3.32.0
  │   ├── @wordpress/block-editor@12.23.0
  │   └─┬ @wordpress/core-data@6.32.0
  │     └── @wordpress/block-editor@12.23.0 deduped
  ├─┬ @wordpress/editor@13.30.0
  │ └── @wordpress/block-editor@12.21.0 deduped
  ├─┬ @wordpress/format-library@4.30.0
  │ └── @wordpress/block-editor@12.21.0 deduped
  └─┬ @wordpress/reusable-blocks@4.30.0
    └── @wordpress/block-editor@12.21.0 deduped

Package deps

"dependencies": {
    "@automattic/isolated-block-editor": "^2.29.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.66",
    "@types/react-dom": "^18.2.22",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react": "^7.34.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "sass": "^1.75.0",
    "vite": "^5.2.0"
  }

I'd also be open to helping open out the documentation a little to provide a bundled react example. The examples currently provided won't work for us as we can't use unpkg internally. Happy to help debug.

Outside of that I'm seeing a lot of peer dependency issues with deps looking for react@16 and getting react@18. Hard to say if these are part of the problem, but the examples also use React 18 so I'm guessing that we can overlook those for a minute?

kristianoye commented 3 months ago

I am experiencing the same issue. I copied/pasted the React code from the "getdave" repo linked to by the official documentation ("Building a custom block editor"). I get the error in:

webpack://kristianoye/node_modules/@wordpress/block-library/build-module/block/edit.js

image

Has anyone figured out how to fix this?

Additional: I am digging around a bit more and found that some odd stuff in my webpack bundle. I found what seems like 3 calls to create the same symbol. The source map for all 3 instances point back to the same location in the pre-webpacked code, but the symbol instances seem to be unique:

image
kristianoye commented 3 months ago

I figured out a hacky workaround for this particular issue. My webpack bundle included a bunch of nested definitions for the @wordpress/private-apis package. It was getting included by the 'preferences', 'patterns', and 'widgets' dependencies. I ended up completely deleting all the nested node_modules:

After I recompiled my bundle, the editor tried to start...

image

But I am now presented with a new set of errors to work through.

index.js:11 Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot pattern-overrides.js:44 Uncaught TypeError: useSetPatternBindings is not a function at BindingUpdater (pattern-overrides.js:44:1) at renderWithHooks (react-dom.development.js:15486:1) at mountIndeterminateComponent (react-dom.development.js:20103:1) at beginWork (react-dom.development.js:21626:1) at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) at invokeGuardedCallback (react-dom.development.js:4277:1) at beginWork$1 (react-dom.development.js:27490:1) at performUnitOfWork (react-dom.development.js:26596:1) at workLoopSync (react-dom.development.js:26505:1) react-dom.development.js:18704 The above error occurred in the component:

at BindingUpdater (http://localhost:8080/js/bundle.js:218626:79)
at http://localhost:8080/js/bundle.js:218616:89
at FilteredComponentRenderer (http://localhost:8080/js/bundle.js:167767:9)
at EditWithGeneratedProps (http://localhost:8080/js/bundle.js:11169:5)
at BlockEdit (http://localhost:8080/js/bundle.js:11242:3)
at BlockCrashBoundary (http://localhost:8080/js/bundle.js:12149:5)
at BlockListBlock (http://localhost:8080/js/bundle.js:12512:10)
at http://localhost:8080/js/bundle.js:60363:59
at http://localhost:8080/js/bundle.js:62933:98
at FilteredComponentRenderer (http://localhost:8080/js/bundle.js:167767:9)
at http://localhost:8080/js/bundle.js:197313:82
at BlockListBlockProvider (http://localhost:8080/js/bundle.js:12819:5)
at Items (http://localhost:8080/js/bundle.js:13212:3)
at BlockListItems
at div
at Root (http://localhost:8080/js/bundle.js:13111:3)
at BlockList
at div
at ObserveTyping (http://localhost:8080/js/bundle.js:46301:3)
at div
at WritingFlow (http://localhost:8080/js/bundle.js:54694:3)
at div
at BlockTools (http://localhost:8080/js/bundle.js:20863:3)
at div
at BlockRefsProvider (http://localhost:8080/js/bundle.js:46480:3)
at Provider (http://localhost:8080/js/bundle.js:177215:3)
at http://localhost:8080/js/bundle.js:46539:5
at http://localhost:8080/js/bundle.js:46890:5
at WithRegistryProvider(Component)
at BlockEditorProvider (http://localhost:8080/js/bundle.js:46566:12)
at div
at BlockEditor (http://localhost:8080/js/bundle.js:421581:24)
at div
at NavigableRegion (http://localhost:8080/js/bundle.js:234882:3)
at div
at div
at div
at InterfaceSkeleton (http://localhost:8080/js/bundle.js:234779:3)
at SlotFillProvider (http://localhost:8080/js/bundle.js:176844:3)
at SlotFillProvider (http://localhost:8080/js/bundle.js:177357:3)
at Provider (http://localhost:8080/js/bundle.js:177215:3)
at div
at ShortcutProvider (http://localhost:8080/js/bundle.js:235619:78)
at Editor (http://localhost:8080/js/bundle.js:421797:23)

React will try to recreate this component tree from scratch using the error boundary you provided, BlockCrashBoundary. index.js:32

OPTIONS http://localhost:8080/wp/v2/media?_locale=user 404 (Not Found) defaultFetchHandler @ index.js:104 fetchAllMiddleware @ fetch-all-middleware.js:81 (anonymous) @ index.js:152 httpV1Middleware @ http-v1.js:41 (anonymous) @ index.js:152 namespaceAndEndpointMiddleware @ namespace-endpoint.js:18 (anonymous) @ index.js:152 userLocaleMiddleware @ user-locale.js:20 (anonymous) @ index.js:152 apiFetch @ index.js:154 (anonymous) @ resolvers.js:316 (anonymous) @ thunk-middleware.js:4 (anonymous) @ index.js:24 (anonymous) @ promise-middleware.js:19 (anonymous) @ resolvers-cache-middleware.js:40 (anonymous) @ index.js:500 setTimeout (async)
fulfillSelector @ index.js:494 selectorResolver @ index.js:510 (anonymous) @ index.js:32 (anonymous) @ index.js:136 __unstableMarkListeningStores @ registry.js:118 (anonymous) @ registry.js:193 updateValue @ index.js:136 (anonymous) @ index.js:177 useMappingSelect @ index.js:202 useSelect @ index.js:286 BlockEditor @ index.js:31 renderWithHooks @ react-dom.development.js:15486 mountIndeterminateComponent @ react-dom.development.js:20103 beginWork @ react-dom.development.js:21626 beginWork$1 @ react-dom.development.js:27465 performUnitOfWork @ react-dom.development.js:26596 workLoopSync @ react-dom.development.js:26505 renderRootSync @ react-dom.development.js:26473 performSyncWorkOnRoot @ react-dom.development.js:26124 flushSyncCallbacks @ react-dom.development.js:12042 flushSync @ react-dom.development.js:26240 legacyCreateRootFromDOMContainer @ react-dom.development.js:29614 legacyRenderSubtreeIntoContainer @ react-dom.development.js:29640 render @ react-dom.development.js:29731 (anonymous) @ index.js:11 Show less

donjajo commented 3 weeks ago

@kristianoye I downgraded to 2.28.0 to fix the TypeError: useSetPatternBindings is not a function Sadly, this is not getting enough support and contribution. I could contribute after knowing my ways around it.

wolfv commented 2 weeks ago

In NextJS I fixed most problems by using:

import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.resolve.alias['@wordpress'] = path.resolve(__dirname, 'node_modules/@wordpress');
    return config;
  },
};

export default nextConfig;

Or if you use webpack, you can use the config directly (https://github.com/Automattic/isolated-block-editor/issues/252#issuecomment-2364053585).