webpack - 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/"
]
}
}
解决方案
推荐阅读
- javascript - 为什么此 JS 代码中的光标不更新?
- c# - 使用 Unity 导入 System.Management.Automation
- node.js - 为什么反应管理员登录页面只显示一秒钟?
- delphi - 在 Delphi 错误缓冲区中调用函数 DLL
- swift - 在 Swift 中制作按钮三角形而不是矩形的框架
- visual-studio-code - 无法在笔记本中选择 Jupyter Python 内核
- javascript - 为什么子进程使用除 tcpdump 之外的不同命令行?
- javascript - 如何使用 Jquery 搜索带有 javascript 运算符符号的表单列?
- python - 表格不显示
- c++ - 正确的全局变量定义/声明