GithubHelp home page GithubHelp logo

rechoir's Introduction

rechoir

NPM version Downloads Build Status Coveralls Status

Prepare a node environment to require files with different extensions.

What is it?

This module, in conjunction with interpret-like objects, can register any filetype the npm ecosystem has a module loader for. This library is a dependency of liftoff.

Note: While rechoir will automatically load and register transpilers like coffee-script, you must provide a local installation. The transpilers are not bundled with this module.

Usage

const config = require('interpret').extensions;
const rechoir = require('rechoir');
rechoir.prepare(config, './test/fixtures/test.coffee');
rechoir.prepare(config, './test/fixtures/test.csv');
rechoir.prepare(config, './test/fixtures/test.toml');

console.log(require('./test/fixtures/test.coffee'));
console.log(require('./test/fixtures/test.csv'));
console.log(require('./test/fixtures/test.toml'));

API

prepare(config, filepath, [cwd], [noThrow])

Look for a module loader associated with the provided file and attempt require it. If necessary, run any setup required to inject it into require.extensions.

config An interpret-like configuration object.

filepath A file whose type you'd like to register a module loader for.

cwd An optional path to start searching for the module required to load the requested file. Defaults to the directory of filepath.

noThrow An optional boolean indicating if the method should avoid throwing.

If calling this method is successful (e.g. it doesn't throw), you can now require files of the type you requested natively.

An error with a failures property will be thrown if the module loader(s) configured for a given extension cannot be registered.

If a loader is already registered, this will simply return true.

License

MIT

rechoir's People

Contributors

phated avatar sttk avatar jmm avatar silkentrance avatar alansouzati avatar cspotcode avatar blakeembrey avatar madcapjake avatar pspeter3 avatar zertosh avatar github-actions[bot] avatar

Stargazers

Fernando Silva avatar Maurice Doepke avatar Sean P. Myrick V19.1.7.2 avatar flumpus avatar 没有毒 avatar Charaf Rezrazi avatar  avatar Erick Zhao avatar Haruka avatar Yoshiki Kadoshita avatar Corbin Crutchley avatar zhuangzhuang avatar Tenvi avatar yiminghe avatar Ja avatar  avatar Masahiro Miyashiro (3846masa) avatar Neos21 avatar lilkypimp1 avatar Qdigital avatar Jack Lee avatar Sara Tasche avatar  avatar Siva avatar Neil Zheng avatar Julio Xavier avatar Sibelius Seraphini avatar Sam Genest avatar  avatar Glauber Mota avatar Cat  avatar suitougreentea avatar Adrian Perez avatar Vincenzo Ferrari avatar Alexey Kozlov avatar Yoshiya Hinosawa avatar LY Cheng avatar Kevin Goslar avatar Ivan Tugay avatar Michael Anthony avatar Biko Tushinde avatar  avatar  avatar Aleksandr Abashkin avatar Isao Yagi avatar  avatar David Chase avatar  avatar

Watchers

Jon Schlinkert avatar contra avatar James Cloos avatar  avatar Tyler Kellen avatar  avatar Michael Anthony avatar  avatar  avatar Sean P. Myrick V19.1.7.2 avatar

rechoir's Issues

Discrepancy in use between require() and rechoir.load()

When using require() one can use relative paths, e.g. './foo.bar'. When using rechoir.load() from with the very same context, one must use paths relative to the process' cwd instead.

Since rechoir.load() uses a different require() than the module from which it is being called, this actually makes sense.

As such, passing in relative paths to rechoir.load() should be prevented and the user calling that function must first path.resolve() the filepath before calling rechoir.load().

Consequently, the fix introduced with #7 will not work at all.

Should we deprecate the load function or make it require absolute paths to be passed in instead?

Or perhaps, change the API so that upon

rechoir = require('rechoir')(module);

one must pass in the module for which rechoir is being required for. That way, rechoir could customize itself so that it uses the correct require() function and so on...

Allow register functions to access the module's package path in order to require() additional modules

Requirement: Needs to be orchestrated with gulpjs/interpret#13.

In order to compensate for current lack of transparency on the behalf of both existing and future (custom, node-interpret.js) register functions, and also to add support for older versions of coffee-script and derivates thereof, the resolved package path of the compiler module needs to be passed to the registration functions defined by node-interpret.

As this also requires findup, I find it only natural to merge this on master prior to #6.

throw new Error('No module loader found for "'+ext+'".');

I have a scenario where my file name has the following format filename.tmp.js.

The extension from rechoir is .tmp.js where I was expecting that to be .js.

I believe because of that we can't find the corresponding module loader for this file.

Support for esm.ts using `node --loader ts-node/esm`

I use ts for my gulpfile, but some of the plugins i use (gulp-imagemin specifically), are esm.
So having a way to use both would be useful, as otherwise when one tries to run gulp, they get something like this:

[18:15:57] Requiring external module ts-node/register
TypeError: Unknown file extension ".ts" for /home/monyarm/Documents/gulp-gameoptimizer/gulpfile.ts
    at new NodeError (node:internal/errors:371:5)
    at Loader.defaultGetFormat [as _getFormat] (node:internal/modules/esm/get_format:71:15)
    at Loader.getFormat (node:internal/modules/esm/loader:105:42)
    at Loader.getModuleJob (node:internal/modules/esm/loader:243:31)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Loader.import (node:internal/modules/esm/loader:177:17)
    at importModuleDynamicallyWrapper (node:internal/vm/module:437:15) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

path.extname fails on .coffee.md

path.extname('file.coffee.md') will only return '.md'.

It is better to use a custom regular expression instead. I will make a PR for this.

Fails to look up loader when an extension is single character.

What were you expecting to happen?

Looks up loader successfully when an extension is single character.

What actually happened?

rechoir throws an error of which message is "No module loader found for "undefined". when an extension is single character.

Please give us a sample of your gulpfile for reproduction

// test.js
const config = {                                                                                                                         
  '.coffee': 'coffeescript/register',
  '.co': 'coffeescript/register',
  '.c': 'coffeescript/register',
};
const rechoir = require('rechoir');

console.log(rechoir.prepare(config, './aaa.coffee'));
console.log(require('./aaa.coffee'));

console.log(rechoir.prepare(config, './aaa.co'));
console.log(require('./aaa.co'));

console.log(rechoir.prepare(config, './aaa.c'));
console.log(require('./aaa.c'));

Terminal output / screenshots

$ npm i rechoir coffeescript
$ touch aaa.coffee aaa.co aaa.c
$ node test.js
[ { moduleName: 'coffeescript/register', module: {}, error: null } ]
{}
[ { moduleName: 'coffeescript/register', module: {}, error: null } ]
{}
/path/to/rechoir/bug/node_modules/rechoir/index.js:30                                                                                    
    throw new Error('No module loader found for "' + usedExtension + '".');
    ^

Error: No module loader found for "undefined".
    at Object.exports.prepare (/path/to/rechoir/bug/node_modules/rechoir/index.js:30:11)
    at Object.<anonymous> (/path/to/rechoir/bug/test.js:14:21)
    at Module._compile (node:internal/modules/cjs/loader:1108:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Module.load (node:internal/modules/cjs/loader:973:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
    at node:internal/main/run_main_module:17:47

Please provide the following information:

  • OS & version [e.g. MacOS Catalina 10.15.4]: macOS Big Sur 11.2.1
  • node version (run node -v): v15.5.0
  • npm version (run npm -v): 7.3.0
  • gulp version (run gulp -v): rechoir version: 0.7.0

Additional information

Nothing.

Allow users to provide a custom node-interpret.js module for adhoc extension of the supported languages

For starters, and as a follow up to the discussion we had about making this more versatile over at gulpjs/interpret#12, I'd like to propose that

  • users can provide their own 'interpret-custom' module, that when available, will be mixed into the existing interpret registry
  • here, users can provide their own extension to registration module mappings

Upon load, node-rechoir will by require its own interpret module. In addition to that, it will also look for a interpret-custom and try to require that as well. When available, it will merge in the mappings found in interpret-custom into those from the standard interpret, overwriting existing or adding new mappings.

In order to prevent encouraging users from publishing a node-interpret-custom or interpret-custom package to NPM, node-rechoir will look in the following locations

  • package-root/interpret-custom.js
  • package-root/src/interpret-custom.js
  • package-root/lib/interpret-custom.js

It will not use standard node package/module resolving, so placing this under node_modules will have no effect.

The package-root is assumed to be equal to the cwd variable, or, if that is missing, it will be determined from the resolved absolute path of the specified filepath, looking for either package.* or 'src' or 'lib', or 'node_modules'.

Doesn't emit `require` or `requireFail` events

Liftoff expects the requiring of a language module to emit an event, either require or requireFail, when a language file is loaded. In trying to switch the logic over to rechoir, I found that there isn't a way to hook it into this behavior of liftoff. @tkellen any thoughts on how to solve this?

rechoir.load() fails to require() module under certain circumstances

When doing

> node

> rechoir = require('../../index.js')  // from inside test fixtures
> rechoir.load('./test.coffee')

rechoir will fail to load the specified module. This is due to the fact that it does not first path.resolve() the specified filepath.

When doing require(path.resolve(filepath)) instead, everything works fine.

Error.message was deprecated a long time ago

In the code we have handleLegacy which relies on Error.message still being available. Since this has been deprecated and replaced by Error.toString(), a new Error should be thrown with the adjusted error message.

wish: expose 'extensions' from interpret

For a use-case like node-config, we'd like to load all supported config files in a specific order.

It would be helpful if rechoir republished the extensions property of interpret so that rechoir could be used both to introspect the supported extensions as well as load them.

Currently interpret needs to be loaded separately for this, which means it ends up appearing in two locations in the dependency tree.

Thanks for considering the update.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.