mde / ejs

Embedded JavaScript templates -- http://ejs.co
Apache License 2.0
7.72k stars 846 forks source link

Error "ReferenceError : variable is not defined" when enabling strict mode (strict:true) ? #583

Closed e-dot closed 3 years ago

e-dot commented 3 years ago

I'm trying to enable strict mode in a very simple template but get the error "variable is not defined" (whereas the variable is defined).

The source code (hello.js) and template (home.ejs) is attached to this post and is very simple:

const express = require('express')
const ejs = require('ejs')
const app = express()
app.set('view engine', 'ejs')
app.set('view options', {
  /* With "strict: true" it crashes with error "title is not defined" */
  strict: true
})
app.get('/', function (req, res) {
  res.render('home', { title: 'TEST' } )
})
app.listen(process.env.PORT);

The template is also basic:

<!DOCTYPE html>
<html>
  <head>
    <title><%= title -%></title>
  </head>
  <body>
    <h1><%= title -%></h1>
  </body>
</html>

When strict mode is true, it fails with this error:

ReferenceError: C:\Program Files\iisnode\www\express\views\home.ejs:4
    2| <html>

    3|   <head>

 >> 4|     <title><%= title -%></title>

    5|   </head>

    6|   <body>

    7|     <h1><%= title -%></h1>

title is not defined
    at eval (eval at compile (C:\Program Files\iisnode\www\express\node_modules\ejs\lib\ejs.js:662:12), <anonymous>:10:26)
    at home (C:\Program Files\iisnode\www\express\node_modules\ejs\lib\ejs.js:692:17)
    at tryHandleCache (C:\Program Files\iisnode\www\express\node_modules\ejs\lib\ejs.js:272:36)
    at View.exports.renderFile [as engine] (C:\Program Files\iisnode\www\express\node_modules\ejs\lib\ejs.js:489:10)
    at View.render (C:\Program Files\iisnode\www\express\node_modules\express\lib\view.js:135:8)
    at tryRender (C:\Program Files\iisnode\www\express\node_modules\express\lib\application.js:640:10)
    at Function.render (C:\Program Files\iisnode\www\express\node_modules\express\lib\application.js:592:3)
    at ServerResponse.render (C:\Program Files\iisnode\www\express\node_modules\express\lib\response.js:1012:7)
    at C:\Program Files\iisnode\www\express\hello.js:11:7
    at Layer.handle [as handle_request] (C:\Program Files\iisnode\www\express\node_modules\express\lib\router\layer.js:95:5)

This occurs on Windows, with iisnode and express 4.17.1 (and ejs version 3.1.6).

Please advise - how can I properly enable strict mode in templates?

Regards,

E. strict_mode_error_not_defined.zip

ExE-Boss commented 3 years ago

This is the intended behaviour because strict: true makes it so that the EJS code is no longer wrapped inside a with statement, since it’s disallowed in strict mode.


You can use the destructuredLocals option to define a snapshot binding of the title property:

app.set('view options', {
    strict: true,
    destructuredLocals: ["title"],
})
e-dot commented 3 years ago

Thank you - it works perfectly with option destructuredLocals.

However, after carefully reading the documentation, I'd rather use the locals object to read values, i.e. updating my template like this:

<!DOCTYPE html>
<html>
  <head>
    <title><%= locals.title -%></title>
  </head>
  <body>
    <h1><%= locals.title -%></h1>
  </body>
</html>

Regards,

E.