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

JSON files (and other types of dependencies different from JS modules) should not be passed to acorn to be parsed #4

Closed
DmitrySharabin opened this issue Dec 25, 2024 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@DmitrySharabin
Copy link

DmitrySharabin commented Dec 25, 2024

I stumbled upon this issue while trying to fix the watch mode in one of the projects built with Eleventy.

For now, we pass the contents of such files to acorn.parse():

let ast = acorn.parse(contents, {sourceType: "module", ecmaVersion: "latest"});

acorn, in its turn, throws the SyntaxError: Unexpected token error (as far as I understand, acorn tries to parse the file content as a JS statement but fails).

Because of this error, the watch mode is still broken even in Eleventy v3.0.1-alpha.1. 😔

You can see the issue in action by replacing the test in test/stubs/imported.json, for example, with this one:

-{}
+{
+	"foo": "bar"
+}
image

There still might be a chance that I'm missing something.

@jgarber623
Copy link

jgarber623 commented Jan 3, 2025

I believe I've encountered this issue as well using import attributes in eleventy.config.js using Node.js v22.12.0 ("lts/jod"), Eleventy v3.0.1-alpha.1, and npx eleventy --serve.

In a bare bones project, npx eleventy correctly builds the site without error, but npx eleventy --serve throws an error:

[11ty] Writing ./_site/README/index.html from ./README.md (liquid)
[11ty] Wrote 1 file in 0.06 seconds (v3.0.1-alpha.1)
[11ty] Eleventy Error (watch CLI):
[11ty] 1. A problem was encountered looking for JavaScript dependencies in ESM file: ./eleventy.config.js. This only affects --watch and --serve behavior and does not affect your build. (via EleventyBaseError)
[11ty] 2. Unexpected token (1:8) (via SyntaxError)
[11ty] 
[11ty] Original error stack trace: SyntaxError: Unexpected token (1:8)
[11ty]     at pp$4.raise (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:3646:15)
[11ty]     at pp$9.unexpected (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:772:10)
[11ty]     at pp$9.semicolon (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:749:68)
[11ty]     at pp$8.parseExpressionStatement (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:1244:10)
[11ty]     at pp$8.parseStatement (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:965:26)
[11ty]     at pp$8.parseBlock (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:1260:23)
[11ty]     at pp$8.parseStatement (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:930:38)
[11ty]     at pp$8.parseTopLevel (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:829:23)
[11ty]     at Parser.parse (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:601:17)
[11ty]     at Function.parse (eleventy-import-attributes-test/node_modules/acorn/dist/acorn.js:651:37)

This only seems to happen when the imported JSON file is a non-empty object. An empty object ({}), an empty array ([]), and a non-empty array (["foo", "bar"]) do not trigger this error when the --serve or --watch flags are passed.

Reproducible Test Case

  1. Create the following files:

package.json

{
  "name": "eleventy-import-attributes-test",
  "type": "module",
  "devDependencies": {
    "@11ty/eleventy": "3.0.1-alpha.1"
  }
}

eleventy.config.js

import app from "./app.json" with { type: "json" };

export default async function(eleventyConfig) {}

app.json sample file

{ "name": "eleventy-import-attributes-test" }
  1. Set local Node.js to v22.12.0 ("lts/jod") using your preferred version manager or what have you.
  2. npm install
  3. npx eleventy (note that _site is generated)
  4. npx eleventy --serve (note the error above)

--watch also throws a similar error.

@jgarber623
Copy link

Working my way through the test suite and the structure of acorn.parse and whatnot. For a node with an import attribute:

import eleventyPackage from "./imported.json" with { type: 'json' };

…the resulting Node instance looks somewhat like:

Node {
  type: 'ImportDeclaration',
  start: 0,
  end: 68,
  specifiers: [
    Node {
      type: 'ImportDefaultSpecifier',
      start: 7,
      end: 22,
      local: [Node]
    }
  ],
  source: Node {
    type: 'Literal',
    start: 28,
    end: 45,
    value: './imported.json',
    raw: '"./imported.json"'
  },
  attributes: [
    Node {
      type: 'ImportAttribute',
      start: 53,
      end: 65,
      key: [Node],
      value: [Node]
    }
  ]
}

What I think we care about is the attributes property, shown here in full:

[
  Node {
    type: 'ImportAttribute',
    start: 53,
    end: 65,
    key: Node { type: 'Identifier', start: 53, end: 57, name: 'type' },
    value: Node {
      type: 'Literal',
      start: 59,
      end: 65,
      value: 'json',
      raw: "'json'"
    }
  }
]

This is Acorn's representation of { type: "json" }. Neat! We can work with that.

When encountering a Node of this type, this package will want to add the file path (e.g. ./test/stubs/imported.json) to sources but not recursively parse that file.

I don't have a solution yet, but there'll need to be some updates in findByContents to accommodate. 🤔

@zachleat zachleat self-assigned this Jan 9, 2025
@zachleat
Copy link
Member

zachleat commented Jan 9, 2025

Howdy y’all! Confirmed that this is a bug with our package here. The fix will go up with v1.0.3 v1.0.2 of this package.

@zachleat zachleat added this to the v1.0.2 milestone Jan 9, 2025
@zachleat
Copy link
Member

zachleat commented Jan 9, 2025

This will roll up with Eleventy v3.0.1-alpha.2

@zachleat zachleat added the bug Something isn't working label Jan 9, 2025
@zachleat
Copy link
Member

zachleat commented Jan 9, 2025

You can also npm install @11ty/[email protected] into your project to get the fix now!

@jgarber623
Copy link

@zachleat Hero! Thanks for the fix. I’ll give it a try later tonight or tomorrow.

@jgarber623
Copy link

Follow up: Got this working great on an Eleventy v3.0.0 project by deleting package-lock.json and re-running npm install which picked up the v1.0.2 version of this package.

Works like a charm!

// eleventy.config.js
import manifest from "./src/manifest.webmanifest.json" with { type: "json" };

export default function(eleventyConfig) {
  eleventyConfig.addGlobalData("app", manifest);

  // etc. etc. etc.
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants