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

Issue with JSON values containing dash (-) or dot (.) #2292

Closed
pixelpeter opened this issue Jun 2, 2022 · 4 comments
Closed

Issue with JSON values containing dash (-) or dot (.) #2292

pixelpeter opened this issue Jun 2, 2022 · 4 comments

Comments

@pixelpeter
Copy link

esbuild: 0.14.42
MacOs: 12.4
NodeJS: 16.15.0

While running this JavaScript file (not TypeScript) on the console with node build.js

// build.js

const dotenv = require('dotenv')
const fs = require('fs');
const path = require('path');
const esbuild = require('esbuild');
const functionsDir = `../lambdas`;
const outDir = `dist`;
const entryPoints = fs
    .readdirSync(path.join(__dirname, functionsDir))
    .map(entry => `${functionsDir}/${entry}/index.js`);


// const test = { FOO: "foo_bar" }; // working
// const test = { "FOO": "foo_bar" }; // working
// const test = { FOO: "foo-bar" }; //  'Invalid define value (must be valid JSON syntax or a single identifier): foo-bar'
// const test = { "FOO": "foo-bar" }; //  'Invalid define value (must be valid JSON syntax or a single identifier): foo-bar'
// const test = { FOO: "foo.bar" }; //  'Invalid define value (must be valid JSON syntax or a single identifier): foo.bar'
const test = { "FOO": "foo.bar" }; //  'Invalid define value (must be valid JSON syntax or a single identifier): foo.bar'

esbuild
    .build({
        entryPoints,
        bundle: true,
        outdir: path.join(__dirname, outDir),
        outbase: functionsDir,
        platform: 'node',
        sourcemap: 'inline',
        define: test
    });

When the JSON value is foo_bar everything is working fine 👍🏼

When the JSON value is foo-bar or foo.bar I will get this error

errors: [
    {
      detail: undefined,
      location: null,
      notes: [],
      pluginName: '',
      text: 'Invalid define value (must be valid JSON syntax or a single identifier): foo.bar'
    }
  ],

Can somebody please tell me what I'm doing wrong?
Thanks in advance

@hyrious
Copy link

hyrious commented Jun 2, 2022

That's said, the value of the record in define must be a valid json value which can be literals (123, true, "string", [null]), or a variable name (foo). esbuild parses this string into js ast node, so it needs it to be valid.

If you need to replace some variable with complex initializing codes, you can use define and inject together to make that happen. For example:

// FOO-shims.js
export let foo_bar = foo.bar;

// index.js
console.log(process.env.FOO);

Then run: esbuild index.js --inject:FOO-shims.js --define:process.env.FOO=foo_bar.

// output
var foo_bar = foo.bar;
console.log(foo_bar);

@evanw
Copy link
Owner

evanw commented Jun 2, 2022

Are you really trying to replace FOO with foo-bar (foo minus bar)? Or are you trying to replace it with the string "foo-bar"? If you want a string, you need to quote the input. The documentation describes this in more detail: https://esbuild.github.io/api/#define. foo-bar is not valid JSON because JSON doesn't allow the subtraction operator, but "foo-bar" is valid JSON because JSON allows string literals:

> JSON.parse('foo-bar')
Uncaught SyntaxError: Unexpected token o in JSON at position 1

> JSON.parse('"foo-bar"')
'foo-bar'

If you are unfamiliar with how JSON works, the JSON specification has an excellent visual representation of what is allowed as a valid JSON value: https://www.json.org/json-en.html.

@kskalski
Copy link

kskalski commented Jun 4, 2022

Is dot reference not considered an 'identifier'? I'm trying to create define that injects process.env, but I'm getting error

Invalid define value (must be valid JSON syntax or a single identifier): process.env

It doesn't seem there is way to express dot reference as any valid JSON or a single identifier, what is the suggested solution in that case?

@hyrious
Copy link

hyrious commented Jun 4, 2022

Is dot reference not considered an 'identifier'?

Yes, it actually wants a single variable name.

I'm trying to create define that injects process.env

See the inject api like what I did in previous comment.

However, in your referenced issue I see someone is doing define: { 'process.env': 'process.env' }. This is not allowed in esbuild at least from 0.10.x. So I guess the author was relying on a vite feature that do the string replacement by themselves instead of in esbuild define config.

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

4 participants