为React Native Web Project使用适当的编译器

问题描述 投票:2回答:1

我正在尝试创建一个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:

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

我真的对如何设置Webpack或应该如何使用这些文件来摆脱上述错误完全迷失了。

我在哪里添加错误询问的加载器?

抱歉,这是一个令人困惑的问题-RN的这一部分对我来说是全新的

javascript reactjs react-native webpack metro-bundler
1个回答
1
投票

实际上,我遇到了类似的问题,但没有网络问题,我们的项目需要具有独特的逻辑,但是Android和iOS的UI不同,因此我们决定通过.android.js.ios.js文件将具有不同文件的UI分离,其名称为Platform-specific extensions,并在.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"]
    }
  }
}

因此,要使每个堆栈的UI解耦如下:

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配置中以加载到Web构建中,并使用ignore-loader忽略Web构建中的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'], }, }; ,您可以看到我只调用了project on CodeSandBox,但是呈现了import Home from './Home';组件。

通过使用此技巧,您甚至可以在Web构建或开发中使用Home.web.js

© www.soinside.com 2019 - 2024. All rights reserved.