test - Mejor manera de requerir extensiones con Node.js
mocha npm (3)
Estoy probando un montón de componentes React JSX. Todos deben ser transpilados con React, o Babel o lo que sea, pero tenemos necesidades especiales para los requisitos de aplastamiento, así que estoy tratando de anular los requisitos con un compilador especial que se ejecuta con Mocha. La solución a continuación funciona bien, pero notará que estamos usando require.extensions [] para capturar todos los archivos .jsx. Lo que me preocupa es que require.extensions está bloqueado y en desuso. ¿Hay alguna manera mejor de hacer esto?
// Install the compiler.
require.extensions[''.jsx''] = function(module, filename) {
return module._compile(transform(filename), filename);
};
Aquí está todo el transpiler para referencia:
// Based on https://github.com/Khan/react-components/blob/master/test/compiler.js
var fs = require(''fs''),
ReactTools = require(''react-tools'');
// A module that exports a single, stubbed-out React Component.
var reactStub = ''module.exports = require("react").createClass({render:function(){return null;}});'';
// Should this file be stubbed out for testing?
function shouldStub(filename) {
if (!global.reactModulesToStub) return false;
// Check if the file name ends with any stub path.
var stubs = global.reactModulesToStub;
for (var i = 0; i < stubs.length; i++) {
if (filename.substr(-stubs[i].length) == stubs[i]) {
console.log(''should stub'', filename);
return true;
}
}
return false;
}
// Transform a file via JSX/Harmony or stubbing.
function transform(filename) {
if (shouldStub(filename)) {
delete require.cache[filename];
return reactStub;
} else {
var content = fs.readFileSync(filename, ''utf8'');
return ReactTools.transform(content, {harmony: true});
}
}
// Install the compiler.
require.extensions[''.jsx''] = function(module, filename) {
return module._compile(transform(filename), filename);
};
Y algunos enlaces a soluciones simalar ...
- https://github.com/danvk/mocha-react/issues/1
- https://github.com/Automattic/jsx-require-extension
- https://www.npmjs.com/package/node-jsx
- https://github.com/olalonde/better-require
- http://mochajs.org/#usage
- http://nodejs.org/api/globals.html#globals_require_extensions
Se puede encontrar una solución desde aquí: https://github.com/danvk/mocha-react
Hay dos razones por las que la API ha quedado en desuso. Uno, el algoritmo de resolución del módulo de nodo es MUY complicado, tiene que mirar el archivo especificado, si no existe, busca ese archivo y todas las posibles extensiones en las claves de require.extensions
, y si es un directorio, busque un package.json o index.js. Ah, y no se olvide, si no hay ./
al principio, se ve en el directorio node_modules, mirando el directorio principal si no se puede encontrar en ese node_modules
. Ryan Dahl dijo que se arrepiente de haberlo hecho tan complicado en su charla en JsConf 2018 , y utiliza un algoritmo de resolución de módulo mucho más simple en su proyecto de deno . Dos, necesita más llamadas al sistema de archivos si hay más extensiones en require.extensions, porque tiene que coincidir con archivos sin extensión.
Una solución al segundo problema es require-extension . No lo he usado, pero abstrae la API require.extensions y la hace mucho más eficaz.
No hay otra manera de hacer esto, y así es como todo el mundo hace la transposición (babel, etc.). La respuesta de @uni_nake - para usar node-hook - está bien porque oculta esto de usted, pero esencialmente usa el mismo mecanismo: una mirada en su código muestra que usa Module._extensions, pero esto es lo mismo que require.extensions , como lo demostró una prueba que escribí: https://github.com/giltayar/playing/blob/1f04f6ddc1a0028974b403b4d1974afa872edba4/javascript/node/test/is-module-extensions-same-as-require-extensions.test.js
Entonces, la respuesta final: supondría que nadie en Node romperá a Babel, y si lo hacen, probablemente darán otra solución para el mismo problema. ¡No dudaría en usarlo!
Uso el node-hook para .scss
todas .scss
llamadas .scss
en mis pruebas.
Verá en los documentos que cuando se requiere un archivo coincidente, ejecutará la cadena que lo contiene y es bastante poderoso, ya que también le pasa la fuente original.
Espero que eso sea lo que estás buscando.