mozilla / nunjucks

A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)
https://mozilla.github.io/nunjucks/
BSD 2-Clause "Simplified" License
8.48k stars 634 forks source link

GraalJS support #1457

Closed jamcn-nhsbsa closed 4 months ago

jamcn-nhsbsa commented 5 months ago

Summary

Proposed change:

GraalJS is an environment which allows JavaScript to be run in a VM controlled by other languages such as Java. Unfortunately, the environment is missing several global functions often expected in scripts written for Nodejs or browser environments.

A few small changes allow for nunjucks to check if it is being run in a GraalJS environment and replace calls to the non-existant functions with the Graal alternatives. This allows nunjucks to run in a Graal environment without issue, opening up the possibility of using the framework with more languages.

Checklist

I've completed the checklist below to ensure I didn't forget anything. This makes reviewing this PR as easy as possible for the maintainers. And it gets this change released as soon as possible.

codecov[bot] commented 5 months ago

Codecov Report

Attention: 4 lines in your changes are missing coverage. Please review.

Comparison is base (ea0d6d5) 89.65% compared to head (cfd2031) 89.67%.

Files Patch % Lines
nunjucks/src/web-loaders.js 84.61% 4 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #1457 +/- ## ========================================== + Coverage 89.65% 89.67% +0.02% ========================================== Files 22 22 Lines 3046 3062 +16 ========================================== + Hits 2731 2746 +15 - Misses 315 316 +1 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

webketje commented 4 months ago

This is outside of the scope of Nunjucks and would better be solved with a custom loader. Maintainers will not bother to keep an integration for a third-party environment (especially outside of the JS ecosystem) up-to-date

jamcn-nhsbsa commented 4 months ago

Ah, of course! I overlooked the custom loader functionality before.

I've been able to make a custom loader using what was in this MR to allow for nunjucks to work in GraalJS:

var GraalLoader =  nunjucks.Loader.extend({
    async: true,
    getSource: function(name, callback) {
        var useCache = this.useCache;
        var err = null;
        var src;
        try {
            src = read(name);
        } catch (e) {
            err = e;
        }
        var result = {
            src: src,
            path: name,
            noCache: !useCache
        };
        callback(err, result);
    },
    resolve: function(from, to) {
        stack = from.split('/');
        parts = to.split('/');
        stack.pop();
        for (let i = 0; i < parts.length; i++) {
            if (parts[i] === '..') {
                stack.pop();
            } else if (parts[i] !== '.') {
                stack.push(parts[i]);
            }
        }
        return stack.join('/');
    },
    isRelative: function(filename) {
        return (filename.indexOf('./') === 0 || filename.indexOf('../') === 0);
    }
});
const nunjucksEnv = new nunjucks.Environment(new GraalLoader());