Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copying JS Files To Generated Content #3177

Closed
Undistraction opened this issue Dec 10, 2017 · 4 comments
Closed

Copying JS Files To Generated Content #3177

Undistraction opened this issue Dec 10, 2017 · 4 comments

Comments

@Undistraction
Copy link
Contributor

Undistraction commented Dec 10, 2017

Unless I've missed something there is currently no plugin that supports copying JavaScript files across to the the built site so that they can be referenced from the generated pages. If I haven't missed something obvious, I'm wondering if this is worth consideration as a plugin? I'll explain my use-case and hopefully the need will be clear.

I'm working on a personal site that displays a number of small, self contained JS scripts - each one is a visual experiment and effectively renders a visual component which may or may not be interactive. Each one exists as its own npm module and uses rollup to build a self-contained umd module which I will copy into my gatsby project, alongside a markdown file with information about the script and instructions if it is interactive.

My directory structure will look something like this:

- content
  - lab
    - alpha
      - index.js
      - index.md
     - bravo
      - index.js
      - index.md 

Which will be available at the url example.com/lab/alpha, where the page will need to load the script from a relative path.

Just to be absolutely clear: each js file will already be compiled with its dependencies included. It won't need any preprocessing etc. The template will just need to load the script into a container div.

With a generic lab.js template. Everything is easy to set up apart from dealing with the JavaScript file. I figure I can use helmet within the template to add a relative link to the js file, but the question is how to copy the js file from content/lab/alpha to lab/alpha? I understand how to do this, but I'm wondering:

  1. if there is existing functionality for this, and if not …
  2. is it worth discussing a generic plugin?

There is currently gatsby-remark-copy-linked-files but that copies files linked to in markdown, and copies everything to a single directory.

I guess another option is to inline the content of the js file into the generated page within a script tag.

@luczaki114
Copy link
Contributor

I think using Gatsby's static folder is a great use case for this. You can add files that do not need preprocessing in there and all the files are available in dev and production.

src/static
    -alpha.js
    beta
        -beta.js

You can reference those files like so:

localhost:8000/alpha.js
localhost:8000/beta/beta.js

Also, you can read up on it here:
https://www.gatsbyjs.org/docs/adding-images-fonts-files/

@Undistraction
Copy link
Contributor Author

Undistraction commented Dec 10, 2017

@luczaki114 Thanks for the suggestion, but I'd discounted that approach because of the things you lose, namely (as outlined at the link you supplied):

  • Missing files will not be called at compilation time, and will cause 404 errors for your users.
  • Result filenames won’t include content hashes so you’ll need to add query arguments or rename them every time they change.

The second is not so important, but the first is a big loss. Copying the files via a plugin allows for this kind of validation, and would also allow a hash to be appended to the file name. I'm wondering if a generic alternative to static files is worth considering - one that:

  • Checks for existance of files (and raises a compilation error if they are missing).
  • Copies files over to build dir
  • Renames file with a content hash
  • Updates node info

@Undistraction
Copy link
Contributor Author

Undistraction commented Dec 10, 2017

Thinking about this a little more:

gatsby-config.js

{
   resolve: 'gatsby-plugin-copy-js-to-static',
   options: {
      metadataFieldName: ‘jsPath’,
   },
}

content/lab/example.md

---
title: "Code"
date: "2017-08-10"
slug: "code"
description: Sed nisi dolor, fringilla et consectetur eu
keywords: webgl, fractal
jsPath: 'node_modules/example/dist/index.js
---
Here is a quick piece using webgl to produce 3D fractals.

addMetadataToNode()

  • Checks node for metadata field defined in options.metadataFieldName
  • If field is found, existence of the file is verified with an error if it isn’t at the path.
  • If the file exists it is hashed and copied to static with original filename+hash.
  • createNodeField() is used to save staticJsPath to node.

createPages()

  • staticJsPath is exposed to the page using context in createPage().

templates/lab

  • helmet is used to populate script tag with staticJsPath from GraphQL query
  • JS file exposes a function that can be passed a DOM node to render to.

There is also the option if the path is to an npm module to pull out some metadata from the package.json - version, name, etc.

@KyleAMathews
Copy link
Contributor

MDX sounds like a great solution for this!

Due to the high volume of issues, we're closing out older ones without recent activity. Please open a new issue if you need help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants