From eec381ec72db3858452799b7a3264e240be3044d Mon Sep 17 00:00:00 2001 From: Harttle Date: Sun, 17 Apr 2022 23:53:24 +0800 Subject: [PATCH] fix: use `createRequire` for ESM, fixes #334 --- demo/esm/README.md | 9 +++++++++ demo/esm/index.mjs | 30 ++++++++++++++++++++++++++++++ demo/esm/layouts/html.liquid | 7 +++++++ demo/esm/package.json | 13 +++++++++++++ demo/esm/partials/footer.liquid | 1 + demo/esm/partials/todo.liquid | 1 + demo/esm/todolist.liquid | 7 +++++++ rollup.config.ts | 11 ++++++++++- src/emitters/streamed-emitter.ts | 4 ++-- src/fs/node-require.mjs | 5 +++++ src/fs/node-require.mjs.d.ts | 1 + src/fs/node-require.ts | 1 + src/fs/node.ts | 3 ++- 13 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 demo/esm/README.md create mode 100644 demo/esm/index.mjs create mode 100644 demo/esm/layouts/html.liquid create mode 100644 demo/esm/package.json create mode 100644 demo/esm/partials/footer.liquid create mode 100644 demo/esm/partials/todo.liquid create mode 100644 demo/esm/todolist.liquid create mode 100644 src/fs/node-require.mjs create mode 100644 src/fs/node-require.mjs.d.ts create mode 100644 src/fs/node-require.ts diff --git a/demo/esm/README.md b/demo/esm/README.md new file mode 100644 index 000000000..d70afb158 --- /dev/null +++ b/demo/esm/README.md @@ -0,0 +1,9 @@ +# LiquidJS for Node.js + +## Get Started + +```bash +cd demo/nodejs +npm install +npm start +``` \ No newline at end of file diff --git a/demo/esm/index.mjs b/demo/esm/index.mjs new file mode 100644 index 000000000..20b04df59 --- /dev/null +++ b/demo/esm/index.mjs @@ -0,0 +1,30 @@ +import { Liquid } from 'liquidjs' + +const engine = new Liquid({ + extname: '.liquid', + globals: { title: 'LiquidJS Demo' }, + // root files for `.render()` and `.parse()` + root: process.cwd(), + // layout files for `{% layout %}` + layouts: process.cwd() + '/layouts', + // partial files for `{% include %}` and `{% render %}` + partials: process.cwd() + '/partials' +}) + +const ctx = { + todos: ['fork and clone', 'make it better', 'make a pull request'] +} + +async function main () { + console.log('==========renderFile===========') + const html = await engine.renderFile('todolist', ctx) + console.log(html) + + console.log('===========Streamed===========') + const tpls = await engine.parseFile('todolist') + engine.renderToNodeStream(tpls, ctx) + .on('data', data => process.stdout.write(data)) + .on('end', () => console.log('')) +} + +main() diff --git a/demo/esm/layouts/html.liquid b/demo/esm/layouts/html.liquid new file mode 100644 index 000000000..98bdac6be --- /dev/null +++ b/demo/esm/layouts/html.liquid @@ -0,0 +1,7 @@ + + + + {% block %}{% endblock %} + {% render "footer.liquid" %} + + \ No newline at end of file diff --git a/demo/esm/package.json b/demo/esm/package.json new file mode 100644 index 000000000..84fd3ee3a --- /dev/null +++ b/demo/esm/package.json @@ -0,0 +1,13 @@ +{ + "name": "liquidjs-demo-nodejs", + "description": "Node.js demo for liquidjs", + "private": true, + "main": "index.mjs", + "scripts": { + "start": "node index.mjs" + }, + "dependencies": { + "hello-liquid": "^1.0.0", + "liquidjs": "^9.28.3" + } +} diff --git a/demo/esm/partials/footer.liquid b/demo/esm/partials/footer.liquid new file mode 100644 index 000000000..1ebe82b66 --- /dev/null +++ b/demo/esm/partials/footer.liquid @@ -0,0 +1 @@ +{{title}} \ No newline at end of file diff --git a/demo/esm/partials/todo.liquid b/demo/esm/partials/todo.liquid new file mode 100644 index 000000000..d81a9f163 --- /dev/null +++ b/demo/esm/partials/todo.liquid @@ -0,0 +1 @@ +
  • {{index}} - {{todo}}
  • diff --git a/demo/esm/todolist.liquid b/demo/esm/todolist.liquid new file mode 100644 index 000000000..2459c9da3 --- /dev/null +++ b/demo/esm/todolist.liquid @@ -0,0 +1,7 @@ +{% layout 'html.liquid' %} +

    {% include "hello-liquid" %}

    + \ No newline at end of file diff --git a/rollup.config.ts b/rollup.config.ts index 50b8f1c95..9fea0bd20 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -47,6 +47,11 @@ const browserStream = { delimiters: ['', ''], '../emitters/streamed-emitter': '../emitters/streamed-emitter-browser' } +const esmRequire = { + include: './src/fs/node.ts', + delimiters: ['', ''], + './node-require': './node-require.mjs' +} const nodeCjs = { output: [{ @@ -67,7 +72,11 @@ const nodeEsm = { banner }], external: ['path', 'fs'], - plugins: [versionInjection, typescript(tsconfig)], + plugins: [ + versionInjection, + replace(esmRequire), + typescript(tsconfig) + ], treeshake, input } diff --git a/src/emitters/streamed-emitter.ts b/src/emitters/streamed-emitter.ts index 8c0c60faf..83a9ca25e 100644 --- a/src/emitters/streamed-emitter.ts +++ b/src/emitters/streamed-emitter.ts @@ -1,10 +1,10 @@ import { stringify } from '../util/underscore' import { Emitter } from './emitter' +import { PassThrough } from 'stream' export class StreamedEmitter implements Emitter { public buffer = ''; - // eslint-disable-next-line @typescript-eslint/no-var-requires - public stream: NodeJS.ReadWriteStream = new (require('stream').PassThrough)() + public stream: NodeJS.ReadWriteStream = new PassThrough() public write (html: any) { this.stream.write(stringify(html)) } diff --git a/src/fs/node-require.mjs b/src/fs/node-require.mjs new file mode 100644 index 000000000..fa14f94b0 --- /dev/null +++ b/src/fs/node-require.mjs @@ -0,0 +1,5 @@ +import { createRequire } from 'module' + +const require = createRequire(import.meta.url) + +export const requireResolve = require.resolve diff --git a/src/fs/node-require.mjs.d.ts b/src/fs/node-require.mjs.d.ts new file mode 100644 index 000000000..49195e75a --- /dev/null +++ b/src/fs/node-require.mjs.d.ts @@ -0,0 +1 @@ +export declare function requireResolve(file: string): string; diff --git a/src/fs/node-require.ts b/src/fs/node-require.ts new file mode 100644 index 000000000..962e77c37 --- /dev/null +++ b/src/fs/node-require.ts @@ -0,0 +1 @@ +export const requireResolve = require.resolve diff --git a/src/fs/node.ts b/src/fs/node.ts index cdb761ffe..5f15d196b 100644 --- a/src/fs/node.ts +++ b/src/fs/node.ts @@ -1,6 +1,7 @@ import * as _ from '../util/underscore' import { sep, resolve as nodeResolve, extname, dirname as nodeDirname } from 'path' import { stat, statSync, readFile as nodeReadFile, readFileSync as nodeReadFileSync } from 'fs' +import { requireResolve } from './node-require' const statAsync = _.promisify(stat) const readFileAsync = _.promisify(nodeReadFile) @@ -33,7 +34,7 @@ export function resolve (root: string, file: string, ext: string) { } export function fallback (file: string) { try { - return require.resolve(file) + return requireResolve(file) } catch (e) {} } export function dirname (filepath: string) {