Импорт ES6 из корня

Я сейчас играю с React Native. Я пытаюсь структурировать свое приложение, но оно начинает запутываться с импортом.

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

Теперь, в моем index.ios.js, я могу просто сделать:

import Loading from './components/Loading';

Однако, когда я начинаю создавать больше компонентов, используя более глубокую директорию, он начинает запутываться:

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

Я понимаю, что предпочтительным решением было бы сделать частные модули npm для вещей, но это переполнение для небольшого проекта.

В браузере можно использовать решение типа global.requireRoot, но как это реализовать при импорте?

Ответ 1

Имел ту же проблему с React. Поэтому я написал некоторый плагин для babel, который позволяет импортировать модули с корневой перспективы - пути не короче, но он ясно, что вы импортируете.

Итак, вместо:

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

Вы можете использовать:

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

Вот плагин (протестирован и с четким README)

Ответ 2

Если вы используете Webpack, вы можете настроить его с помощью свойства разрешить, чтобы разрешить путь импорта.

Webpack 1

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

Webpack 2

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

После этого вы можете использовать

import configureStore from "store/configureStore";

вместо:

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

Webpack настроит ваш путь импорта из переданного параметра разрешения.

То же самое можно сделать с загрузчиком System.js, но с его собственным параметром конфигурации (это может быть карта или путь. Проверьте его в документации System.js) (если вы хотите его использовать. Angular 2, но я предлагаю: не используйте стандартные System.js, даже если вы работаете с ng2. Webpack намного лучше).

Ответ 3

С webpack вы также можете создавать пути, начиная с, например, ~ разрешать корневой каталог, поэтому вы можете использовать import Loading from '~/components/Loading';:

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

Трюк использует синтаксис скобки javascript для назначения свойства.

Ответ 4

В Webpack 3 конфигурация немного отличается:

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")
    }
},

Ответ 5

Я только что проверил проект React, которому более 6 месяцев, и по некоторым причинам мой импорт больше не работал. Я попробовал первый ответ:

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

К сожалению, это не сработало.

Я добавил файл .env в корень моего проекта на том же уровне, что и мой package.json. Я добавил следующую строку в этот файл, и это исправило мой импорт в моем проекте.

NODE_PATH=src/

Ответ 6

Если вы используете приложение Create React, вы можете добавить paths.appSrc для resolve.modules в config/webpack.config.dev.js и config/webpack.config.prod.js.

От:

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

Для того, чтобы:

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

Ваш код будет работать:

import Loading from 'components/Loading';

Ответ 7

Если вы используете Create-React-App, вам просто нужно изменить переменную среды NODE_PATH, чтобы она содержала корень вашего проекта.

В вашем config.json сделайте следующее изменение, чтобы установить эту переменную перед запуском команд реагирующих сценариев:

"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"
},

Мы используем библиотеку npm cross-env, потому что она работает на Unix и Windows. Синтаксис команды cross-env var=value command.

Теперь вместо import module from '../../my/module' мы можем сделать import module from 'src/my/module'

Дополнительные детали по реализации

Важно отметить, что область действия cross-env ограничена выполняемой командой, поэтому для команды cross-env var=val command1 && command2 будет установлена только во время command1. Исправьте это, если необходимо, выполнив cross-env var=val command1 && cross-env var=val command2

create-реагировать-приложение отдает приоритет папкам в node_modules/over что в NODE_PATH, поэтому мы устанавливаем NODE_PATH в "." вместо "./src". С помощью "." требует, чтобы все абсолютные импорты начинались с "src/", что означает, что никогда не должно быть конфликта имен, если вы не используете какой-то node_module с именем src.

(Внимание! Решение, описанное выше, заменяет переменную NODE_PATH. В идеале мы добавили бы ее, если она уже существует. NODE_PATH - это список путей, разделенных ":" или ";", в зависимости от того, является ли он unix или windows. Если кто-либо находит кроссплатформенное решение для этого, я могу отредактировать свой ответ.)