web-dev-qa-db-fra.com

ES6 import depuis la racine

Je joue actuellement avec React Native. J'essaie de structurer mon application, mais elle commence à être compliquée par les importations.

--app/
    -- /components
        -- Loading.js
    -- index.ios.js

Maintenant, dans mon index.ios.js je suis capable de faire simplement:

import Loading from './components/Loading';

Cependant, lorsque je commence à créer plus de composants, avec une structure de répertoire plus profonde, cela commence à devenir compliqué:

import Loading from '.../../../../components/Loading';

Je comprends que la solution préférée serait de créer des modules privés pour npm, mais c’est exagéré pour un petit projet.

Vous pouvez créer une solution de type global.requireRoot sur le navigateur, mais comment puis-je l'implémenter avec l'importation?

23
Alias

J'ai eu le même problème avec React . J'ai donc écrit un plugin pour babel qui permet d'importer les modules depuis la perspective racine - les chemins ne sont pas plus courts - mais ce que vous importez est clair.

Donc au lieu de:

import 'foo' from '../../../components/foo.js';

Vous pouvez utiliser:

import 'foo' from '~/components/foo.js';

Voici le plugin (testé et avec un fichier LISEZMOI clair)

28
Michael J. Zoidl

Si vous utilisez Webpack, vous pouvez le configurer via la propriété resol pour résoudre un chemin d’importation.

Webpack 1

resolve: {
  root: [
    path.resolve(__dirname  + '/src')
  ]
}......

Webpack 2

resolve: {
  modules: [
    path.resolve(__dirname + '/src'),
    path.resolve(__dirname + '/node_modules')
  ]
}.....

Après cela, vous pouvez utiliser 

import configureStore from "store/configureStore";

à la place du:

import configureStore from "../../store/configureStore";

Webpack configurera votre chemin d'importation à partir du paramètre de résolution passé.

Même chose que vous pouvez faire avec le chargeur System.js mais avec son propre paramètre de configuration (il peut s'agir de map ou path. Vérifiez-le dans la documentation de System.js) (si vous souhaitez l'utiliser. C'est principalement pour un cas Angular 2. Mais je suggère: n'utilisez pas System.js standard même si vous travaillez avec ng2, Webpack est bien meilleur).

10
Velidan

Avec WebPack, vous pouvez également créer des chemins commençant par, par exemple, ~ à la racine. Vous pouvez donc utiliser import Loading from '~/components/Loading';:

resolve: {
  extensions: ['.js'],
  modules: [
    'node_modules', 
    path.resolve(__dirname + '/app')
  ],
  alias: {
    ['~']: path.resolve(__dirname + '/app')
  }
}

L'astuce consiste à utiliser la syntaxe JavaScript pour attribuer la propriété.

5
Alexander Derck

Dans Webpack 3 la config est légèrement différente:

import webpack from 'webpack';
import {resolve} from 'path';

...

module: {
    loaders: [
        {
            test: /\.js$/,
            use: ["babel-loader"]
        },
        {
            test: /\.scss$|\.css$/,
            use: ["style-loader", "css-loader", "sass-loader"]
        }
    ]
},
resolve: {
    extensions: [".js"],
    alias: {
        ["~"]: resolve(__dirname, "src")
    }
},
4
keemor

Je viens de vérifier un projet React datant de plus de 6 mois et, pour certaines raisons, mes importations ne fonctionnaient plus. J'ai essayé la première réponse:

import 'foo' from '~/components/foo.js';

Malheureusement, cela n'a pas fonctionné.

J'ai ajouté un fichier .env à la racine de mon projet au même niveau que mon package.json. J'ai ajouté la ligne suivante à ce fichier et cela a corrigé mes importations dans mon projet.

NODE_PATH=src/
3
Fasani

Si vous utilisez Create-React-App , il vous suffit de modifier la variable d'environnement NODE_PATH pour contenir la racine de votre projet.

Dans votre config.json, apportez les modifications suivantes pour définir cette variable avant d'exécuter les commandes react-scripts:

"scripts": {
  "start": "cross-env NODE_PATH=. react-scripts start",
  "build": "cross-env NODE_PATH=. react-scripts build",
  "test": "cross-env NODE_PATH=. react-scripts test",
  "eject": "react-scripts eject"
},

Nous utilisons la bibliothèque npm cross-env car elle fonctionne sous unix et windows. La syntaxe est cross-env var=value command.

Maintenant, au lieu de import module from '../../my/module', nous pouvons faire import module from 'src/my/module'

Détails supplémentaires sur la mise en œuvre

Il est important de noter que la portée de cross-env est limitée à la commande qu'il exécute, donc cross-env var=val command1 && command2 n'aura que var défini lors de la commande1. Corrigez ceci si nécessaire en faisant cross-env var=val command1 && cross-env var=val command2

create-react-app donne la priorité aux dossiers de node_modules/à ceux de NODE_PATH, c'est pourquoi nous avons défini NODE_PATH sur "." au lieu de "./src". En utilisant "." exige que toutes les importations absolues commencent par "src /", ce qui signifie qu'il ne devrait jamais y avoir de conflit de nom, à moins que vous n'utilisiez un noeud_module appelé src.

(Attention: la solution décrite ci-dessus remplace la variable NODE_PATH. Idéalement, nous y ajoutons si elle existe déjà. NODE_PATH est une liste de chemins séparée par des ":" ou ";" Unix ou Windows. Si quelqu'un trouve une solution multiplate-forme pour le faire, je peux modifier ma réponse.)

2
Scotty Jamison

Si vous utilisez l'application Create React, vous pouvez ajouter paths.appSrc à resolve.modules dans config/webpack.config.dev.js et config/webpack.config.prod.js.

De:

resolve: {
    modules: ['node_modules', paths.appNodeModules].concat(...

À:

resolve: {
    modules: [paths.appSrc, 'node_modules', paths.appNodeModules].concat(...

Votre code fonctionnerait alors:

import Loading from 'components/Loading';
1
Craig Myles