Использование соответствующих транспортеров для React Native Web Project - PullRequest
2 голосов
/ 10 апреля 2020

Я пытаюсь создать проект React Native Web.

Ранее я создал несколько приложений React Native, но никогда не пытался разместить их в Интернете.

Моя самая большая проблема связана с была несовместимость нативных библиотек при запуске Интернета - не неожиданная проблема.

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

Например, я получаю текущую ошибку:

./node_modules/react-native-calendars/src/expandableCalendar/asCalendarConsumer.js
Module parse failed: Unexpected token (11:8)
You may need an appropriate loader to handle this file type.
|     render() {
|       return (
|         <CalendarContext.Consumer>
|           {(context) => (
|             <WrappedComponent

Как бы это исправить? Эта библиотека теоретически совместима с React Native Web, и все же я получаю вышеуказанную ошибку.

Будет ли этот загрузчик находиться в Babel? Метро? Webpack?

У меня есть babel.config. js, который выглядит так:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  resolve: {
    alias: {
      'react-native$': 'react-native-web'
    }
  },
  rules: [
    {
      test: /\.(js|jsx|mjs)$/,
      include: [
        paths.src,
        // In order to use react-native targetted libraries on web,
        // we have to use babel to compile them from ES6 to ES5.
        // This would still not allow us to use libraries that have RN
        // dependencies that are not polyfilled by react-native-web.
        path.resolve(paths.nodeModules, 'react-native-vector-icons'),
      ],
      loader: 'babel-loader',
      options: {
        compact: true,
        presets: ['react-native'],
      },
    }
  ]
};

У меня есть метро, ​​которое выглядит так:

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-css-transformer")
    },
    resolver: {
      sourceExts: [...sourceExts, "css"]
    }
  };
})();

А вот мой веб-пакет:

// webpack.config.js
module.exports = {
    plugins: ["@babel/plugin-syntax-dynamic-import"],

    resolve: {
        alias: {
            'react-native$': 'react-native-web'
        },
    },
    rules: [
        {
            test: /\.js$/,
            loader: 'babel-loader',
            //exclude: /node_modules/,
            options: {
                presets: ['es2015', 'stage-0', 'react', 'babel-preset-env', 'babel-preset-stage-0'],
                plugins: ["@babel/plugin-syntax-dynamic-import"],
            }
        },
        {
            test: /\.ttf$/,
            loader: "url-loader", // or directly file-loader
            include: path.resolve(__dirname, "node_modules/react-native-vector-icons"),
        },
    ]
}

Я действительно совершенно заблудился о том, как настроить веб-пакет или как я должен использовать эти файлы, чтобы избавиться от вышеуказанной ошибки.

Куда добавить загрузчик, о котором спрашивает ошибка?

Извините, если это запутанный вопрос - эта часть RN для меня совершенно новая

1 Ответ

1 голос
/ 17 апреля 2020

На самом деле, я столкнулся с такой проблемой, но не с Интернетом. Наш проект должен иметь уникальный лог c, но разные пользовательские интерфейсы для Android и iOS, поэтому мы решили отделить пользовательские интерфейсы от разных файлов, .android.js и .ios.js файлы, его имя Платформа-спецификация c расширения , а также его настройка в файле .babelrc:

{
  "presets": ["module:metro-react-native-babel-preset", "module:react-native-dotenv"],
  "plugins": [
    "lodash",
    ["module-resolver", {
      "extensions": [".android.js", ".ios.js", ".js"], // here
      "cwd": "babelrc",
      "root": ["./app"]
    }]
  ],
  "env":{
    "production":{
      "plugins": ["transform-remove-console"]
    }
  }
}

Так что для отделения пользовательского интерфейса для каждого стека, как показано ниже:

CheckoutPage.android.js
CheckoutPage.ios.js

Для импорта компонента мы используем этот способ:

import Checkout from '[pathToComponent]/CheckoutPage';

~~~

<CheckoutPage ...

Решение:

Теперь мое предложение использует другое расширение файла, web.js, и поместите его в конфигурацию babel:

"extensions": [".android.js", ".ios.js", ".web.js", ".js"],

Кроме того, добавьте расширение web.js в конфигурацию Webpack для загрузки в веб-сборку и используйте ignore-loader для игнорирования .ios.js и .android.js файлов в веб-сборке:

// webpack configuration file

module.exports = {

  module: {
    rules: [
      {
        test: /\.(js|web.js)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.(android.js|ios.js)$/,
        exclude: /node_modules/,
        use: {
          loader: "ignore-loader",
        },
      },
    ],
  },

  ~~~

  resolve: {
    extensions: ['.web.js', '.js'],
  },
};

Для лучшего объяснения я создаю проект на CodeSandBox , и вы можете увидеть там я просто вызываю import Home from './Home';, но компонент Home.web.js отображается.

При использовании это трюк, который вы можете использовать platform-specific extensions даже в веб-сборке или разработке.

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