emberjs / ember.js

Ember.js - A JavaScript framework for creating ambitious web applications
https://emberjs.com
MIT License
22.46k stars 4.21k forks source link

Breaking change in 5.9 beta: `with` keyword #20694

Open ef4 opened 1 month ago

ef4 commented 1 month ago

🐞 Describe the Bug

In Ember 5.8, the {{#with}} keyword works in handlebars strict mode. In 5.9.0-beta.1, it results in a build error.

I'm aware that it's listed as deprecated at 4.0 but apparently we left it working up until 5.8.0, with no deprecation message. So it was lurking in an app where I tried to test the beta.

🔬 Minimal Reproduction

This app demonstrates the difference:

https://github.com/ef4/with-keyword-bug

It should fail to build. If you downgrade to ember-source 5.8.0, it works.

ef4 commented 1 month ago

Error dump:

Build Error (Babel) in bug-repro/components/example.js

/Users/edward/hacking/bug-repro/bug-repro/components/example.js: Attempted to resolve a component in a strict mode template, but that value was not in scope: with: 

|
|  with
|

(error occurred in '/Users/edward/hacking/bug-repro/bug-repro/components/example.js' @ line 2 : column 5)SyntaxError: /Users/edward/hacking/bug-repro/bug-repro/components/example.js: Attempted to resolve a component in a strict mode template, but that value was not in scope: with: 

|
|  with
|

(error occurred in '/Users/edward/hacking/bug-repro/bug-repro/components/example.js' @ line 2 : column 5)
    at generateSyntaxError (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:7830:17)
    at StrictModeValidationPass.errorFor (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5396:50)
    at StrictModeValidationPass.Expression (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5211:23)
    at StrictModeValidationPass.InvokeBlock (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5317:19)
    at StrictModeValidationPass.Statement (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5171:23)
    at /Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5137:44
    at OkImpl.andThen (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:3643:14)
    at StrictModeValidationPass.Statements (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5137:25)
    at StrictModeValidationPass.validate (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5132:19)
    at StrictModeValidationPass.validate (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5126:33)
    at /Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5448:72
    at OkImpl.andThen (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:3643:14)
    at normalize (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:5448:27)
    at precompileJSON (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:6106:19)
    at precompile (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:6139:33)
    at Object.precompile (/Users/edward/hacking/bug-repro/node_modules/.pnpm/ember-source@5.9.0-beta.1_@babel+core@7.24.5_@glimmer+component@1.1.2_rsvp@4.8.5_webpack@5.91.0/node_modules/ember-source/dist/ember-template-compiler.js:17043:37)
    at insertCompiledTemplate (/Users/edward/hacking/bug-repro/node_modules/.pnpm/babel-plugin-ember-template-compilation@2.2.4/node_modules/babel-plugin-ember-template-compilation/src/plugin.js:279:48)
    at PluginPass.CallExpression (/Users/edward/hacking/bug-repro/node_modules/.pnpm/babel-plugin-ember-template-compilation@2.2.4/node_modules/babel-plugin-ember-template-compilation/src/plugin.js:158:25)
    at NodePath._call (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/path/context.js:46:20)
    at NodePath.call (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/path/context.js:36:17)
    at NodePath.visit (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/path/context.js:82:31)
    at TraversalContext.visitQueue (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:89:16)
    at TraversalContext.visitSingle (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:65:19)
    at TraversalContext.visit (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:112:19)
    at traverseNode (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at NodePath.visit (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/path/context.js:88:52)
    at TraversalContext.visitQueue (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:89:16)
    at TraversalContext.visitMultiple (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:61:17)
    at TraversalContext.visit (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:110:19)
    at traverseNode (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at NodePath.visit (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/path/context.js:88:52)
    at TraversalContext.visitQueue (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:89:16)
    at TraversalContext.visitSingle (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:65:19)
    at TraversalContext.visit (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/context.js:112:19)
    at traverseNode (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at Object.traverse (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+traverse@7.24.5/node_modules/@babel/traverse/lib/index.js:52:34)
    at PluginPass.pre (/Users/edward/hacking/bug-repro/node_modules/.pnpm/babel-plugin-ember-template-compilation@2.2.4/node_modules/babel-plugin-ember-template-compilation/src/plugin.js:170:23)
    at transformFile (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+core@7.24.5/node_modules/@babel/core/lib/transformation/index.js:73:27)
    at transformFile.next (<anonymous>)
    at run (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+core@7.24.5/node_modules/@babel/core/lib/transformation/index.js:24:12)
    at run.next (<anonymous>)
    at transform (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+core@7.24.5/node_modules/@babel/core/lib/transform.js:22:33)
    at transform.next (<anonymous>)
    at evaluateSync (/Users/edward/hacking/bug-repro/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:251:28)
    at sync (/Users/edward/hacking/bug-repro/node_modules/.pnpm/gensync@1.0.0-beta.2/node_modules/gensync/index.js:89:14)
    at stopHiding - secret - don't use this - v1 (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+core@7.24.5/node_modules/@babel/core/lib/errors/rewrite-stack-trace.js:47:12)
    at Object.transform (/Users/edward/hacking/bug-repro/node_modules/.pnpm/@babel+core@7.24.5/node_modules/@babel/core/lib/transform.js:36:80)
    at /Users/edward/hacking/bug-repro/node_modules/.pnpm/broccoli-babel-transpiler@7.8.1/node_modules/broccoli-babel-transpiler/lib/worker.js:12:31
    at tryCatcher (/Users/edward/hacking/bug-repro/node_modules/.pnpm/rsvp@4.8.5/node_modules/rsvp/dist/rsvp.js:326:21)
    at invokeCallback (/Users/edward/hacking/bug-repro/node_modules/.pnpm/rsvp@4.8.5/node_modules/rsvp/dist/rsvp.js:498:33)
chancancode commented 1 month ago

Yeah I posted about this a while ago. The feature was implemented in glimmer-vm and a deprecation was added in ember as an AST plugin. When it comes time to cleanup the deprecation we just removed the ember AST plugin without removing the feature in glimmer-vm. We finally did recently.

ef4 commented 1 month ago

Maybe we should at least put this in changelog. That's where I first looked.

ef4 commented 1 month ago

I realized why these weren't caught in this app during 3.28 deprecation cleanup. They were only ever build-time deprecations, and our support for those isn't great.

IMO we should try to emit this kind of thing at runtime in the future. The AST transform could have chosen to insert a call to a deprecation-emitting helper instead of printing to the console.

chancancode commented 1 month ago

Agreed. We can also backport and/or make this a hard error or something until 6.0 or something. IIRC with is a non-contextual keyword in JS anyway so it’s unlikely that it will cause any real issues.

Just didn’t bother because @kategengler didn’t find any real world cases of it. But now you have we can certain do more