# Jekyll, Bundler and NPM

**URL:** <https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203>\
**Category:** Help\
**Created:** [November 9, 2020, 5:29pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203 "2020-11-09T17:29:04Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Koos](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@Koos](https://talk.jekyllrb.com/u/Koos)\
**Post date:** [November 9, 2020, 5:29pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/1 "2020-11-09T17:29:04Z")

</div>

I’m wondering: has someone had good experiences with combining NPM with Bundler and Jekyll? I’d like to set up a simple way of managing JavaScript dependencies. I have never set up a JS bundling setup from scratch. Ideally, I’d only have:

- One dependency manager to ask for installing or updating the setup (not sure if this is even possible or desirable, but somehow combining two package managers feels wrong)
- One command to start the dev server (e.g. `npm run dev`)
- One command to start a site build (e.g. `npm run build`)

I guess I also need something like Grunt or Parcel to combine the JS files?

Background is that I want to add Alpine.js. I already have several JS files that I combine using includes and that feels messy.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 10, 2020, 1:09pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/2 "2020-11-10T13:09:57Z")

</div>

Hi Koos

I know your struggle and have a solution fr you. GitHub Pages does not support custom builds with NPM etc. But you can use GitHub Actions with a config of like 100 lines or Netlify with a config of a few lines.

Some Ruby or Jekyll projects use `rake` to manage npm install and other tasks but I struggle to get into it.

My approach is to use a `Makefile` and call it with `make` command. That comes from the C compilation background but you’ll also see it in Python and C++ projects. It comes with mac and linux and I think you can install on windows

Here is my simple Jekyll related makefile.

> <https://github.com/MichaelCurrin/jekyll-blog-demo/blob/master/Makefile>

To use it:

```auto
cd repo
make install
make build

```

And now the site is built.

Run those commands on GitHub Actions or your remote server and it will work the same. On Netlify you don’t even need to run make install as Netlify finds a Gemfile and package.json and installs for you.

I use a Makefile for all my Jekyll projects as it let’s me manage by commands easily and I can run multiple tasks underneath like NPM and Bundle steps to install or build.

For example to you can define commands as

```auto
install-js:
	npm install

install-gems:
	bundle config set --local path vendor/bundle
	bundle install

install: install-js install-gems

```

Which means when you run

```auto
make install

```

It runs

```auto
npm install
bundle config...
bundle install

```

And you can define build as

```auto
build:
  npm run build
  bundle exec jekyll build --trace

```

So you just have to run `make build` and it will run both commands.

And then you would have `make build` as the build step in your Netlify config or GH Actions workflow.

Note that make will exit on failure so it effectively does

```auto
npm run build && bundle exec ...

```

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 10, 2020, 1:13pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/3 "2020-11-10T13:13:22Z")

</div>

Regarding using parcel etc.

You can define that in your package.json file. So that `npm run build` will run a parcel command and then react build etc.

Or you can move everything to makefile

So

```auto
build: lint
  parcel foo
  react build bar
  bundle exec jekyll build --trace

```

Above I also define that `make lint` always runs before the other commands in the build command.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 10, 2020, 1:16pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/4 "2020-11-10T13:16:24Z")

</div>

And you can define a dev command like this. Here I assume you build a static npm site rather than have it running as a dev server.

```auto
dev:
  npm run build
  bundle exec jekyll serve --trace

```

If your Jekyll site needs to point to a server side node app, then you’ll have to start that node app in another terminal window when running your Jekyll dev server

---

<div class="post-metadata">

**Author:** ![Koos](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@Koos](https://talk.jekyllrb.com/u/Koos)\
**Post date:** [November 10, 2020, 1:57pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/5 "2020-11-10T13:57:23Z")

</div>

Thanks, that’s pretty simple 🙂 I’m not on Github pages, so I think I could just as well do that with a bash script? Not sure about the mac-specificness of that though, maybe Makefiles have better support.

---

<div class="post-metadata">

**Author:** ![Koos](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@Koos](https://talk.jekyllrb.com/u/Koos)\
**Post date:** [November 10, 2020, 1:59pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/6 "2020-11-10T13:59:34Z")

</div>

> [@MichaelCurrin](#):
>
> ```auto
> dev:
> npm run build
> bundle exec jekyll serve --trace
> 
> ```

But this way you manually have to rebuild and refresh with every JS change, right?

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 10, 2020, 6:50pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/7 "2020-11-10T18:50:39Z")

</div>

Make is available on mac and linux and will run bash commands.

You can choose to run then bash commands directly like with an alias on your machine.

A makefile is a nice versioned way to share commands across your machines and across local and CI flows

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 10, 2020, 6:58pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/8 "2020-11-10T18:58:13Z")

</div>

Yes you have to stop and start the dev step to build the JS.

But you could use `npm run watch` in another tab to build and then continuously look for changed Js files and rebuild. I’m not so familiar with it but have see it in some JS projects.

If you want to run the two command at the same time in one terminal, you can use this `concurrently` package.

> **[concurrently](https://www.npmjs.com/package/concurrently#usage)**
>
> Run commands concurrently

The example is within package.json start command so it is implied that it it runs node\_modules/bin/concurrently or similar

You could try use it in your make command. Dont know if this works. Use npx as a shortcut for the Node Modules path.

```auto
dev:
  npx concurrently 'npm run watch' 'bundle exec jekyll s

```

You can also try parallel jobs in make, here calling two targets.

```auto
make -j 2 watch-js jekyll-serve

```

If that that works you could turn _that_ into a make command.

```auto
dev:
   make -j 2 watch-js jekyll-serve

```

---

<div class="post-metadata">

**Author:** ![Koos](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@Koos](https://talk.jekyllrb.com/u/Koos)\
**Post date:** [November 13, 2020, 10:49am UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/9 "2020-11-13T10:49:57Z")

</div>

Thanks, I’m going to try that out. Just to make sure I understand the approach: the idea is that the bundler and npm watch/build processes run in parallel (not serial) and there’s not actual relationship between the two other than the make file?

What’s not clear to me yet: how do you let the browser connected to the dev server reload on changes to html and assets including JS?

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 13, 2020, 1:26pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/10 "2020-11-13T13:26:07Z")

</div>

That’s correct. The processes start and stop at the same time but they don’t know about each other

Get it to work in too terminal tabs first and the try the one terminal parallel approach.

Also bear in mind that a rebuild of npm assets to `assets` will also trigger Jekyll to rebuild but that should be a good flow.

Jekyll serve has a flag for `--livereload` to refresh the browser on file changes and based on my previous paragraph it will pick up JS changes too.

I hope that outputting 10 JS assets doesnt cause 10 rebuilds in the same second. Maybe you can set a wait flag along with the hot reload flag, or just make sure you output as few JS files as possible

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 13, 2020, 1:30pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/11 "2020-11-13T13:30:57Z")

</div>

I have a copy of jekyll CLI flags near the bottom here

> **[Run](https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/jekyll/run.html)**
>
> A collection of code snippets and CLI guides for quick and easy reference while coding

---

<div class="post-metadata">

**Author:** ![brad](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/brad/32/2543_2.png) [@brad](https://talk.jekyllrb.com/u/brad)\
**Post date:** [November 13, 2020, 5:19pm UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/12 "2020-11-13T17:19:26Z")

</div>

A possible alternative using `alias`:

Let’s say I wanted to run a npm watch script at the same time as a Jekyll build/serve command. I’d install [parallelshell](https://www.npmjs.com/package/parallelshell) and add something like the below to my bash\_aliases file:

alias serve=‘parallelshell “bundle exec jekyll serve --livereload” “npm run watch-js”’

Then in my terminal all I have to type is `serve`.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 14, 2020, 7:36am UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/13 "2020-11-14T07:36:31Z")

</div>

That is similar to concurrently I suggest above. Haven’t used either but here is a comparison

> **[Google](https://npmcompare.com/compare/concurrently,npm-run-all,parallelshell)**
>
> Celebrating Maria Tallchief! #GoogleDoodle

My hope is that make with parallel job flag will do this without relying on an external library

Also the problem is not that bad if you accept creating a 2nd terminal and leaving it running while your work on your site for a few hours or even days.

---

<div class="post-metadata">

**Author:** ![ginfuru](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/ginfuru/32/773_2.png) [@ginfuru](https://talk.jekyllrb.com/u/ginfuru)\
**Post date:** [March 16, 2021, 11:48am UTC](https://talk.jekyllrb.com/t/jekyll-bundler-and-npm/5203/14 "2021-03-16T11:48:59Z")

</div>

I have a project called flightdeck that uses NPM scripts to achieve what you’re wanting.

> **[flight-deck/flightdeck-jekyll](https://github.com/flight-deck/flightdeck-jekyll)**
>
> 🚀 Flightdeck is an opinionated starter project for Jekyll using a modern front-end workflow
