If I write a script and distribute it, Deno should know if it can run it.
I think this is really important for supporting the vision of portable scripts.
It would be awesome to be able to run scripts on any machine with deno without a second thought. I think that's in alignment with the vision of the project.
There are two big things that ensure that portability and trust.
A simple case would be if I were using optional chaining. How does deno know that a module that's being loaded will be compatible. I guess the typescript compiler will choke on syntax it doesn't understand (in a particular version), but is that the experience we want?
Deno globalI imagine this would be the same case. Deno would see that it doesn't have a property on the Deno global during the compilation process, but the user wouldn't inherently understand that they just need a later version of deno.
I don't have a specific idea for how we'd accomplish this. One naive idea / straw man would be to have simple comment at the beginning of the file.
// @deno min 1.0
import somethingElse from './somewhereElse.ts'
// @deno minTs 3.6
import somethingElse from './somewhereElse.ts'
I think this will just get in the way, to be honest. There is a long history of people getting it wrong, making wrong assumptions about what is really required, etc. I think if and when we get to the point where we introduce a backwards incompatible change, we should potentially tackle this, but not before, and it should come with good examples of how expressing this actually solves something. Expressing a requirement or dependency without knowing why you are expressing it is not good.
This doesn't offer any more than the ability to do a runtime check on Deno.version.
As for static stuff like new syntax... the problem applies to any coding environment. As long as it doesn't run and do something unexpected the version can be documented/investigated like it normally is.
I agree that it's not that pressing yet and that there's some room for people to use it incorrectly. One potential approach could be to attempt to run the file anyway, but have a better message if it does fail during compilation.
Regardless, I think the issue is foreseeable and tangible. I can imagine issues being opened often on projects where all the user would need to do is update deno.
// @deno minTs 3.7
const a: string | null = null
const message = null
console.log(message ?? 'Hello!')
deno todayerror TS1109: Expression expected.
â–º file:///Users/user/code/deno-null/example.ts:6:22
6 console.log(message ?? 'Hello!')
^
error TS1005: ':' expected.
â–º file:///Users/user/code/deno-null/example.ts:6:32
6 console.log(message ?? 'Hello!')
^
Found 2 errors.
denoâ–º file:///Users/user/code/deno-null/example.ts requires typescript 3.7.0 or later.
It looks like you are using deno 0.20.0 with typescript 3.6.3.
Try upgrading deno!
But everyone authoring code would have to know when the special syntax they are using was introduced.
That seem onerous and prone to errors. You don't get a browser saying "upgrade your browser to a specific version because you are using unsupported syntax" and you don't have people putting minimum version of JavaScript in their code.
Applications do often have prompts for users to upgrade/switch browsers if their browser is unsupported / old.
Aside from that, developers have to worry about it. When they don't use a prompt to upgrade, they target an older version of javascript. That's why we have so much tooling for transpiling, polyfilling, and targeting browser compatibility. There's babel, typescript's target option, lint rules, browserlist and preset-env, etc etc.
On the node/npm side of things you have the engines field, which is more the approach of having a minimum version.
Applications do often have prompts for users to upgrade/switch browsers if their browser is unsupported / old.
People can do that already if they wish with Deno.version. 😄
When they don't user a prompt to upgrade, they target an older version of javascript.
I'm not really sure that is true. Most of the "legacy" stuff in Node.js eco-system are authors who just don't care about refactoring their code. Abandonware is far more a drain than prompting users to upgrade their version of Node.js. The README often states the minimum version of Node.js required, I don't know why that wouldn't be sufficient here.
When they don't user a prompt to upgrade, they target an older version of javascript.
I'm not really sure that is true. Most of the "legacy" stuff in Node.js eco-system are authors who just don't care about refactoring their code.
I was talking about browser use cases specifically there. I don't think that's as common for node.js modules.
In general, I agree with your thoughts and don't think this is priority.
After some more thought too, I think the more common use case is going to be users running a newer version of deno with an older script (which wouldn't be a problem).
What about a convenience method on the Deno object?
Deno.assertMinVersion('0.20');
Deno.assertMinTSVersion('3.7');
I guess these are implicitly runtime checks, but tooling could take advantage of them being standard to do checks ahead of time if desired.
When we reach 1.0 we will have a stable API and such checks will not be necessary.
I don't think we need convenience methods when Deno.version.deno exists.
Most libs do something like:
«You are using an outdated Deno version. We recommend to upgrade. Run: brew install deno»
I almost sure you’ll make this check (isn’t it added yet?). Additional/alternative check may be useful when using modules. A warning saying something like:
«XXX module is using YYY Deno version. We recommend you to upgrade too. Run: brew install deno»
Most helpful comment
People can do that already if they wish with
Deno.version. 😄I'm not really sure that is true. Most of the "legacy" stuff in Node.js eco-system are authors who just don't care about refactoring their code. Abandonware is far more a drain than prompting users to upgrade their version of Node.js. The README often states the minimum version of Node.js required, I don't know why that wouldn't be sufficient here.