express-react-views icon indicating copy to clipboard operation
express-react-views copied to clipboard

Views are still cached, even in development env.

Open ghost opened this issue 7 years ago • 9 comments

Heyo,

My views are still cached even my process.env.NODE_ENV is set to development via dotenv.

In development, we clear your view files from the cache so you can simply refresh your browser to see changes.

Anyone an idea why my views are still cached?

ghost avatar Sep 16 '17 18:09 ghost

This library does not use environment variables for settings.

https://github.com/reactjs/express-react-views/blob/master/index.js#L60

const options = { 
  settings: { 
    env: process.env.NODE_ENV || 'development'
  }
};
app.engine('jsx', require('express-react-views').createEngine(options));
}

landau avatar Sep 17 '17 10:09 landau

app.engine('jsx', reactViews.createEngine({
    beautify: true,
    settings: {
        env: process.env.NODE_ENV || 'development'
    }
}));

app.get('/*', (req, res) => {

    res.render('index');

});

And the view is still cached, I checked the options.settings.env with a console.log in the lib index, and it is set to development, the moduleDetectRegEx.test(require.cache[module].filename) check is always false. I'm doing something wrong here? The index.jsx contains atm only plain html.

import React from 'react';

class Layout extends React.Component {

    render() {

        return (
            <html>
            <head>
                <meta charSet="UTF-8"/>
                <meta name="author" content="Jerome Peters"/>

                <link href="/css/main.css" rel="stylesheet" type="text/css"/>
            </head>
            <body>

            <nav>
                <div className="nav-wrapper grey darken-3">
                    <ul className="hide-on-med-and-down">
                        <li><a href="/">Home</a></li>
                        <li><a href="/contact">Contact</a></li>
                    </ul>
                </div>
            </nav>

            <main>
                <div id="root">
                    {this.props.children}
                </div>
            </main>

            <footer className="page-footer grey lighten-4">
                <div className="container">
                    <div className="row">
                        <div className="col s12 m6 l6 center-align">
                            <ul>
                                <li><a className="grey-text text-darken-3" href="//goo.gl/E6ueB7" target="_blank">Twitter</a>
                                </li>
                                <li><a className="grey-text text-darken-3" href="https://goo.gl/tR51GY" target="_blank">Instagram</a>
                                </li>
                            </ul>
                        </div>
                        <div className="col s12 m6 l6 center-align">
                            <ul>
                                <li><a className="grey-text text-darken-3" href="//goo.gl/tVR4Xy" target="_blank">Github</a>
                                </li>
                                <li><a className="grey-text text-darken-3" href="//goo.gl/W1w3A1" target="_blank">Discord</a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
                <div className="footer-copyright">
                    <div className="container">
                        <span id="footerCopyright" className="grey-text text-darken-3">Made with <span
                            className="red-text">❤</span></span>
                    </div>
                </div>
            </footer>

            <script src="/js/main.js" type="text/javascript"/>
            </body>
            </html>
        );

    };

}

export default Layout;

ghost avatar Sep 17 '17 11:09 ghost

@ghost As per my understanding, if you look carefully engineOptions and options are different by looking at code. try this app.set('env', 'development'); before setting your views let me know if that's working for you.

svenkatreddy avatar Oct 02 '17 21:10 svenkatreddy

Having the same issue right now. I have tried both, setting the env in the createEngine() options and via app.set('env', 'development');. Views are still cached.

          if (moduleDetectRegEx.test(require.cache[module].filename)) {
            delete require.cache[module];
          }

I had to remove this part to get it working. The regex returns always false when I test it with the following console.log

        Object.keys(require.cache).forEach(function(module) {
          console.log(moduleDetectRegEx.test(require.cache[module].filename))
          if (moduleDetectRegEx.test(require.cache[module].filename)) {
            delete require.cache[module];
          }
        });

ghost avatar Feb 22 '18 09:02 ghost

The issue seems to arise when you use a relative path for your views directory, such as:

app.set('views', './view')

The solution is to use an absolute path when setting your views directory:

app.set('views', path.join(__dirname, 'views'))

samholmes avatar Jun 21 '18 23:06 samholmes

Using an absolute path made no difference for me, nor did setting the env to 'development'.

lowtolerance avatar Nov 21 '18 15:11 lowtolerance

Anyone make any progress here? Seeing the same issue

pablougas avatar Jun 17 '19 17:06 pablougas

~~I ended up just reverting to an older version from NPM~~ (confused this problem with another related to this project updating to Babel 7)

I never found a graceful solution to this problem, but I worked around it by just handling the cache clearing myself. I just copied the relevant code from this package and rolled it into its own function:

moduleDetectRegEx = new RegExp(
    []
        .concat(options.settings.views)
        .map(viewPath => '^' + _escaperegexp(viewPath))
        .join('|')
)

function clearCache() {
    Object.keys(require.cache).forEach(function(module) {
        if (moduleDetectRegEx.test(require.cache[module].filename)) {
           delete require.cache[module];
        }
     });
}

lowtolerance avatar Jun 17 '19 20:06 lowtolerance

This one works perfectly fine

app.set("views", __dirname + "\\views");

The problem is when comparing module path with "views" path set in app.set(), the module path is always with \\ instead of /, so these two fail because path.join() also generates / instead of \\

app.set("views", __dirname + "/views");
app.set("views", path.join(__dirname, "views"));

LiveGobe avatar Nov 23 '21 18:11 LiveGobe