3

With the following node.js code:

import { fileURLToPath } from 'node:url';
import path from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));

I am seeing the following lint error relating to the import.meta.url reference:

enter image description here

This snippet is to replicate __filename and __dirname in ESM as per node.js guidance. The same error is given when using import.meta.url as follows... which is also in the official guidance:

import { readFileSync } from 'fs';
const buffer = readFileSync(new URL('./data.proto', import.meta.url));

I have looked at this but it doesn't solve my problem. This is specifically within the Cloud9 IDE... not the current AWS Cloud9 but a self-hosted Cloud9 based on this repo (last updated 4 years ago). The only guidance from (AWS) Cloud9 is on this page:

enter image description here

I can get certain basic rules to work using this .eslintrc file, e.g.

{
  rules: {
    semi: ["error", "never"]
  }
}

enter image description here

So I know that the config file is taking effect in the IDE. But can't see the appropriate rule to disable the "unexpected token import" error.

EDIT: the following seem relevant but I cannot determine if it has ever really reached a conclusion:

https://github.com/eslint/eslint/issues/12518

https://github.com/eslint/eslint/pull/13196

https://github.com/eslint/eslint/issues/13133

drmrbrewer
  • 11,491
  • 21
  • 85
  • 181

1 Answers1

5

This is actually an educated guess, since I'm not using the Cloud9 IDE. If your .eslintrc file is being recognized, what you need to add there are the proper parser options, e.g.:

{
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module"
  },
  "rules": {
    "semi": ["error", "never"]
  }
}

The reason is that the ESLint parser treats by default all JavaScript sources as ES5 scripts, while the import.meta syntax is only allowed in modules since ECMAScript 2020.

Update

The setting "ecmaVersion": 2020 is supported in ESLint 6 onwards. Another option to have import.meta recognized is using a custom parser like Babel. The packages to install for the Babel parser are @babel/core and @babel/eslint-parser. And the relevant settings in .eslintrc are here:

{
  "parser": "@babel/eslint-parser",
  "parserOptions": {
    "ecmaVersion": 2020,
    "requireConfigFile": false
},

Note: I couldn't find out which versions of ESLint are supported by the Babel parser in the documentation in their repo (link above). I can only see in the code that ESLint 7 and 8 are supported. If the current version of Babel does not work with your version of ESLint, you may have to try installing older releases and see if they work. And in that case, an additional plugin like syntax-import-meta may be required.

GOTO 0
  • 42,323
  • 22
  • 125
  • 158
  • Sadly this doesn't work. In fact, adding the parser options stops the `semi` rule from working. I notice that after hitting newline in the editor, an error indication pops up briefly in the margin and then disappears... if I hover over it before it vanishes I see that it says: `Parsing error: Invalid ecmaVersion`. Perhaps the ESLint parser baked into this version of Cloud9 (frozen for 4 years) just won't support new parser versions? – drmrbrewer Nov 18 '21 at 07:56
  • It seems that `2018` is that last `ecmaVersion` that doesn't result in `Invalid ecmaVersion`. Is this version of Cloud9 just doomed or is there a way to set custom rules to disable particular checks? Or perhaps it might be possible to fork the [Cloud9 repo](https://github.com/c9/core) and update the parser? This Cloud9 version is still a very capable IDE despite lacking any update for 4 years. – drmrbrewer Nov 18 '21 at 08:16
  • 1
    If I understand [the code](https://github.com/c9/core/blob/7e1ac98f51b85e8bed401c593774ef73ada3cd07/plugins/c9.ide.language.javascript.eslint/packager/package.json#L10) correctly, the IDE uses ESLint 4 (current is 8). If you cannot update ESLint in the repo you could try the Babel parser, but I'm not sure if it still works with ESLint 4. – GOTO 0 Nov 18 '21 at 08:19
  • 1
    I'll see if I can update the version of the `eslint` dependency. Before posting this question I did investigate using the Babel parser but couldn't figure it out because it seemed to require installing it as a dev dependency for a particular project, and as such it wouldn't be available as a parser option in this global .eslintrc file. – drmrbrewer Nov 18 '21 at 08:30
  • I tried updating all dependencies in the `package.json` you linked to in the C9 repo and re-built the IDE based on this fork... sadly no change. Do you have any hints about how Babel parser might be used in this sort of context, where a global .eslintrc config file is being used? – drmrbrewer Nov 18 '21 at 10:40
  • I updated my answer. Remember that you will have to install the Babel packages in your dependencies rather than in the dev dependencies for them to be available at runtime. – GOTO 0 Nov 18 '21 at 11:45
  • Thanks for the update. You say "you will have to install the Babel packages in your dependencies"... sorry for being thick, but this is where I get confused... what "dependencies" are we talking about here? For the Cloud9 IDE itself? Because the linter is just working on a file that opens for editing in the IDE... I'm not compiling or transpiling or doing anything like that which would cause the dependencies associated with the package itself (containing the relevant file) to be read. – drmrbrewer Nov 18 '21 at 13:21
  • Maybe in the same package.json where ESLint is listed inside the "dependencies"? (https://github.com/c9/core/blob/7e1ac98f51b85e8bed401c593774ef73ada3cd07/plugins/c9.ide.language.javascript.eslint/packager/package.json) - It looks like babel-core is already installed there, though it's an old version. – GOTO 0 Nov 18 '21 at 13:48
  • OK I'll need to do some more digging, because it's not even apparent to me that the c9 build process ever does an `npm install` based on that package.json... certainly in the `/cloud9` folder left in the container after the build process, there is no `node_modules` folder in there... and in fact no `eslint` folder anywhere on the filesystem at all. – drmrbrewer Nov 18 '21 at 14:13
  • The more I look into this, the more I think that Cloud9 uses a slightly bespoke implementation of eslint: see [here](https://github.com/c9/core/issues/251#issuecomment-186386107)... seems that a [browserified version of eslint](https://github.com/c9/c9.ide.language.javascript.eslint/blob/master/worker/eslint_browserified.js) is included in the repo, and hence why the versioning in `package.json` doesn't seem to have any effect... I think the `setup.sh` script in the `packager` folder should generate the browserified eslint file, but it didn't work for me when I ran it. – drmrbrewer Nov 18 '21 at 17:22
  • 1
    OMG, that's creepy. That Cloud9 repo is archived but it has [a lot of forks](https://github.com/c9/core/network/members). If I had to work on it, I would start looking there in case someone already did the job of upgrading the dependencies, sometimes miracles happen. I'm sorry I could not help. Good look! – GOTO 0 Nov 18 '21 at 18:22
  • Thanks, it's a great help to know that there isn't anything obvious I'm missing. I did also think it would be good to look at the forks... in theory this should help identify the best candidates... but it doesn't seem to work 100% as it should: https://techgaun.github.io/active-forks/index.html#c9/core (looks like dependabot pull requests mess up the results). – drmrbrewer Nov 18 '21 at 19:17
  • 1
    That tool works well enough to narrow down the search, and it seems that there are no useful forks :-( Perhaps time to investigate other self-hosted options, e.g. vscode looks good: https://code.visualstudio.com/docs/nodejs/working-with-javascript – drmrbrewer Nov 18 '21 at 19:24