узел требуется разрешить до исходного расширения после очистки кэша и удаления файла - PullRequest
0 голосов
/ 10 октября 2019

Мой код выполняет const cfg = require('./config'), так что либо config.js, либо config.json будет прочитано. В целом это работает отлично. Проблема, с которой я сталкиваюсь, заключается во время тестирования.

Код тестирования повторяется на следующих этапах:

  • очистить требуемый кэш для require.resolve('./config.json')
  • write config.json с данными для проверки
  • проверить код, содержащий const cfg = require('./config')

Все выше работает нормально. Проблема возникает, когда тест пытается проверить, что config.js также работает.

  • очистить требуемый кеш для require.resolve('./config.json')
  • delete config.json
  • написать config.js
  • проверить код, содержащий const cfg = require('./config')

Попытка чтения config.js через require('./config') не удалась, поскольку require.resolve('./config') все еще разрешается в файл .jsonкоторого больше не существует.

Поведение может быть объяснено тем, что каталог где-то кэшируется, поэтому запись config.js не отражается в поиске по запросу узла. Но это всего лишь предположение.

Изменение порядка проверок так, чтобы сначала выполнялись .js тесты, а затем результаты .json с той же проблемой, но в обратном порядке.

поведение одинаково на версиях узла 6+;Я не проверял более ранние версии.

Как можно сделать так, чтобы узел возвращал экспорт файла .js в этом сценарии?

Следующая проблема иллюстрирует следующее. Указав расширение в операторе require (измените const withExt = false на true), оно выполнится успешно.

'use strict'

/* eslint-disable no-console */

const fs = require('fs');

const fullConfigName = `${process.cwd()}/xyzzy`;

function cleanup (ext) {
  // remove any files created with the default names
  try {fs.unlinkSync(`${fullConfigName}.${ext}`)} catch (e) {
    console.log(`failed to cleanup ${ext}`, e.code || e.message);
  }
  // clear the require cache
  delete require.cache[`${fullConfigName}.${ext}`];
}


function writeFile (extension) {
  let config;
  if (extension === 'json') {
    config = JSON.stringify({some: 'i was json'}) + '\n';
  } else {
    config = 'module.exports = {someSetting: "i was a module"}\n'
  }
  fs.writeFileSync(`${fullConfigName}.${extension}`, config, 'utf8');
}

function main () {
  cleanup('js');
  cleanup('json');

  //const configName = fullConfigName;
  const configName = './xyzzy';
  const withExt = false;

  const exts = false ? ['json', 'js'] : ['js', 'json'];

  exts.forEach(ext => {
    const extPart = withExt ? `.${ext}` : '';

    console.log(`writing ${configName}.${ext}`);
    writeFile(ext);

    const fileToRequire = `${configName}${extPart}`;
    console.log(`requiring ${fileToRequire}`);

    const resolved = require.resolve(fileToRequire);
    console.log(`require.resolve result ${resolved}`);
    try {
      const contents = require(`${fileToRequire}`);
      console.log('contents', contents);
    } catch (e) {
      console.log('require failed', e.code || e.message);
    }

    console.log(module.children.map(c => {
      return {
        id: c.id,
        exports: c.exports,
        filename: c.filename,
        loaded: c.loaded,
      }
    }));
    const cache = Object.keys(require.cache).filter(k => true || k.startsWith(fullConfigName));
    console.log('cache:', cache);

    console.log(`${ext} - cleanup`);
    cleanup(ext);
  })
}

main ()
...