در حال بارگذاری ...

Introducing TinkerWell0:00

Today, I want to give you a little behind-the-scenes look of how TinkerWell works. So if you haven't heard about TinkerWell yet, it is basically php artisan tinker on steroids. So it's a desktop application. I have it open here. If you open it, it will come with a default Laravel 7 application. So I could, for example, do something like make use of the new str::of method that's in Laravel 7. Then we append the heart emoji, because we all love Laracasts. Then I can press Command-R or press the Run button, and this code will be evaluated. And the same can be done either with remote projects via SSH, or you can just open your

Then I can press Command-R or press the Run button, and this code will be evaluated. And the same can be done either with remote projects via SSH, or you can just open your local projects and then access your local models. So for example, if I open Flare, I could do something like get all users out of the database and use my models, and then I get the output here, or I can make use of a table view and get my model output in this table. All right. So it is basically artisan tinker with a lot of superpowers. So that's like the main idea of TinkerWell. So I want to show you a bit how it works under the hood and how it's built.

Vue.js App Structure2:23

So for example, I can use Tailwind to style my application, which is awesome. And I can use Vue.js to make reactivity in my application. So that's also what I'm using in TinkerWell. So if we go to the Vue tab in my developer tools, and then take a look at the components, you can see that we have a TinkerWell component, which is like the main application. Then we have some tabs. We have a toolbar component that has its own data. We have the Tinker CLI, which is the current selected mode. And this has an editor and it has the output. So yeah, it's basically just a Vue.js application under the hood.

Electron IPC and Vuex4:45

They are basically two separate browser windows. So what I do is, or what you can do in Electron, there is this very nice debug extension when you have your Electron app, which is called DevTron. And in here you can see, for example, these IPC events. So let's listen for these events. And then when I change the font size, you can see that I am emitting a couple of events. So the first one is a setFontSize event, which just gets the font size. And then I have a setPreference event that is storing the font size key and the value as well. Now why I do this is to store the actual data, I'm using Vuex.

as well. Now why I do this is to store the actual data, I'm using VUX. So if we take a look at VUX, then when I clear this. So when I'm changing the font size, you can see that I get these mutations that set the font size to the value that I want. So this window is basically communicating to our background process. And the background process is then dispatching this event back to our main window. So that's how these two windows can communicate with each other. So let me show you how this looks like in the code. So if we go to our preferences view, then you can see that we have as the data, we have

Preferences Event Wiring6:11

So let me show you how this looks like in the code. So if we go to our preferences view, then you can see that we have as the data, we have the preferences. And in here we have the fontSize. So the default value of the fontSize is coming out of the Vuex store. We can preload the fontSize with whatever value you saved. Now I have a watcher for this fontSize. Here it is. And whenever the fontSize changes, then I'm going to emit an event. So I'm basically sending an event from my renderer to my backgroundProcess.

And if we go to our background.js, which is from the background process, then we have these event listeners for the main event. So this is basically the background process event listener. So in here I'm listening for the setFontSize event. And when I receive this event from a renderer, I'm basically just going to dispatch this event back to my main window. So once again, the preferences window sends the event, the background process catches the event, and then sends it or forwards it to my main window. And that's how both of those windows can communicate with each other. So the last step is that in my editor component, I have another event listener.

PHAR Execution Pipeline9:30

this code and then giving me the output. So let's take a look at how that works. Little disclaimer, it is a bit messy, but it has a reason. So this is the PHP file that I have that gets compiled to a FAR file. And as you can see, there are some weird namespaces going on in here. So we have these PHP scoper and then some random identifier namespaces in here. So that's because since TinkerWell ships with its own FAR file, and it requires, for example, on the PsyShell composer package, which again, requires some symphony components, I do not want to break other people's application because of my dependencies. Or maybe TinkerWell would not work because I have other dependencies that their applications.

want to break other people's application because of my dependencies. Or maybe TinkerWell would not work because I have other dependencies that their applications already have. So to avoid this problem, I'm using something called php-scoper, which basically just scans your PHP code once and then adds some random namespaces to it. So if we go take a look at the vendor directory of this, then you can see that basically everything in here is namespaced by this php-scoper namespace. So this allows me to safely use my dependencies without having to take care of any dependencies that the user's applications might have. So this is really nice, but well, it makes the code a bit messy because yeah, they have

Framework Driver Bootstrapping11:00

that the user's applications might have. So this is really nice, but well, it makes the code a bit messy because yeah, they have these long namespaces that get prepended. But yeah, it does the job and works fine. So the way it works with TinkerWell is once the code that you want to evaluate gets called, I'm trying to detect a driver for a specific path. So this is a bit like how Laravel Valet does it. So I'm trying to detect which driver I can use for this specific project path. And then inside, I have the so these are the available drivers, we have a lot of frameworks integrated.

And then inside, I have the so these are the available drivers, we have a lot of frameworks integrated. And if we take a look at the Laravel TinkerWell driver, what we do is we just try and detect can we bootstrap this specific project path? So can the Laravel TinkerWell driver bootstrap this path? In our case, this would be the case if the public/index.php file exists is existent, and there is an artisan file. And once that's true, we are going to bootstrap this specific path. So for Laravel, this route would require that we load the autoloader, then we require our bootstrap/app.php.

So for Laravel, this route would require that we load the autoloader, then we require our bootstrap/app.php. And then we get the console kernel out of the container and bootstrap that. And from this point on, Laravel is basically ready to go and we can evaluate code within it. So then basically, all that happens is we have PsyShell. We create a new PsyShell instance, I set the output to be an output buffer so that I can get the output back. The file that you have the content that you have here, so your code is being written to a temporary file that's that happens in the app.

The file that you have the content that you have here, so your code is being written to a temporary file that's that happens in the app. And then in the far file, I'm basically just loading that file so that I can get the content of your code. We're going to add that code to PsyShell and execute it. Then well, yeah, I'm just getting the output back from my output buffer, I remove some things that PsyShell adds, and then just echo it. So that's basically all that the far file does. And in Tinkerwell, once you run the code, okay, so this doesn't work here, it changed, I did the hot reloading stuff, then Tinkerwell is going to just execute this php command

And in Tinkerwell, once you run the php command, okay, so this doesn't work here, it changed, I did the hot reloading stuff, then Tinkerwell is going to just execute this php command and then get the output and emit it to our VUX store. So let me show you how that works. If I'm just going to say, let's just get a UUID. If we take a look at the DevTools, remove that, run the code, you can see that a couple of things happened. We set the code. So this is our payload, which is the code here, we set some is executing event, which just sets a loading icon.

So this is our payload, which is the code here, we set some isExecuting event, which just sets a loading icon. And once that's finished, we clear the output. And then we append this output, which is coming from our file to the actual editor. So this is a very, very short overview of some of the things that happened behind the scenes in Tinkerwell, there's a ton more going on. And I think it's super interesting to work with Aleksandr, especially in combination with php. If you want to check out Tinkerwell, the application itself, you can get it at Tinkerwell.app. We support a ton of frameworks.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟