передать переменные окружения на этапе сборки babel для импорта различных файлов - PullRequest
0 голосов
/ 29 сентября 2018

Я создаю сеть (react с webpack & babel) и мобильные приложения (react-native с expo) для проекта.Поэтому я создал общую библиотеку для бизнес-логики и библиотеки redux / api.

Некоторый код будет немного отличаться в сети и на мобильных устройствах.В моем случае это localStorage vs AsyncStorage, который я использую для аутентификации между прочим ...

Я пытаюсь передать переменную окружения на этапе сборки для переключения импорта определенных файлов так что правильный файл загружается для каждой сборки, которая просто связана с путем (т.е. без предварительной сборки моей библиотеки, я просто делаю import '../mylib'), например:

if(PLATFORM === 'mobile'){
   import StorageModule from './mobile-storage-module`
} else {
   import StorageModule from './mobile-storage-module`
}
export default StorageModule

Попробуйте 1

@babel/preset-env, чтобы сказать, является ли он мобильным или веб-, так что он импортирует различные библиотеки в зависимости от сборки, например, так:

My .babelrc имеет это:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "platform": "mobile"
      }
    ]
  ]
}

И затем в локальном хранилище я делаю это:

export default () => {
    const platform = process.env.platform
    if (platform === 'mobile') {
        return import './storage-modules/storage-mobile'
    }
    return import './storage-modules/storage-web'
}

Это не сработало, и это также не сработало для меня.

Попробуйте 2

Я установил act-native-dotenv и создал файл .env с: PLATFORM=mobile И установил плагин в мой .babelrc:

{
  "presets": [
    "babel-preset-expo",
    "react-native-dotenv"
  ]
}

И в моем примере файла я попробовал это:

import { PLATFORM } from 'react-native-dotenv'
export default PLATFORM === 'mobile' ? import './storage-modules/storage-mobile' : import './storage-modules/storage-web'

Но теперь моя сборка не работает.Любая идея, как я делаю динамический импорт во время процесса сборки, который работает для babel в реакции-нативной сборке приложений и веб-пакетов (также использует babel)?

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

Поскольку заголовок вашего вопроса гласит: " на этапе сборки Babel ", я предполагаю, что вы хотели бы сделать разные сборки для настольных компьютеров и мобильных устройств (не одну для обоих и загружать необходимые модули динамически во время выполнения),Поэтому я бы сказал так:

Определите сценарии запуска в package.json для настольных и мобильных устройств:

"scripts": {
  "devmobile": "cross-env NODE_ENV=development PLATFORM=mobile webpack --progress",
  "dev": "cross-env NODE_ENV=development webpack --progress",
}

... или вы можетесоздайте два разных webpack.config.js файла для настольных и мобильных сборок, но я думаю, что выше легче ...

Затем npm run devmobile для сборки для мобильных устройств и npm run dev для настольных компьютеров.

Поскольку я в Windows, я использую пакет cross-env , но это рекомендуемый способ быть независимым от ОС.

Тогда я быиспользуйте Webpack NormalModuleReplacementPlugin:
(на основе этот пример )

В вашем webpack.config.js:

// defining the wanted platform for the build (comfing form the npm run script)
const targetPlatform = process.env.PLATFORM || 'desktop';

// then use the plugin like this
plugins: [
  new webpack.NormalModuleReplacementPlugin(/(.*)-PLATFORM(\.*)/, function(resource) {
    resource.request = resource.request.replace(/-PLATFORM/, `-${targetPlatform}`);
  }),
]

...затем, если у вас есть эти два файла:

./storage-modules/storage-mobile.js
./storage-modules/storage-desktop.js

импортируйте нужный файл в ваш скрипт следующим образом:

import './storage-modules/storage-PLATFORM';

Таким образом, сгенерированная сборка будет содержать только файл, необходимый для текущегоПЛАТФОРМА, используемая для процесса сборки.

Другим возможным решением может быть ifdef-загрузчик , но я его не тестировал.Может быть, стоит попробовать, кажется, просто.


Если вы хотите создать хотя бы одну сборку и динамически импортировать нужный модуль, вы можете сделать что-то подобное в вашем app.js (или как угодно):

// this needs to have defined when the app is running
const targetPlatform = process.env.PLATFORM || 'desktop';

import(
    /* webpackChunkName: "[request]" */
    `./storage-modules/storage-${targetPlatform}`
).then(storageModule => {
    // use the loaded module
});

или:

(async () => {
    const storageModule = await import(
        /* webpackChunkName: "[request]" */
        `./storage-modules/storage-${targetPlatform}`
    );
    // use the loaded module
})();

Чтобы это работало, Babel должен быть настроен .
Подробнее о Webpack с динамическим импортом здесь .

0 голосов
/ 22 ноября 2018

Вы можете использовать transform-inline-environment-variable для передачи платформы в babel

"build-mobile": "PLATFORM=mobile ...",
"build-app": "PLATFORM=app ...",
0 голосов
/ 02 октября 2018

Во-первых, @babel/preset-env не делает то, что вы думаете, что делает.Это не для указания ваших собственных переменных, это плагин для автоматического использования правильной цели и pollyfills для браузеров, которые вы хотите поддерживать.

Самый простой способ получить переменные среды - с помощью плагина определения веб-пакета (которыйявляется частью веб-пакета, поэтому не нужно устанавливать ничего лишнего)

Просто добавьте это в конфигурацию вашего веб-пакета.

plugins: [
    new webpack.DefinePlugin({
        'process.env': {
            platform: 'mobile',
        },
    }),
],

Далее, вы не можете использовать обычные операторы import внутрисослагательное наклонение.import разрешается до запуска любого кода, либо при сборке через веб-пакет, либо в поддерживаемых средах при загрузке скрипта.Чтобы импортировать что-то во время выполнения, вам нужно использовать динамический импорт.

Вот пример того, как это может выглядеть.

export default new Promise(async resolve => {
    resolve(
        process.env.platform === 'mobile'
            ? (await import('./mobile.js')).default
            : (await import('./desktop.js')).default
    );
});

Теперь вы можете импортировать из этого файла, как обычно, но имейте в виду, что экспорт по умолчанию является обещанием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...