首页 > 解决方案 > Babel 不处理 ES6 导入 react-native 包

问题描述

在 Babel 7.11 中,使用 react-native 0.63.2 和 react-native-web 0.13.9,我无法让 webpack-dev-server 构建应用程序,因为它无法识别 react-native 中的“导入”。

我采取了许多不同的方法来解决这个问题,但无济于事。唉!

这是错误:

    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    /Users/byofuel/code/sevminhebrew/node_modules/react-native/index.js:13
    import typeof AccessibilityInfo from './Libraries/Components/AccessibilityInfo/AccessibilityInfo';
    ^^^^^^
    
    SyntaxError: Unexpected token import
        at createScript (vm.js:80:10)
        at Object.runInThisContext (vm.js:139:10)
        at Module._compile (module.js:617:28)
        at Object.Module._extensions..js (module.js:664:10)
        at Module.load (module.js:566:32)
        at tryModuleLoad (module.js:506:12)
        at Function.Module._load (module.js:498:3)
        at Module.require (module.js:597:17)
        at require (internal/module.js:11:18)
        at requireModule (/Users/byofuel/code/sevminhebrew/node_modules/@babel/core/lib/config/files/plugins.js:165:12)
     @ multi ./index.web.js main[0]

这是我的 webpack.config.js:

const path = require('path');
const _ = require('lodash');
const fs = require('fs');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const dotenv = require('dotenv');

const webfillsFolder = 'webfills';

// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfig = {
  test: /\.js$/,
  // exclude: [/node_modules/, /react-native-web/, /\.(native|ios|android)\.(ts|js)x?$/],
  // exclude: /node_modules/,  // this can't be excluded because react-native modules need to be transpiled (like react-native-gesture-handler)
  // Add every directory that needs to be compiled by Babel during the build
  include: [
    path.resolve(__dirname, 'index.web.js'),
    path.resolve(__dirname, 'app'),
    // These are the CRNA libraries that work, if you just babel them.\
    path.resolve(__dirname, 'node_modules/react-native-safe-area-view'),
    path.resolve(__dirname, 'node_modules/react-native-tab-view'),
    path.resolve(__dirname, 'node_modules/react-native'),
    // path.resolve(__dirname, 'node_modules/react-native-web'),
    path.resolve(__dirname, 'node_modules/react-navigation'),
    path.resolve(__dirname, 'node_modules/react-native-web-linear-gradient'),
    // path.resolve(__dirname, 'node_modules/react-native-gesture-handler')
  ],
  use: {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true,
      plugins: [
        'react-native-web',
        '@babel/plugin-transform-flow-strip-types',
        '@babel/plugin-proposal-class-properties', // ie. static methods and property assignments in ES6 classes
      ],

      // The 'react-native' preset is recommended (or use your own .babelrc)
      presets: ['module:react-native', '@babel/preset-env'],
      // rootMode: "upward",
    },
  },
};


// This is needed for webpack to import static images in JavaScript files
const fileLoader = {
  test: /\.(jpe?g|png|gif|svg|wav|mp3)$/,
  loader: 'file-loader',
  exclude: /node_modules/
};

const aliases = Object.assign({}, fs.readdirSync(webfillsFolder).filter(
    f => fs.statSync(`${webfillsFolder}/${f}`).isDirectory()).reduce((mods, mod) => {
    console.log(`Webfill detected: ${mod}`);
    if (mod !== 'react-native-drawer-layout') mods[mod] = path.join(__dirname, webfillsFolder, mod);
    return mods;
  }, {}),
  {
    // 'react-native$': 'react-native-web',
    // 'react-navigation': path.resolve(__dirname, './react-navigation.web.js'),
    'react-native-web/dist/exports/DeviceInfo': path.resolve('./react-native-web-device-info.web.js'),
    'react-native-linear-gradient': 'react-native-web-linear-gradient'
  }
);

function buildConfig(env) {
  let envVars;
  // determine which .env file to use
  if (env.prod) {
    envVars = dotenv.config({ path: '.env.production' }).parsed;
  } else if (env.staging) {
    envVars = dotenv.config({ path: '.env.staging' }).parsed;
  } else if (env.dev) {
    // dev mode sets variables to staging but it's still built with development checks
    envVars = dotenv.config({ path: '.env.staging' }).parsed;
  } else if (env.local) {
    envVars = dotenv.config({ path: '.env.local' }).parsed;
  } else {
    throw new Error('Unknown stage, plese specify --env.{dev|qa|prod}');
  }

  // `process.env.NODE_ENV === 'production'` must be `true` for production
  // builds to eliminate development checks and reduce build size. You may
  // wish to include additional optimizations.
  const isLocal = Boolean(env.dev || env.local);
  envVars.NODE_ENV = JSON.stringify(isLocal ? 'development' : 'production');

  // append process.env to envVars
  const envKeys = Object.keys(envVars).reduce((prev, next) => {
    prev[`process.env.${next}`] = JSON.stringify(envVars[next]);
    return prev;
  }, {});

  console.log('Running with environment keys:', envKeys);

  const extraPlugins = [
    new webpack.DefinePlugin({
      __DEV__: JSON.stringify(isLocal),
      ...envKeys
    }),
  ];

  const newConfig = {
    output: {
      filename: (env.prod || env.staging) ? '[name].[contenthash].js' : 'bundle.js',
    },

    module: {
      rules: [
        babelLoaderConfig,
        fileLoader
      ],
    },

    entry: ['./index.web.js'],

    // externals: {
    //     "react-native": true,
    // },

    plugins: [
      // new webpack.ProvidePlugin({
              // Promise: 'es6-promise', // Thanks Aaron (https://gist.github.com/Couto/b29676dd1ab8714a818f#gistcomment-1584602)
              // fetch: 'imports-loader?this=>global!exports-loader?global.fetch!whatwg-fetch'
          // }),
      new HtmlWebpackPlugin({
        // hash: env.prod,
        filename: 'm.html',
        template: 'index.html',
        inject: 'body'
      }),
    ],

    resolve: {
      alias: aliases,
      // If you're working on a multi-platform React Native app, web-specific
      // module implementations should be written in files using the extension
      // `.web.js`.
      extensions: ['.web.js', '.js'],
    },

    // devServer: {
      // historyApiFallback: true,
    // },
  };
  newConfig.plugins = [...newConfig.plugins, ...extraPlugins];
  return [newConfig];
}

module.exports = buildConfig;

这是我的 babel.config.json:

{
  "presets": ["module:metro-react-native-babel-preset"],
}

这是我的 package.json:

{
  "name": "SevMinHeb",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "ajv": "^6.4.0",
    "dotenv": "^6.0.0",
    "email-validator": "^2.0.4",
    "howler": "2.2.0",
    "immutability-helper": "3.1.1",
    "lodash": "^4.17.4",
    "migrat-postgres": "^0.1.1",
    "moment": "^2.22.2",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "0.63.2",
    "react-native-auth0": "2.6.0",
    "react-native-communications": "2.2.1",
    "react-native-easy-markdown": "2.0.0",
    "react-native-gesture-handler": "1.7.0",
    "react-native-linear-gradient": "2.5.6",
    "react-native-sound": "0.11.0",
    "react-native-web": "0.13.9",
    "react-native-web-linear-gradient": "1.1.1",
    "react-navigation": "4.4.0",
    "uuid": "^3.2.1"
  },
  "devDependencies": {
    "@babel/cli": "7.10.5",
    "@babel/core": "7.11.4",
    "@babel/plugin-proposal-class-properties": "7.10.4",
    "@babel/plugin-transform-flow-strip-types": "7.10.4",
    "@babel/polyfill": "7.10.4",
    "@babel/preset-env": "7.11.0",
    "@babel/preset-flow": "7.10.4",
    "@babel/preset-react": "7.10.4",
    "aws-sdk": "2.734.0",
    "babel-jest": "22.4.3",
    "babel-loader": "8.1.0",
    "babel-plugin-module-resolver": "4.0.0",
    "babel-plugin-react-native-web": "0.13.9",
    "babel-plugin-transform-decorators-legacy": "6.24.1",
    "babel-plugin-transform-decorators-legacy": "1.3.5",
    "babel-plugin-transform-remove-console": "6.9.4",
    "eslint-config-rallycoding": "^3.2.0",
    "file-loader": "6.0.0",
    "html-webpack-plugin": "4.3.0",
    "jest": "22.4.3",
    "metro-react-native-babel-preset": "0.63.0",
    "sinon": "7.1.1",
    "stripe": "7.9.1",
    "webpack": "4.44.1",
    "webpack-cli": "3.3.12",
    "webpack-dev-server": "3.11.0"
  },
  "jest": {
    "preset": "react-native"
  },
  "rnpm": {
    "assets": [
      "./app/assets/fonts/"
    ]
  }
}

标签: webpackbabeljs

解决方案


推荐阅读