mrm
mrm copied to clipboard
Allow running custom tasks directly with npx
I'd like to be able to run an mrm task without a) globally installing mrm and b) without globally installing the task. I.e. just:
npx @my-org/my-task
And have that be it.
AFAIU right now I have to both npm i -g mrm
as well as npm i -g @my-org/my-task
, to finally be able to do mrm @my-org/my-task
.
Granted, if I'm going to run mrm
and @my-org/my-task
repetitively, this is fine, but I'd like to use mrm
for things similar to npx create-react-app
, where users who want to use/install a library want to run just a one-time command or two, and won't necessarily have/want mrm
to be installed globally and stick around.
(Note that I know npx mrm
works, but AFAIU I can't avoid an npm i -g
for custom tasks, i.e. how can I invoke @my-org/my-task
with a single npx
invocation?)
(Fwiw, my guess that this is admittedly tricky because npx
would need to fetch both the core mrm
as well as @my-org/my-task
with a single npx
invocation, so it's probably "simplest" for the npx
command to look like npx @my-org/my-task
and then somehow the task knows it's being run directly and actually invokes mrm
with itself as the task to run.)
You should be able to do
npx mrm @my-org/my-task
or if it's a preset
npx mrm my-task @my-org/my-preset
@MattBodey AFAICT that doesn't work, b/c npx
knows to download mrm
(which is great) but neither npx
nor mrm
know to download @my-org/my-task
, so you need to explicitly npm i -g
it.
For example this command does not work for me w/o our task already -g
installed:
npx mrm @homebound-team/mrm-tasks-prettier
@stephenh Ah sorry, I mistyped above.
npx mrm myTask --preset @my-team/mrm-preset
I use this, and I have neither mrm or my preset installed globally.
I think for the above to work you need to publish your custom task in a preset rather than as a separate task https://mrm.js.org/docs/making-presets.
Unfortunately I have no knowledge about how to do this for tasks published outside of a preset
I also want this solution, and am digging into how we could solve this...
This first thing I notice is that using libnpx
causes the most wait time for mrm
to run. Every invocation libnpx
runs rimraf
and wipes everything and re-downloads all the tasks.
You can see in this flame graph that the majority of the first half of the run is rimraf
wiping the modules before starting the run.
I digress, since I have been in the internals of mrm
a bunch.
I was thinking about using degit to run our own personal tasks since it can:
- download right from github, no publishing or installing.
- has a nice node interface so it shouldn't be hard to add to
mrm
I was thinking of adding to our config.json
maybe something like
{
externalTasks: [
"github:kevinkhill/mrm-contrib-tsx"
]
}
to which on running mrm
it can use npx
to run degit
and download the task into our local location. We know where this is since we already read the config file. degit
can download our externalTasks
, store them alongside the config and then be available for execution.
@stephenh, @MattBodey What do you think?
@kevinkhill personally publishing tasks to npm wasn't a big deal for us. Really great to hear you're poking around at mrm internals though! Its a great project.
I don't really have an answer why, but I've never really published to npm. It's always felt daunting 🤷
It almost feels like an extra step to have to setup github actions to publish or do it myself, when I am already pushing it to github.
I really like degit
as a solution 🤔
@kevinkhill ah yeah, I get that. When I used to do Java projects back in the day, publishing to Maven central (their npm) was a huge PITA (mostly b/c Maven central was actually secure (for some definition of secure) and required registering your package via an email address from your org's DNS) </soapbox>
:-) ).
So yeah being able to "just pull from a git url" seems neat too. Especially if it's public/no auth.
🏎️ 👀
I've been toying around and accidentally ripped the whole thing apart..... 😬
I was trying really hard not to change too much, but then got carried away.... It's kinda far from what mrm
was internally. I converted it to ES modules and then started in on my degit
resolver. Then I wanted to pass in options, then I wanted to have path aliases to install into...
I will keep playing with it because it is really fun! 😁
🥂 to mrm
@sapegin, it's a really cool you made.
I accidentally made it TypeScript! heh, really and removed a few dependencies for modern ES6/7 methods... this was helpful
It's just something fun to tinker with before work, keep myself fresh on TypeScript... If it is useful to anyone else, super, if not, that's cool too. 😎