ImportJS es una herramienta para importar automáticamente dependencias en su proyecto JavaScript. Úselo junto con una de nuestras integraciones de editor para Atom, Emacs, Sublime, Vim o VS Code.
Existen complementos de ImportJS para los siguientes editores:
Puede encontrar instrucciones detalladas sobre cómo instalar ImportJS en los enlaces del editor anteriores.
¿Quieres agregar otro editor a la lista? Vea cómo contribuir.
ImportJS usa Babel 7 desde la versión 3.1.0. En la mayoría de los casos, Babel 7 es compatible con Babel 6, pero si tiene problemas (como este sobre decoradores), considere instalar una versión anterior de ImportJS (por ejemplo, 3.0.0) o actualizar su proyecto para que sea Babel 7. compatible.
Digamos que tienes un proyecto JavaScript con la siguiente estructura:
.
|-- index.html
|-- components
| |-- button.js
| |-- icon.js
|-- vendor
| |--
|-- pages
| |-- index.js
Ahora, imagina que estás editando pages/index.js
que contiene:
document . createElement ( new Button ( { text : 'Save' } ) . toDOMElement ( ) ) ;
En este punto, Button
no está definido, por lo que debemos importarlo. Si está acostumbrado a hacer esto manualmente, esto implica descubrir la ruta al módulo JavaScript que define Button
. Con ImportJS, en su lugar, coloca el cursor en la palabra "Botón", luego presiona <leader>j
(Vim), (Mx) import-js-import
(Emacs) o elige "ImportJS: importar palabra debajo del cursor" (Sublime). El búfer de archivos ahora cambiará a lo siguiente:
import Button from '../components/button' ;
document . createElement ( new Button ( { text : 'Save' } ) . toDOMElement ( ) ) ;
Eso es básicamente todo. ImportJS lo ayudará a encontrar módulos y agregar automáticamente declaraciones import
. Pero sigue leyendo para conocer más funciones interesantes.
ImportJS se puede utilizar para corregir automáticamente todas las importaciones en el archivo actual. Al presionar <leader>i
(Vim), (Mx) import-js-fix
(Emacs) o elegir ImportJS: fix all imports
(Sublime), todas sus variables no definidas se resolverán y todas sus importaciones no utilizadas se eliminarán.
Si está utilizando JSX, ImportJS ya no importará React
automáticamente por usted. Si esto es algo que necesita, considere usar ImportJS versión 5.1.0 o anterior. La necesidad de que las importaciones de React utilicen JSX se eliminó en React 17. Lea más aquí
Dado que ImportJS es bastante bueno para encontrar módulos JS, tiene sentido que haya una opción para abrir/ir a un archivo en lugar de importarlo. Esto es similar a "Abrir archivo debajo del cursor" integrado de Vim. Úselo colocando el cursor en una variable y presione <leader>g
(Vim), (Mx) import-js-goto
(Emacs), o elija "ImportJS: goto module" (Sublime).
.js*
y .ts*
al importargroupImports
y sortImports
. Los comentarios y los espacios en blanco se conservarán si ambos están deshabilitados. ImportJS se configura a través de un archivo JavaScript ( .importjs.js
).
El archivo debe exportar un único objeto que contenga sus ajustes de configuración, como el siguiente ejemplo.
module . exports = {
excludes : [ './react-components/**/test/**' ] ,
// continue with the rest of your settings...
} ;
Guarde este archivo en la carpeta raíz de su proyecto (por ejemplo, donde se encuentra el archivo package.json). También puede guardarlo en el directorio de inicio del usuario si desea compartir una configuración global entre diferentes proyectos.
Se admiten las siguientes opciones de configuración.
aliases
danglingCommas
declarationKeyword
emptyLineBetweenGroups
environments
excludes
globals
groupImports
ignorePackagePrefixes
importDevDependencies
importFunction
importStatementFormatter
logLevel
maxLineLength
mergableOptions
minimumVersion
moduleNameFormatter
namedExports
parserPlugins
sortImports
stripFileExtensions
tab
useRelativePaths
aliases
Es posible que algunos nombres de variables no se asignen fácilmente a un archivo en el sistema de archivos. Para aquellos, puede agregarlos a la configuración aliases
.
aliases: {
$ : 'third-party-libs/jquery' ,
_ : 'third-party-libs/underscore' ,
}
danglingCommas
De forma predeterminada, ImportJS agregará comas al final al crear declaraciones de importación con varias importaciones con nombre.
Puede desactivar este comportamiento configurando danglingCommas
en false
.
danglingCommas: false ;
declarationKeyword
El valor predeterminado para esta propiedad es import
, lo que hace que sus declaraciones de importación utilicen la sintaxis de los módulos ES2015:
import Foo from 'foo' ;
Los alias se pueden dinamizar utilizando la cadena {filename}
. Esta parte del alias será reemplazada por el nombre del archivo que estás editando actualmente.
p.ej
aliases: {
styles : './{filename}.scss' ,
}
lo hará para un archivo foo/bar.js
como resultado
import styles from './bar.scss' ;
emptyLineBetweenGroups
De forma predeterminada, ImportJS insertará una línea vacía entre los grupos de importación.
Puede desactivar este comportamiento configurando emptyLineBetweenGroups
en false
.
emptyLineBetweenGroups: false ;
environments
Esta lista de entornos controla qué módulos principales están disponibles al importar y qué variables se consideran globales de forma predeterminada. Los valores admitidos en este momento son
['meteor']
- hace que los módulos principales de Meteor estén disponibles y agrega un montón de elementos globales de meteorito['node']
- hace que todos los módulos principales de Node estén disponibles y agrega un montón de nodos globales['browser']
- agrega un montón de elementos globales del navegador['jasmine']
- agrega un montón de globales de jazmín['jest']
- agrega un montón de globales de bromaenvironments: [ 'meteor' , 'node' ] ;
excludes
Defina una lista de patrones globales que coincidan con archivos y directorios que no desea incluir para la importación.
excludes: [ './react-components/**/test/**' ] ;
globals
Proporcione una lista de identificadores globales utilizados en el código. ImportJS los ignorará cuando intente importar todas las variables no definidas.
Nota: Si utiliza correctamente la opción de configuración environments
, es posible que no necesite especificar globales .
groupImports
De forma predeterminada, ImportJS colocará las importaciones en grupos:
Puede desactivar este comportamiento configurando groupImports
en false
. Cuando está deshabilitada, las importaciones se enumeran alfabéticamente en una lista.
groupImports: false ;
ignorePackagePrefixes
Si tiene dependencias de paquetes especificadas en package.json
que tienen el prefijo, por ejemplo, el nombre de una organización, pero desea poder importarlas sin el prefijo del paquete, puede configurar la opción de configuración ignorePackagePrefixes
.
ignorePackagePrefixes: [ 'my-company-' ] ;
Cuando las dependencias del paquete coinciden, estos prefijos se ignorarán. Como ejemplo, una variable denominada validator
coincidiría con un paquete denominado my-company-validator
.
importDevDependencies
ImportJS buscará las dependencias de paquetes enumeradas en package.json
al importar. De forma predeterminada, solo se utilizarán los módulos enumerados en dependencies
y peerDependencies
. Al establecer importDevDependencies
en true
, también se tendrán en cuenta devDependencies
.
importDevDependencies: true ;
importFunction
Nota: esto solo se aplica si está utilizando var
o const
como declarationKeyword
.
El valor predeterminado para esta opción de configuración es "require"
, que es el nombre de función estándar de CommonJS utilizado para la importación.
importFunction: 'myCustomRequireFunction' ;
importStatementFormatter
Utilice una función aquí para controlar cómo se verá la declaración de importación resultante. Esto es útil si, por ejemplo, desea eliminar los puntos y coma finales (que ImportJS agrega de forma predeterminada).
Nota: este método sólo debe utilizarse en casos excepcionales. Existe la posibilidad de que ImportJS no pueda reconocer la declaración de importación resultante la próxima vez que esté a punto de importar algo.
importStatementFormatter ( { importStatement } ) {
return importStatement . replace ( / ;$ / , '' ) ;
} ,
logLevel
Uno de ["debug", "info", "warn", "error"]
. Esto controla lo que termina en el archivo de registro. El valor predeterminado es info
.
logLevel: 'debug' ;
El archivo de registro se escribe en "importjs.log" en el directorio predeterminado de su sistema operativo para archivos temporales. Puede obtener la ruta al archivo de registro ejecutando importjs logpath
.
maxLineLength
El valor predeterminado es 80
. Esta configuración controla cuándo las declaraciones de importación se dividen en varias líneas.
maxLineLength: 70 ;
mergableOptions
Un diccionario de opciones que se fusionan con los valores predeterminados y proporcionados por un environment
. Esto se puede utilizar para sobrescribir las opciones proporcionadas por los entornos. El valor predeterminado es:
mergableOptions: {
aliases : true ,
coreModules : true ,
namedExports : true ,
globals : true ,
}
Nota: la opción mergableOptions
siempre se fusionará y se ignorará si se incluye en una configuración de usuario.
Para deshabilitar la combinación de una opción o conjunto de opciones en particular, establezca la clave en false
:
mergableOptions: {
globals: false ;
}
Por ejemplo, si está utilizando el entorno meteor
pero desea importar explícitamente módulos que se proporcionan como globales, puede usar esta configuración para sobrescribir los globales del entorno.
const globals = require ( 'globals' ) ;
module . exports = {
environments : [ 'meteor' , 'node' ] ,
mergableOptions : {
globals : false , // Overwrite globals
} ,
globals : [
// Add the globals you want back in
... Object . keys ( globals . builtin ) , // include javascript builtins
... Object . keys ( globals . node ) , // include node globals
'Package' ,
'Npm' , // Include meteor globals for `package.js` files
] ,
} ;
minimumVersion
Configurar minimumVersion
advertirá a las personas que estén ejecutando una versión de ImportJS anterior a la que requiere su archivo de configuración .importjs.js
. Si la versión de su complemento es anterior a este valor, se le mostrará una advertencia que lo insta a actualizar su complemento.
minimumVersion: '1.0.0' ;
moduleNameFormatter
Utilice una función aquí para controlar cómo se verá la cadena de nombre del módulo resultante. Es útil si, por ejemplo, desea agregar un prefijo personalizado a determinadas importaciones. Además de los valores estándar pathToCurrentFile
y pathToImportedModule
pasados a todas las funciones de configuración, a este método también se le pasa un valor moduleName
, que en general es lo que desea manipular.
moduleNameFormatter ( { moduleName , pathToCurrentFile } ) {
if ( / -test / . test ( pathToCurrentFile ) ) {
// Import a mocked version in test files
return `mocks/ ${ moduleName } ` ;
}
if ( moduleName . startsWith ( 'foo' ) ) {
// Add a leading slash to foo imports
return `/ ${ moduleName } ` ;
}
// Fall back to the original specifier. It's important that this function
// always returns a string.
return moduleName ;
} ,
namedExports
*Nota: Desde 2.1.0, ImportJS encuentra automáticamente las exportaciones con nombre. Lo más probable es que no necesites esta opción. Si termina teniendo que usar esta configuración de todos modos, puede haber un error en las partes de búsqueda de exportaciones de ImportJS. ¡Presenta un problema y cuéntanoslo!
Si tiene un módulo ES6/ES2015 que exporta varias cosas (exportaciones con nombre), o un módulo CommonJS que exporta un objeto con propiedades que desea desestructurar al importar, puede agregarlos a una opción de configuración namedExports
.
namedExports: {
underscore : [
'omit' ,
'debounce' ,
'memoize'
] ,
'lib/utils' : [
'escape' ,
'hasKey' ,
] ,
}
Las importaciones que utilizan la palabra clave de declaración import
utilizan la sintaxis de importaciones con nombre. p.ej
import { memoize } from 'underscore' ;
memoize ( ( ) => {
foo ( ) ;
} ) ;
y las importaciones que usan const
o var
usan [ES2015 Destructuring Assigment][asignación de destrucción], por ejemplo
const { memoize } = require ( 'underscore' ) ;
memoize ( ( ) => {
foo ( ) ;
} ) ;
La clave utilizada para describir las exportaciones nombradas debe ser una ruta de importación válida. Esto puede ser, por ejemplo, el nombre de un paquete que se encuentra en node_modules
, una ruta a un módulo que usted mismo creó o una ruta de importación relativa.
Considere el ejemplo como un caso de uso válido para la propiedad namedExports
. Digamos que tenemos un archivo:
import { Provider } from 'react-redux' ;
import React from 'react' ;
import store from './redux/redux-store' ;
import ReactDOM from 'react-dom' ;
import App from './App' ;
ReactDOM . render (
< BrowserRouter >
< Provider store = { store } >
< App / >
< / Provider >
< / BrowserRouter > ,
document . getElementById ( 'root' ) ,
) ;
Y vamos a importar BrowserRouter
pero en lugar del resultado deseado obtenemos el módulo No JS para importar el mensaje de BrowserRouter
. Para solucionar el problema, complete namedExports
en su archivo de configuración de la siguiente manera:
namedExports: {
'react-router-dom' : [ 'BrowserRouter' , 'Route' , 'Redirect' ]
}
Después de eso podremos importar BrowserRouter
correctamente. La declaración de importación resultante se verá así:
import { BrowserRouter } from 'react-router-dom'
Si aún no está listo para ES2015, tiene la opción de usar var
o const
en su lugar.
declarationKeyword: 'const' ;
En tal caso, sus declaraciones de importación se verán así:
var Foo = require ( 'foo' ) ; // "declarationKeyword": "var"
const Foo = require ( 'foo' ) ; // "declarationKeyword": "const"
parserPlugins
ImportJS tiene por defecto un compromiso razonable en cuanto a la sintaxis que debe admitir, pero puede anularse (reemplazarse) en la configuración. Los últimos valores predeterminados se pueden encontrar aquí
Los complementos disponibles han terminado en Babel: Lista de complementos
parserPlugins: [ ]
hack
) Cuando se especifica parserPlugins
, debe volver a agregar los valores predeterminados.
parserPlugins: [
'jsx' ,
'doExpressions' ,
'objectRestSpread' ,
'decorators-legacy' ,
'classProperties' ,
'classPrivateProperties' ,
'classPrivateMethods' ,
'exportExtensions' ,
'asyncGenerators' ,
'functionBind' ,
'functionSent' ,
'dynamicImport' ,
'numericSeparator' ,
'optionalChaining' ,
'importMeta' ,
'bigInt' ,
'optionalCatchBinding' ,
'throwExpressions' ,
'nullishCoalescingOperator' ,
'exportNamespaceFrom' ,
'exportDefaultFrom' ,
[
'pipelineOperator' ,
{
proposal : 'hack' ,
} ,
] ,
] ;
sortImports
De forma predeterminada, ImportJS ordenará las importaciones por el nombre o la ruta del módulo importado.
Puede desactivar este comportamiento configurando sortImports
en false
. Cuando está deshabilitado, las importaciones existentes no se reorganizan y las nuevas importaciones siempre se agregan encima de las existentes.
sortImports: false ;
stripFileExtensions
Una matriz que controla qué extensiones de archivo se eliminan de la declaración de importación resultante. La configuración predeterminada elimina [".js", ".jsx", ".ts", ".tsx"]
. Establezca una matriz vacía []
para evitar eliminar extensiones.
stripFileExtensions: [ '.web.js' , '.js' ] ;
tab
El valor predeterminado es dos espacios ( " "
). Esta configuración controla cómo se construye la sangría cuando las declaraciones de importación se dividen en varias líneas.
tab: 't' ;
useRelativePaths
Esta opción está habilitada de forma predeterminada. Cuando está habilitado, las importaciones se resolverán en relación con el archivo actual que se está editando.
import Foo from './foo' ;
import Bar from '../baz/bar' ;
Puedes desactivar esto configurándolo en falso:
useRelativePaths: false ;
Las dependencias del paquete (ubicadas en node_modules
) no se importarán relativamente.
Diferentes secciones de su aplicación pueden tener necesidades de importación especiales. Por ejemplo, es posible que sus pruebas necesiten la palabra clave de declaración 'const'
, pero el resto de su aplicación puede usar 'import'
. Para poder abordar estos casos especiales, puede convertir su opción de configuración en una función. Cuando ImportJS resuelve una opción de configuración, comprobará si se utiliza una función. En tal caso, la función se invoca con los siguientes argumentos:
pathToCurrentFile
: (siempre disponible) Una ruta al archivo que está editando.pathToImportedModule
(no disponible para algunas opciones) Una ruta al archivo/módulo que está importando. A continuación se muestra un ejemplo de cómo controlar dinámicamente la opción de configuración declarationKeyword
según el archivo que está importando:
// .importjs.js
function isTestFile ( path ) {
return path . endsWith ( '-test.js' ) ;
}
module . exports = {
declarationKeyword ( { pathToImportedModule } ) {
if ( isTestFile ( pathToImportedModule ) ) {
return 'const' ;
}
return 'import' ;
} ,
} ;
Aquí hay un ejemplo más elaborado que tiene en cuenta pathToImportedModule
y pathToCurrentFile
:
module . exports = {
useRelativePaths ( { pathToImportedModule , pathToCurrentFile } ) {
if ( pathToCurrentFile . endsWith ( '-mock.js' ) ) {
return false ;
}
if ( pathToImportedModule . endsWith ( '-test.js' ) ) {
return false ;
}
return true ;
} ,
} ;
Para utilizar funciones, debe utilizar el archivo de configuración de JavaScript ( .importjs.js
).
ImportJS viene con una práctica herramienta de línea de comandos que puede ayudarle a realizar importaciones fuera de un editor. En el fondo, esto es lo que utilizan la mayoría de las integraciones del editor.
⨠ importjs --help
Usage: importjs [options] [command]
Commands:
word [options] < word > < pathToFile >
search [options] < word > < pathToFile >
fix [options] < pathToFile >
rewrite [options] < pathToFile >
add [options] < imports > < pathToFile >
goto < word > < pathToFile >
start [options] start a daemon
cachepath show path to cache file
logpath show path to log file
Options:
-h, --help output usage information
-V, --version output the version number
Examples:
$ importjs word someModule path/to/file.js
$ importjs search someModule * path/to/file.js
$ importjs fix path/to/file.js
$ importjs rewrite --overwrite path/to/file.js
$ importjs add ' { "foo": "path/to/foo", "bar": "path/to/bar" } ' path/to/file.js
$ importjs goto someModule path/to/file.js
$ importjs cachepath
$ importjs logpath
$ importjs start --parent-pid=12345
Si desea cambiar la forma en que se construyen las importaciones en un proyecto existente, puede usar la herramienta de línea de comandos en combinación con find
para actualizar por lotes un conjunto de archivos. P.ej
find ./app -name " **.js* " -exec importjs rewrite --overwrite {} ;
Dado que el indicador --overwrite
hace que ImportJS sea destructivo (los archivos se sobrescriben), es bueno verificar que el comando find
devuelva los archivos correctos antes de agregar la parte -exec
.
ImportJS busca el archivo package.json
en el directorio ancestral más cercano al archivo que está editando para encontrar módulos de nodo para importar. Sin embargo, a veces puede extraer dependencias de un directorio que se encuentra más arriba en la cadena. Por ejemplo, la estructura de su directorio podría verse así:
.
|-- package.json
|-- components
| |-- button.js
| |-- icon.js
|-- node_modules
| |-- react
|-- subpackage
| |-- package.json
| |-- components
| |-- bulletin.js
Si usara ImportJS en subpackage/components/bulletin.js
que importa React, ImportJS no sabría que react
es una dependencia válida.
Para indicarle a ImportJS que omita un directorio y siga buscando hacia arriba para encontrar el directorio del paquete raíz, especifique "importjs": { "isRoot": false }
en el package.json
del directorio a ignorar. En este caso, querrás algo como esto:
{
"name" : " subpackage " ,
...
"importjs" : {
"isRoot" : false
}
}
Nota : esta sección está destinada principalmente a desarrolladores de complementos de edición. Si está utilizando uno de los complementos del editor estándar, lo más probable es que ya esté utilizando el demonio oculto.
Puede ejecutar ImportJS en un proceso en segundo plano y comunicarse con él mediante stdin
y stdout
. Esto hará que la importación sea más rápida porque no estamos activando un entorno de nodo en cada invocación.
El demonio se inicia ejecutando importjs
. Acepta comandos enviados a través de stdin
. Cada comando es una cadena JSON (de una línea) que termina con una nueva línea. La estructura del comando es básicamente la misma que la de la herramienta de línea de comando, pero envuelta en JSON en lugar de expresada en la línea de comando. A continuación se muestran algunos ejemplos:
Ejecute fix imports
:
{
"command" : " fix " ,
"fileContent" : " const foo = bar(); n " ,
"pathToFile" : " foo.js "
}
Importar una sola palabra:
{
"command" : " word " ,
"commandArg" : " bar " ,
"fileContent" : " const foo = bar(); n " ,
"pathToFile" : " foo.js "
}
Ir a:
{
"command" : " goto " ,
"commandArg" : " bar " ,
"fileContent" : " const foo = bar(); n " ,
"pathToFile" : " foo.js "
}
Los resultados se imprimen en stdout
en formato JSON. La respuesta tendrá el mismo aspecto que la que produce la herramienta de línea de comandos. Si ocurre un error, también terminará en stdout
como JSON (un objeto con una clave error
).
Al iniciarse, el demonio imprimirá una ruta a un archivo de registro. Si desea saber qué sucede detrás de escena, puede inspeccionar este archivo. Si no tiene acceso al registro de la consola del demonio, encontrará el archivo de registro en os.tmpdir() + '/importjs.log
(que se resolverá en algo como var/folders/1l/_t6tm7195nd53936tsvh2pcr0000gn/T/importjs.log
en una Mac).
Si tiene una aplicación grande, recorrer el sistema de archivos para buscar módulos puede resultar lento. Es por eso que ImportJS tiene integración incorporada con Watchman, un servicio de visualización de archivos rápido y sólido desarrollado por Facebook. Todo lo que tiene que hacer para aumentar el rendimiento es instalar Watchman localmente y asegurarse de utilizar un complemento de edición actualizado (Watchman solo se usa cuando ImportJS se ejecuta como demonio).
Consulte el documento CONTRIBUTING.md para obtener sugerencias sobre cómo ejecutar, probar y desarrollar ImportJS localmente.
¡Feliz pirateo!