![](/img/trans.png)
[英]build failed due to babelrc, presets[0] [1] must be an object, false or undefined
[英]Babel failed to compile: .presets[1][0] must be a string, object, function — how to fix?
我的項目基於 Create React App,但由於一些原因我不得不退出。 盡管如此,我還是盡力手動使其符合當前的 CRA 標准。 不過,我的最后一次更新並不順利。 嘗試運行“開始”命令時出現以下錯誤:
./apps/index.tsx
Error: [BABEL] ./apps/index.tsx: .presets[1][0] must be a string, object, function
at Array.forEach (<anonymous>)
at Array.forEach (<anonymous>)
我已經手動將一些日志添加到./node_modules/@babel/core/lib/config/validation/option-assertions.js,它給了我以下信息:
LOG "assertPluginItem ERROR inside IF block:"
LOG "Item access(loc, 0)"
{
type: 'access',
name: 0,
parent: {
type: 'access',
name: 1,
parent: { type: 'option', name: 'presets', parent: [Object] }
}
}
LOG "Item loc"
{
type: 'access',
name: 1,
parent: {
type: 'option',
name: 'presets',
parent: { type: 'root', source: 'preset' }
}
}
LOG "Item value"
[ undefined, { development: true, runtime: 'automatic' } ]
LOG "pluginLoc"
{
type: 'option',
name: 'presets',
parent: { type: 'root', source: 'preset' }
}
LOG "pluginValue"
[
[ [Function], { useBuiltIns: 'entry', corejs: 3, exclude: [Array] } ],
[ undefined, { development: true, runtime: 'automatic' } ],
[ [Function] ]
]
顯然,問題在於[ undefined, { development: true, runtime: 'automatic' } ]
中的這個“未定義”,但基於傳遞給這個失敗插件的選項,代碼不在我的設置文件中,而是在某個內部通天塔。
我嘗試將日志添加到 Babel 核心內的各種文件中,但沒有成功,而且我不知道哪個插件失敗以及為什么失敗。 你有什么想法可以幫助我嗎?
這是我的 webpack.config.js 的樣子:
const path = require('path');
const webpack = require('webpack');
const PnpWebpackPlugin = require('pnp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const getTheme = require('../theme');
const paths = require('../paths');
const getClientEnvironment = require('../env/getClientEnvironment');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const postcssNormalize = require('postcss-normalize');
const appPackageJson = require(paths.appPackageJson);
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const webpackDevClientEntry = require.resolve('react-dev-utils/webpackHotDevClient');
const reactRefreshOverlayEntry = require.resolve('react-dev-utils/refreshOverlayInterop');
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const cssRegex = /\.css$/;
const hasJsxRuntime = (() => {
if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
return false;
}
try {
require.resolve('react/jsx-runtime');
return true;
}
catch (e) {
return false;
}
})();
module.exports = function getConfig(appName, webpackEnv = 'development', isHotModuleReloadEnabled = true) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
const isEnvProductionProfile =
isEnvProduction && process.argv.includes('--profile');
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
const shouldUseReactRefresh = env.raw.FAST_REFRESH;
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
options: paths.publicUrlOrPath.startsWith('.')
? { publicPath: '../../' }
: {},
},
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
postcssNormalize(),
],
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
},
},
].filter(Boolean);
if (preProcessor) {
loaders.push(
{
loader: require.resolve('resolve-url-loader'),
options: {
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
root: paths.appSrc,
},
},
{
loader: require.resolve(preProcessor),
options: {
sourceMap: true,
globalVars: getTheme(appName),
},
},
);
}
return loaders;
};
const alias = {
...paths.alias,
app: paths.getAppPath(appName),
};
return {
stats: 'verbose',
name: appName,
mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
bail: isEnvProduction,
devtool: isEnvProduction
? shouldUseSourceMap
? 'source-map'
: false
: isEnvDevelopment && 'cheap-module-source-map',
entry:
isEnvDevelopment && !shouldUseReactRefresh
? [
webpackDevClientEntry,
paths.appStyles,
paths.appIndexJs,
]
: [
paths.appStyles,
paths.appIndexJs,
],
output: {
path: isEnvProduction ? paths.appBuild(appName) : undefined,
pathinfo: isEnvDevelopment,
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
futureEmitAssets: true,
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
publicPath: paths.publicUrlOrPath,
devtoolModuleFilenameTemplate: isEnvProduction
? (info) =>
path
.relative(paths.appsPath, info.absoluteResourcePath)
.replace(/\\/g, '/')
: isEnvDevelopment &&
((info) => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
jsonpFunction: `webpackJsonp${appPackageJson.name}`,
globalObject: 'this',
},
optimization: {
minimize: isEnvProduction,
minimizer: [
new TerserPlugin({
terserOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
},
mangle: {
safari10: true,
},
keep_classnames: isEnvProductionProfile, // eslint-disable-line camelcase
keep_fnames: isEnvProductionProfile, // eslint-disable-line camelcase
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
},
sourceMap: shouldUseSourceMap,
}),
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
parser: safePostCssParser,
map: shouldUseSourceMap
? {
inline: false,
annotation: true,
}
: false,
},
cssProcessorPluginOptions: {
preset: ['default', { minifyFontValues: { removeQuotes: false } }],
},
}),
],
splitChunks: {
cacheGroups: {
app: {
test: /[\\/]apps[\\/]/,
name: 'app',
chunks: 'all',
},
shared: {
test: /[\\/]shared[\\/]/,
name: 'shared',
chunks: 'all',
},
libs: {
test: /[\\/]libs[\\/]/,
name: 'libs',
chunks: 'all',
},
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
runtimeChunk: {
name: (entrypoint) => `runtime-${entrypoint.name}`,
},
},
resolve: {
modules: [
'node_modules',
paths.nodeModules,
paths.sharedSrc,
paths.libSrc,
].concat(
process.env.NODE_PATH.split(path.delimiter).filter(Boolean),
),
extensions: ['.tsx', '.ts', '.js'],
alias,
plugins: [
PnpWebpackPlugin,
],
},
resolveLoader: {
plugins: [
PnpWebpackPlugin.moduleLoader(module),
],
},
module: {
strictExportPresence: true,
rules: [
{ parser: { requireEnsure: false } },
{
oneOf: [
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: [
paths.appsPath,
paths.sharedSrc,
paths.libSrc,
],
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides',
),
presets: [
[
require.resolve('babel-preset-react-app'),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
plugins: [
['add-module-exports'],
['@babel/plugin-transform-modules-commonjs'], // only until no more module.exports = *
['module-resolver', { extensions: ['.js', '.ts', '.tsx'], alias }],
[require.resolve('babel-plugin-named-asset-import'), {
loaderMap: {
svg: {
ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]',
},
},
}],
isEnvDevelopment && shouldUseReactRefresh && require.resolve('react-refresh/babel'),
].filter(Boolean),
cacheDirectory: true,
cacheCompression: false,
compact: isEnvProduction,
},
},
{
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
cacheCompression: false,
sourceMaps: shouldUseSourceMap,
inputSourceMap: shouldUseSourceMap,
},
},
{
test: cssRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
}),
sideEffects: true,
},
{
test: /\.(less)$/,
use: [
isEnvDevelopment && require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 0,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
},
},
{
loader: 'less-loader',
options: {
logLevel: 2,
relativeUrls: true,
globalVars: getTheme(appName),
env: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
},
},
require.resolve('import-glob-loader'),
].filter(Boolean),
sideEffects: true,
},
{
loader: require.resolve('file-loader'),
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined,
),
),
isEnvProduction &&
shouldInlineRuntimeChunk &&
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime~.+[.]js/]),
new InterpolateHtmlPlugin(
HtmlWebpackPlugin,
Object.assign({ FAVICON: `favicon-${appName}.ico?v3` }, env.raw),
),
new ModuleNotFoundPlugin(paths.rootDirectory, paths.yarnLockFile),
new webpack.DefinePlugin(env.stringified),
isEnvDevelopment && isHotModuleReloadEnabled && new webpack.HotModuleReplacementPlugin(),
isEnvDevelopment &&
shouldUseReactRefresh &&
new ReactRefreshWebpackPlugin({
overlay: {
entry: webpackDevClientEntry,
module: reactRefreshOverlayEntry,
sockIntegration: false,
},
}),
isEnvDevelopment && new CaseSensitivePathsPlugin(),
isEnvDevelopment &&
new WatchMissingNodeModulesPlugin(paths.nodeModules),
isEnvProduction &&
new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
new ManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: paths.publicUrlOrPath,
generate: (seed, files, entrypoints) => {
const manifestFiles = files.reduce((manifest, file) => {
manifest[file.name] = file.path; // eslint-disable-line immutable/no-mutation
return manifest;
}, seed);
const entrypointFiles = entrypoints.main.filter(
(fileName) => !fileName.endsWith('.map'),
);
return {
files: manifestFiles,
entrypoints: entrypointFiles,
};
},
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
].filter(Boolean),
node: {
module: 'empty',
dgram: 'empty',
dns: 'mock',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
performance: false,
};
};
感謝 Logan Smyth,我能夠解決這個問題。 如果其他人在這里遇到類似的問題,會發生以下情況:
在上面的 webpack 配置中,在 babel-loader 的模塊規則中,我有babel-plugin-add-module-exports可以與我使用的舊依賴項實現一些互操作性。 升級所有依賴項后,此模塊與內聯require require("@babel/preset-env").default
而default
屬性被add-module-exports刪除,導致它評估為undefined
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.