diff --git a/eject.js b/eject.js index 46bfbb5c..69bd80a3 100644 --- a/eject.js +++ b/eject.js @@ -25,7 +25,11 @@ function cli (args) { if (opts.lang === 'ts' || opts.lang === 'typescript') { template = 'eject-ts' } else { - template = 'eject' + if (opts.esm) { + template = 'eject-esm' + } else { + template = 'eject' + } } return eject(process.cwd(), template).catch(function (err) { diff --git a/help/eject.txt b/help/eject.txt index 8043973f..f610be48 100644 --- a/help/eject.txt +++ b/help/eject.txt @@ -6,5 +6,8 @@ You can set the port to listen on with the PORT environment variable (default to OPTS + --esm + use the ESM template + --lang=ts, --lang=typescript use the TypeScript template diff --git a/templates/eject-esm/server.js b/templates/eject-esm/server.js new file mode 100644 index 00000000..4ee40946 --- /dev/null +++ b/templates/eject-esm/server.js @@ -0,0 +1,43 @@ +// Read the .env file. +import * as dotenv from 'dotenv' + +// Require the framework +import Fastify from 'fastify' + +// Require library to exit fastify process, gracefully (if possible) +import closeWithGrace from 'close-with-grace' + +// Import your application +import appService from './app.js' + +// Dotenv config +dotenv.config() + +// Instantiate Fastify with some config +const app = Fastify({ + logger: true +}) + +// Register your application as a normal plugin. +app.register(appService) + +// delay is the number of milliseconds for the graceful close to finish +const closeListeners = closeWithGrace({ delay: process.env.FASTIFY_CLOSE_GRACE_DELAY || 500 }, async function ({ signal, err, manual }) { + if (err) { + app.log.error(err) + } + await app.close() +}) + +app.addHook('onClose', async (instance, done) => { + closeListeners.uninstall() + done() +}) + +// Start listening. +app.listen({ port: process.env.PORT || 3000 }, (err) => { + if (err) { + app.log.error(err) + process.exit(1) + } +}) diff --git a/test/eject-esm.test.js b/test/eject-esm.test.js new file mode 100644 index 00000000..d49d01bc --- /dev/null +++ b/test/eject-esm.test.js @@ -0,0 +1,107 @@ +'use strict' + +// bailout if a test is broken +// so that the folder can be inspected +process.env.TAP_BAIL = true + +const t = require('tap') +const { + mkdirSync, + readFileSync, + readFile +} = require('fs') +const path = require('path') +const rimraf = require('rimraf') +const walker = require('walker') +const workdir = path.join(__dirname, 'workdir') +const appTemplateDir = path.join(__dirname, '..', 'templates', 'eject-esm') +const { eject, cli } = require('../eject') +const expected = {}; + +(function (cb) { + const files = [] + walker(appTemplateDir) + .on('file', function (file) { + files.push(file) + }) + .on('end', function () { + let count = 0 + files.forEach(function (file) { + readFile(file, function (err, data) { + if (err) { + return cb(err) + } + + expected[ + file.replace(appTemplateDir, '').replace(/__/, '.') + ] = data.toString() + + count++ + if (count === files.length) { + cb(null) + } + }) + }) + }) + .on('error', cb) +})(function (err) { + t.error(err) + define(t) +}) + +function define (t) { + const { beforeEach, test } = t + + beforeEach(() => { + rimraf.sync(workdir) + mkdirSync(workdir, { recursive: true }) + }) + + test('should finish succesfully with template', async (t) => { + try { + const template = 'eject-esm' + await eject(workdir, template) + await verifyCopy(t, expected) + } catch (err) { + t.error(err) + } + }) + + test('should finish successfully with cli', async (t) => { + try { + process.chdir(workdir) + await cli(['--esm']) + await verifyCopy(t, expected) + } catch (err) { + t.error(err) + } + }) + + function verifyCopy (t, expected) { + return new Promise((resolve, reject) => { + let count = 0 + walker(workdir) + .on('file', function (file) { + count++ + try { + const data = readFileSync(file) + file = file.replace(workdir, '') + t.same( + data.toString().replace(/\r\n/g, '\n'), + expected[file], + file + ' matching' + ) + } catch (err) { + reject(err) + } + }) + .on('end', function () { + t.equal(Object.keys(expected).length, count) + resolve() + }) + .on('error', function (err, entry, stat) { + reject(err) + }) + }) + } +} diff --git a/test/eject.test.js b/test/eject.test.js index 63cf64fa..92a3c27d 100644 --- a/test/eject.test.js +++ b/test/eject.test.js @@ -15,7 +15,7 @@ const rimraf = require('rimraf') const walker = require('walker') const workdir = path.join(__dirname, 'workdir') const appTemplateDir = path.join(__dirname, '..', 'templates', 'eject') -const { eject } = require('../eject') +const { eject, cli } = require('../eject') const expected = {} ;(function (cb) { @@ -65,6 +65,16 @@ function define (t) { } }) + test('should finish successfully with cli', async (t) => { + try { + process.chdir(workdir) + await cli([]) + await verifyCopy(t, expected) + } catch (err) { + t.error(err) + } + }) + function verifyCopy (t, expected) { return new Promise((resolve, reject) => { let count = 0