├── .npmrc
├── .npmignore
├── example
├── cached
│ ├── file1.md
│ └── file2.gif
├── .gitignore
├── README.md
├── index.html
├── package.json
└── netlify.toml
├── .gitignore
├── manifest.yml
├── .github
└── workflows
│ └── ci.yml
├── LICENSE
├── package.json
├── index.js
└── README.md
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .github/
2 | .netlify/
3 | example/
4 |
--------------------------------------------------------------------------------
/example/cached/file1.md:
--------------------------------------------------------------------------------
1 | This is a file. A cached file.
2 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Local Netlify folder
2 | .netlify
3 |
4 | cache-output.json
5 | package-lock.json
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local Netlify folder
2 | .netlify
3 |
4 | node_modules/
5 | package-lock.json
6 | npm-debug.log*
7 |
--------------------------------------------------------------------------------
/example/cached/file2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakejarvis/netlify-plugin-cache/HEAD/example/cached/file2.gif
--------------------------------------------------------------------------------
/manifest.yml:
--------------------------------------------------------------------------------
1 | name: netlify-plugin-cache
2 | inputs:
3 | - name: paths
4 | description: Array of files and/or directories to cache between builds.
5 | default: [".cache"]
6 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.netlify.com/sites/infallible-wing-581e78/deploys)
2 |
3 | https://infallible-wing-581e78.netlify.app/cache-output.json
4 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hello world!
5 | This is an example of netlify-plugin-cache. ⚡
6 | 
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "netlify-plugin-cache-example",
4 | "version": "1.0.0",
5 | "description": "Just a test of netlify-plugin-cache.",
6 | "dependencies": {
7 | "netlify-plugin-cache": "file:../",
8 | "netlify-plugin-debug-cache": "^1.0.3"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/example/netlify.toml:
--------------------------------------------------------------------------------
1 | # only used in this example to build from parent directory
2 | [[plugins]]
3 | package = "@netlify/plugin-local-install-core"
4 |
5 | # package would normally equal `netlify-plugin-cache`
6 | [[plugins]]
7 | package = "../"
8 | [plugins.inputs]
9 | paths = ["cached"]
10 |
11 | [[plugins]]
12 | package = "netlify-plugin-debug-cache"
13 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 | strategy:
8 | matrix:
9 | node: [14.x, 13.x, 12.x, 10.x]
10 | fail-fast: false
11 | runs-on: ubuntu-latest
12 | name: Node ${{ matrix.node }}
13 | steps:
14 | - uses: actions/checkout@v2
15 | - uses: actions/setup-node@v1
16 | with:
17 | node-version: ${{ matrix.node }}
18 | - name: Install dependencies
19 | run: npm install --no-package-lock --no-optional
20 | - name: Run tests
21 | run: npm run test
22 | - name: Build example site locally with plugin
23 | run: npm run build
24 | env:
25 | NETLIFY_SITE_ID: '8ceb6251-650b-481a-976c-fec1a4f95800'
26 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Jake Jarvis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "netlify-plugin-cache",
3 | "version": "1.0.3",
4 | "description": "Generic cache plugin for saving and restoring files and/or folders between Netlify builds",
5 | "license": "MIT",
6 | "author": {
7 | "name": "Jake Jarvis",
8 | "email": "jake@jarv.is",
9 | "url": "http://jarv.is/"
10 | },
11 | "homepage": "https://github.com/jakejarvis/netlify-plugin-cache#readme",
12 | "bugs": "https://github.com/jakejarvis/netlify-plugin-cache/issues",
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/jakejarvis/netlify-plugin-cache.git"
16 | },
17 | "main": "index.js",
18 | "scripts": {
19 | "build": "netlify build",
20 | "test": "xo"
21 | },
22 | "dependencies": {},
23 | "devDependencies": {
24 | "netlify-cli": "*",
25 | "xo": "~0.32.0"
26 | },
27 | "engines": {
28 | "node": ">=10.18"
29 | },
30 | "keywords": [
31 | "netlify",
32 | "netlify-plugin",
33 | "cache",
34 | "ci",
35 | "build",
36 | "plugin"
37 | ],
38 | "xo": {
39 | "semicolon": false,
40 | "space": 2,
41 | "rules": {
42 | "object-curly-spacing": 0
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // Netlify Plugin: netlify-plugin-cache
2 | // https://github.com/jakejarvis/netlify-plugin-cache
3 | //
4 | // This plugin is essentially a wrapper around Netlify's native `cache-utils`:
5 | // https://github.com/netlify/build/blob/master/packages/cache-utils/README.md
6 |
7 | module.exports = {
8 | // Try to restore cache before build begins, if it exists
9 | onPreBuild: async ({ utils: { cache }, inputs }) => {
10 | if (await cache.restore(inputs.paths)) {
11 | const files = await cache.list(inputs.paths)
12 | console.log(`Successfully restored: ${inputs.paths.join(', ')} ... ${files.length} files in total.`)
13 | } else {
14 | console.log(`A cache of '${inputs.paths.join(', ')}' doesn't exist (yet).`)
15 | }
16 | },
17 |
18 | // Only save/update cache if build was successful
19 | onSuccess: async ({ utils: { cache, status }, inputs }) => {
20 | if (await cache.save(inputs.paths)) {
21 | const files = await cache.list(inputs.paths)
22 | console.log(`Successfully cached: ${inputs.paths.join(', ')} ... ${files.length} files in total.`)
23 |
24 | // Show success & more detail in deploy summary
25 | status.show({
26 | title: `${files.length} files cached`,
27 | summary: 'These will be restored on the next build! ⚡',
28 | text: `${inputs.paths.join(', ')}`
29 | })
30 | } else {
31 | // This probably happened because the default `paths` is set, so provide instructions to fix
32 | console.log(`Attempted to cache: ${inputs.paths.join(', ')} ... but failed. :(`)
33 | console.log('Try setting the \'paths\' input appropriately in your netlify.toml configuration.')
34 | console.log('More details: https://jrvs.io/netlify-cache-usage')
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ⚡ Netlify Plugin: Custom Cache [](https://www.npmjs.com/package/netlify-plugin-cache) 
2 |
3 | A generic cache plugin for saving and restoring files and/or folders between Netlify builds for impressive speed improvements. Worry less about running out of build minutes! ⏰
4 |
5 | Essentially, this plugin is a pretty wrapper around [Netlify's native cache utility](https://github.com/netlify/build/blob/master/packages/cache-utils/README.md) — it isn't tied to any specific static site generator (on purpose).
6 |
7 | ## 💿 Install
8 |
9 | Add the following lines to your `netlify.toml`:
10 |
11 | ```toml
12 | [[plugins]]
13 | package = "netlify-plugin-cache"
14 | [plugins.inputs]
15 | # Optional (but highly recommended). Defaults to [".cache"].
16 | paths = ["resources", "_vendor", "folder/file.md"]
17 | ```
18 |
19 | This plugin only takes one input named `paths`: an array of files and/or directories relative to your project's root. These files/directories are restored before a build and saved in cache after a build **if it is successful**.
20 |
21 | **🚨 Important:** `paths` defaults to `[".cache"]`, but it's **highly recommended** you set this yourself based on the tool(s) you're using to generate your site. See examples below.
22 |
23 | Read more about plugin configuration at [the official Netlify Plugin docs](https://docs.netlify.com/configure-builds/build-plugins/#install-a-plugin).
24 |
25 | ## 👩💻 Usage
26 |
27 | - **Hugo:** Caching the `resources` directory can speed up your build greatly if you [process](https://gohugo.io/content-management/image-processing/) a lot of images, or compile SASS/SCSS via Hugo pipes. You can also cache the `public` directory to avoid completely rebuilding the entire site on each deploy. [More info here.](https://gohugo.io/getting-started/directory-structure/#directory-structure-explained)
28 | - **Gatsby:** By default, the `.cache` directory holds persistent data between builds. You can also cache the `dist` directory to avoid completely rebuilding the entire site on each deploy. [More info here.](https://www.gatsbyjs.org/docs/build-caching/)
29 | - **Jekyll:** A caching API was added as of v4. The notoriously slow SSG can become (relatively) faster by caching the `.jekyll-cache` directory. [More info here.](https://jekyllrb.com/tutorials/cache-api/)
30 | - **Next.js:** The `.next` directory holds the build output. [More info here.](https://nextjs.org/docs/api-reference/next.config.js/setting-a-custom-build-directory)
31 | - **Anything else:** This is the reason I kept this plugin as generic as possible! Research the caching behavior of your static site generator (and how to customize it if necessary). Feel free to open a PR and list it here as well!
32 |
33 | ## 🐛 Debugging
34 |
35 | This plugin doesn't provide a way to output a list of files that were cached or restored, because Netlify already provides an official plugin named [`netlify-plugin-debug-cache`](https://github.com/netlify-labs/netlify-plugin-debug-cache) to do exactly that. No need to re-invent the wheel!
36 |
37 | You can add the debug plugin **after** this plugin in your `netlify.toml`. (And yes, you need a `[[plugins]]` line for _each_ plugin you add.)
38 |
39 | ```toml
40 | [[plugins]]
41 | package = "netlify-plugin-debug-cache"
42 | ```
43 |
44 | The debug plugin will generate a file named `cache-output.json` at the root of your project's publish directory. [See an example file](https://infallible-wing-581e78.netlify.app/cache-output.json) or [learn more about this plugin](https://github.com/netlify-labs/netlify-plugin-debug-cache).
45 |
46 | ## 📜 License
47 |
48 | This project is distributed under the [MIT license](LICENSE).
49 |
--------------------------------------------------------------------------------