Skip to content

Commit

Permalink
Require Node.js 18 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Nov 2, 2023
1 parent e303828 commit 5f743c6
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 257 deletions.
3 changes: 0 additions & 3 deletions .github/funding.yml

This file was deleted.

10 changes: 4 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ jobs:
fail-fast: false
matrix:
node-version:
- 14
- 12
- 10
- 8
- 20
- 18
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
120 changes: 30 additions & 90 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,104 +1,44 @@
'use strict';
const through = require('through2');
const nunjucks = require('nunjucks');
const PluginError = require('plugin-error');
const is = require('@sindresorhus/is');
import {Buffer} from 'node:buffer';
import {promisify} from 'node:util';
import nunjucks from 'nunjucks';
import {gulpPlugin} from 'gulp-plugin-extras';

function compile(data, options = {}) {
return through.obj(function (file, encoding, callback) {
if (file.isNull()) {
callback(null, file);
return;
}

if (file.isStream()) {
callback(new PluginError('gulp-nunjucks', 'Streaming not supported'));
return;
}
export function nunjucksCompile(data, options = {}) {
return gulpPlugin('gulp-nunjucks', async file => {
const context = {
...data,
...file.data,
};

const context = {...data, ...file.data};
const filePath = file.path;
const env = options.env || new nunjucks.Environment(new nunjucks.FileSystemLoader(file.base), options);

let isAsync = false;
const env = options.env ?? new nunjucks.Environment(new nunjucks.FileSystemLoader(file.base), options);

if (options.filters && !options.env) {
for (const key of Object.keys(options.filters)) {
const filter = options.filters[key];
if (is.asyncFunction(filter)) {
isAsync = true;
env.addFilter(key, async (...args) => {
const cb = args.pop();
try {
const result = await filter(...args);
cb(null, result);
} catch (error) {
cb(error, null);
}
}, true);
} else {
env.addFilter(key, filter);
}
for (const [key, filter] of Object.entries(options.filters)) {
env.addFilter(key, async (...arguments_) => {
const cb = arguments_.pop();
try {
const result = await filter(...arguments_);
cb(undefined, result);
} catch (error) {
cb(error);
}
}, true);
}
}

try {
const writeResult = result => {
file.contents = Buffer.from(result);
file.extname = '.html';
this.push(file);
};
file.contents = Buffer.from(await promisify(env.renderString.bind(env))(file.contents.toString(), context));
file.extname = '.html';

if (isAsync) {
env.renderString(file.contents.toString(), context, (error, result) => {
if (error) {
this.emit('error', new PluginError('gulp-nunjucks', error, {fileName: filePath}));
callback();
return;
}

writeResult(result);
callback();
});
} else {
writeResult(env.renderString(file.contents.toString(), context));
callback();
}
} catch (error) {
this.emit('error', new PluginError('gulp-nunjucks', error, {fileName: filePath}));
callback();
}
return file;
});
}

function precompile(options) {
return through.obj(function (file, encoding, callback) {
if (file.isNull()) {
callback(null, file);
return;
}

if (file.isStream()) {
callback(new PluginError('gulp-nunjucks', 'Streaming not supported'));
return;
}

export function nunjucksPrecompile(options) {
return gulpPlugin('gulp-nunjucks', file => {
const localOptions = {...options};
const filePath = file.path;

try {
localOptions.name = (typeof localOptions.name === 'function' && localOptions.name(file)) || file.relative;
file.contents = Buffer.from(nunjucks.precompileString(file.contents.toString(), localOptions));
file.extname = '.js';
this.push(file);
} catch (error) {
this.emit('error', new PluginError('gulp-nunjucks', error, {fileName: filePath}));
}

callback();
localOptions.name = (typeof localOptions.name === 'function' && localOptions.name(file)) || file.relative;
file.contents = Buffer.from(nunjucks.precompileString(file.contents.toString(), localOptions));
file.extname = '.js';
return file;
});
}

module.exports = precompile;
module.exports.compile = compile;
module.exports.precompile = precompile;
2 changes: 1 addition & 1 deletion license
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
22 changes: 12 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
"description": "Compile/precompile Nunjucks templates",
"license": "MIT",
"repository": "sindresorhus/gulp-nunjucks",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=8"
"node": ">=18"
},
"scripts": {
"test": "xo && ava"
Expand All @@ -33,16 +36,15 @@
"javascript"
],
"dependencies": {
"@sindresorhus/is": "^3.1.2",
"nunjucks": "^3.2.0",
"plugin-error": "^1.0.1",
"through2": "^3.0.1"
"gulp-plugin-extras": "^0.2.2",
"nunjucks": "^3.2.4"
},
"devDependencies": {
"ava": "^2.3.0",
"gulp-data": "^1.2.1",
"vinyl": "^2.1.0",
"xo": "^0.24.0"
"ava": "^5.3.1",
"gulp-data": "^1.3.1",
"p-event": "^6.0.0",
"vinyl": "^3.0.0",
"xo": "^0.56.0"
},
"peerDependencies": {
"gulp": ">=4"
Expand Down
41 changes: 18 additions & 23 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,55 @@
*Issues with the output should be reported on the Nunjucks [issue tracker](https://github.com/mozilla/nunjucks/issues).*


## Install

```sh
npm install --save-dev gulp-nunjucks
```
$ npm install --save-dev gulp-nunjucks
```


## Usage

### Compile

```js
const gulp = require('gulp');
const nunjucks = require('gulp-nunjucks');
import gulp from 'gulp';
import {nunjucksCompile} from 'gulp-nunjucks';

exports.default = () => (
export default () => (
gulp.src('templates/greeting.html')
.pipe(nunjucks.compile({name: 'Sindre'}))
.pipe(nunjucksCompile({name: 'Sindre'}))
.pipe(gulp.dest('dist'))
);
```

You can alternatively use [gulp-data](https://github.com/colynb/gulp-data) to inject the data:

```js
const gulp = require('gulp');
const nunjucks = require('gulp-nunjucks');
const data = require('gulp-data');
import gulp from 'gulp';
import {nunjucksCompile} from 'gulp-nunjucks';
import data from 'gulp-data';

exports.default = () => (
export default () => (
gulp.src('templates/greeting.html')
.pipe(data(() => ({name: 'Sindre'})))
.pipe(nunjucks.compile())
.pipe(nunjucksCompile())
.pipe(gulp.dest('dist'))
);
```

### Precompile

```js
const gulp = require('gulp');
const nunjucks = require('gulp-nunjucks');
import gulp from 'gulp';
import {nunjucksPrecompile} from 'gulp-nunjucks';

exports.default = () => (
export default () => (
gulp.src('templates/greeting.html')
.pipe(nunjucks.precompile())
.pipe(nunjucksPrecompile())
.pipe(gulp.dest('dist'))
);
```


## API

### nunjucks.compile(data?, options?)
Expand All @@ -76,7 +73,7 @@ Options will be passed directly to the Nunjucks [Environment constructor](https:

##### options.env

Type: `nunjucks.Environment`<br>
Type: `nunjucks.Environment`\
Default: `new nunjucks.Environment()`

The custom Nunjucks [Environment object](https://mozilla.github.io/nunjucks/api.html#environment) which will be used to compile templates. If supplied, the rest of `options` will be ignored.
Expand All @@ -89,8 +86,6 @@ An object containing [custom filters](https://mozilla.github.io/nunjucks/api.htm

Async filters should be defined as async functions. You cannot use just a promise-returning function.

Example:

```js
{
'shorten': string => string.slice(0, 5),
Expand All @@ -115,8 +110,8 @@ Type: `object`

##### name

Type: `Function`<br>
Default: Relative template path<br>
Type: `Function`\
Default: Relative template path\
Example: `templates/list.html`

You can override the default behavior by supplying a function which gets the current [File](https://github.com/gulpjs/vinyl#options) object and is expected to return the name.
Expand Down
Loading

0 comments on commit 5f743c6

Please sign in to comment.