SuperGeekery: A blog probably of interest only to nerds by John F Morton.

A blog prob­a­bly of inter­est only to nerds by John F Mor­ton.

Yeoman generators, the file system and symlinks.

I write and main­tain a Yeo­man gen­er­a­tor called Build A Ban­ner”, aka BAB.

As you might guess from the title, the gen­er­a­tor helps in devel­op­ing ani­mat­ed dis­play ad ban­ners. It cre­ates a direc­to­ry with cus­tomized HTML, JS and CSS starter files, builds a small devel­op­ment serv­er with live-reload­ing, and has work­flows for opti­miz­ing and deliv­er­ing ban­ners to a media com­pa­ny. We use it all the time at JMX2.

Although I’ve been main­tain­ing this repo for years, I have just recent­ly decid­ed to pay atten­tion to how my local gen­er­a­tor (i.e. my work in progress ver­sion of BAB) and the glob­al gen­er­a­tors I’ve also got installed exist with­in my file sys­tem.

A quick primer

Before I dive in, let’s talk about Yeo­man quick­ly. Yeo­man is a node pack­age that helps scaf­fold out projects. What kind of projects? Well, in the case of BAB, the project is build­ing an adver­tis­ing ban­ner. Anoth­er project I scaf­fold out reg­u­lar­ly is build­ing a plu­g­in for Craft CMS. A friend of mine main­tains a gen­er­a­tor for it called gen­er­a­tor-craft­plu­g­in” and it does that exact­ly. There are all kinds of gen­er­a­tors and you can find them at the Yeo­man Gen­er­a­tor Dis­cov­er page.

Global node modules

Let’s assume you’ve read the instruc­tions on how to install Yeo­man. How do you install gen­er­a­tors? Gen­er­a­tors are node mod­ules, so you install a gen­er­a­tor just like you’d install any node mod­ule. Typ­i­cal­ly you install them glob­al­ly from the com­mand line like this. (I say typ­i­cal­ly” because Yeo­man has a built in install a gen­er­a­tor fea­ture as well. I don’t use this though.)

To install the cur­rent pub­lic ver­sion of BAB glob­al­ly, you’d use this com­mand on your com­mand line:

npm install -g generator-buildabanner

To install the cur­rent pub­lic ver­sion of gen­er­a­tor-craft­plu­g­in glob­al­ly, you’d use this com­mand on your com­mand line:

npm install -g generator-craftplugin

The -g is the flag telling npm to install glob­al­ly.

Local node modules

If the -g flags was­n’t there, you’d be installing it in a node_modules sub­fold­er of the direc­to­ry you’re cur­rent­ly in while in your Ter­mi­nal. Your mod­ule would­n’t be glob­al­ly avail­able though, and we need our Yeo­man gen­er­a­tors to be avail­able any­where on our com­put­ers since we will scaf­fold out projects in many loca­tions.

You will prob­a­bly not want every­thing to be glob­al though. For exam­ple, if you want­ed the Flick­i­ty javascript library installed into your web dev project, you’d want that library to be in your local direc­to­ry. You’d run the fol­low­ing, with a --save flag, so you can keep track of it in a package.json file.

npm install flickity --save

You’d see a node_modules direc­to­ry cre­at­ed (if it was­n’t there already) and the Flick­i­ty files would be inside of it.


Where Yeoman generators live

Let’s get back to Yeo­man now. Now that those glob­al Yeo­man gen­er­a­tors are installed, you might won­der where they exist on your local file sys­tem. They are glob­al node mod­ules so they’ll be installed along­side your oth­er glob­al node mod­ules. Ok, where is that? Well, fol­low me down the rab­bit hole.

There are sev­er­al ways to install Node. The nor­mal way you would install it would be to fol­low the instruc­tions on the Node JS site. Why would you not fol­low those instruc­tions? There are many ver­sions of Node. Node is also updat­ed reg­u­lar­ly. Some­times you need a ver­sion of Node that is dif­fer­ent from the cur­rent sta­ble ver­sion.

There is a script called Node Ver­sion Man­ag­er, aka NVM, that helps you install mul­ti­ple dif­fer­ent ver­sions of Node and eas­i­ly switch between them as you need to. That’s how I’ve got Node installed.

If you’ve fol­lowed the offi­cial Node direc­tions, your mod­ules are prob­a­bly installed in either /usr/local/lib/node or /usr/local/lib/node_modules.

If you’re using NVM like I am, your mod­ules are installed some­where like this:

/Users/john/.nvm/versions/node/v10.5.0/lib/node_modules

That path shows you that I’ve got Node 10.5.0 installed and have a node_​modules direc­tor for that instal­la­tion of Node.


Node Modules Location Global

`/Users/john/.nvm/versions/node/v10.5.0/lib/node_modules` with global node modules


Check your generators and their version number.

In my case, you can see I’ve got BAB installed. I find I need to check the ver­sion of the gen­er­a­tors I have installed reg­u­lar­ly. The fol­low­ing rather obscure com­mand is how you do that. I have it saved as a text snip­pet on my machine since I can’t remem­ber it eas­i­ly.

npm ls -g --depth=1 2>/dev/null | grep generator-

Here’s what that shows for me.


Node Generator Installed Versions

I’ve got ver­sion 0.10.4 installed. That’s the old ver­sion of BAB and I want my ver­sion in devel­op­ment on my local machine to be shown instead.


Using a local generator globally

So far, so good. Here’s where it might get a lit­tle tricky. It’s not too bad though.

For my BAB project, I want it avail­able glob­al­ly, but I need it some­where else on my file sys­tem so I can work on updat­ing it reg­u­lar­ly. I keep it here:

~/git/generator-buildabanner

I go to that direc­to­ry using a ter­mi­nal pro­gram and link that direc­to­ry using NPM. (Note: Be warned if you’re play­ing along here before get­ting to the end. This will remove your glob­al­ly installed ver­sion entire­ly. You will need to re-install after you’re done.)

npm link

Npm Link Example

A symbolic link from the local git to the global node_modules location is created.


Now let’s check the ver­sion of the installed gen­er­a­tors again.


Npm Updated Version Using Symlink

Version 2.0.0 of the Build A Banner Yeoman generator is installed.


Notice the screen­shot above. The gen­er­a­tor ver­sion num­ber is fol­lowed by an arrow indi­cat­ing that it’s point­ing to a loca­tion to some­where on the local machine oth­er.

If I nav­i­gate to the glob­al node_​modules direc­to­ry, I’d see the pre­vi­ous ver­sion of generator-buildabanner has been replaced by a sym­link. In the Mac Find­er it looks like an alias link. The small arrow on the fold­er indi­cates it’s actu­al­ly point­ing to a dif­fer­ent loca­tion on your file sys­tem, but Node will still use it.


Node Modules Location With Local

Notice the small arrow indicating a symlink.


Removing a symlink

If you need to get rid of that sym­link, there’s an easy to do it. Nav­i­gate back to the loca­tion of your local­ly built project. In my case, that’s ~/git/generator-buildabanner. Enter this unlink com­mand.

npm unlink

Poof. The sym­link is gone. The orig­i­nal ver­sion of the gen­er­a­tor is also gone now. The link com­mand over­wrote it with the local copy. If you need to rein­stall it glob­al­ly in the nor­mal way you’d install a glob­al node mod­ule.

npm install -g generator-buildabanner