升级TypeScript(3→4)与Storybook(5→6)后出现Babel配置错误
升级TypeScript和Storybook后Babel构建错误解决方案
问题背景
将TypeScript从3.9.6升级至4.4.4、Storybook从5.3.19升级至6.5.10后,构建过程中出现Babel配置冲突错误,提示类相关插件的loose模式不一致。
错误日志
ERROR in ./.storybook/preview.js-generated-config-entry.js Module build failed (from ../node_modules/@storybook/builder-webpack4/node_modules/babel-loader/lib/index.js): Error: /Users/liran.harary/dev/mmservices/site/site-pages-ui/.storybook/preview.js-generated-config-entry.js: 'loose' mode configuration must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled). at enableFeature (/Users/liran.harary/dev/mmservices/site/node_modules/@babel/helper-create-class-features-plugin/lib/features.js:51:13) at PluginPass.pre (/Users/liran.harary/dev/mmservices/site/node_modules/@babel/helper-create-class-features-plugin/lib/index.js:82:35) at transformFile (/Users/liran.harary/dev/mmservices/site/node_modules/@storybook/builder-webpack4/node_modules/@babel/core/lib/transformation/index.js:97:27) at transformFile.next (<anonymous>) at run (/Users/liran.harary/dev/mmservices/site/node_modules/@storybook/builder-webpack4/node_modules/@babel/core/lib/transformation/index.js:35:12) at run.next (<anonymous>) at transform (/Users/liran.harary/dev/mmservices/site/node_modules/@storybook/builder-webpack4/node_modules/@babel/core/lib/transform.js:29:41) at transform.next (<anonymous>) at step (/Users/liran.harary/dev/mmservices/site/node_modules/@storybook/builder-webpack4/node_modules/gensync/index.js:261:32) at /Users/liran.harary/dev/mmservices/site/node_modules/@storybook/builder-webpack4/node_modules/gensync/index.js:273:13) at async.call.result.err.err (/Users/liran.harary/dev/mmservices/site/node_modules/@storybook/builder-webpack4/node_modules/gensync/index.js:223:11) @ multi ../node_modules/@storybook/core-server/node_modules/@storybook/core-client/dist/esm/globals/polyfills.js ../node_modules/@storybook/core-server/node_modules/@storybook/core-client/dist/esm/globals/globals.js ../node_modules/@storybook/builder-webpack4/node_modules/webpack-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./storybook-init-framework-entry.js ../node_modules/@storybook/react/dist/esm/client/preview/config-generated-config-entry.js ./.storybook/preview.js-generated-config-entry.js ./generated-stories-entry.js main[5]
已尝试操作
- 手动升级所有Storybook包,自动升级脚本
npx storybook upgrade无效; - 在tsconfig.json的
compilerOptions中添加skipLibCheck: true; - 创建Storybook 6所需的
.storybook/main.js文件; - 在babel.config.js的
@babel/preset-env中添加loose: true和shippedProposals: true,未解决问题。
项目配置
依赖配置(package.json)
{"dependencies": {"@babel/polyfill": "^7.10.1","aphrodite": "^2.2.3","axios": "^0.19.0","body-parser": "^1.18.3","consent-string": "^1.4.1","current-device": "^0.10.0","iframe-resizer": "^4.3.2","intersection-observer": "^0.7.0","luxon": "^1.22.0","mm-client-core": "1.0.0","mm-theme-configuration": "1.0.0","mm-ui-components": "1.0.0","react": "^16.13.1","react-dom": "^16.13.1","react-helmet": "^6.1.0","react-redux": "^7.1.1","redux": "^4.0.0","redux-thunk": "^2.3.0","traffic-source-analyzer": "1.0.0","web-vitals": "^2.1.4"},"devDependencies": {"@babel/core": "^7.10.2","@babel/plugin-proposal-class-properties": "^7.10.1","@babel/plugin-proposal-optional-chaining": "^7.16.7","@babel/preset-env": "^7.10.2","@babel/preset-react": "^7.10.1","@babel/preset-typescript": "^7.10.1","@storybook/addon-actions": "^5.3.19","@storybook/addon-info": "^5.3.21","@storybook/addon-knobs": "^6.4.0","@storybook/addon-links": "^6.5.10","@storybook/addon-viewport": "^6.5.10","@storybook/addons": "^6.5.10","@storybook/react": "^6.5.10","@types/iframe-resizer": "^3.5.8","@types/luxon": "^1.21.0","@types/nock": "^11.1.0","@types/react-redux": "^7.1.0","@types/storybook__addon-info": "^5.2.4","@typescript-eslint/eslint-plugin": "^2.10.0","@typescript-eslint/parser": "^2.10.0","babel-eslint": "^10.1.0","babel-loader": "^8.1.0","copy-webpack-plugin": "^5.0.5","core-js": "^3.4.7","enzyme": "^3.7.0","enzyme-adapter-react-16": "^1.6.0","eslint": "^6.7.2","eslint-config-mm": "git+https://github.com/FTBpro/eslint-config-mm.git#v3.1","eslint-loader": "3.0.2","jest": "^24.0.0","jest-junit": "^10.0.0","mm-pilot-mock": "1.0.0","nock": "^11.7.0","npm-run-all": "^4.1.3","terser-webpack-plugin": "^2.2.1","typescript": "4.4.4","webpack": "^4.29.6","webpack-cli": "^3.3.10","webpack-dev-server": "^3.1.4","webpack-merge": "^4.1.3","webpack-node-externals": "^1.7.2"}}
Babel配置(babel.config.js)
module.exports = function (api) { api.cache(true); const presets = [ ['@babel/preset-env', { modules: false, targets: { browsers: ['last 2 versions'], }, // Added these to try to solve the error. Didn't help loose: true, shippedProposals: true, }, ], '@babel/preset-react', '@babel/preset-typescript', ]; const env = { test: { presets: [ ['@babel/preset-env'], '@babel/preset-react', '@babel/preset-typescript'], }, }; const plugins = [ '@babel/plugin-syntax-dynamic-import', '@babel/plugin-syntax-import-meta', '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-json-strings', '@babel/plugin-proposal-optional-chaining', ]; return { presets, env, plugins, }; };
Storybook配置(.storybook/main.js)
module.exports = { addons: [], babel: async (options) => ({ // Update your babel configuration here ...options, }), framework: '@storybook/react', stories: ['../src/**/*.stories.@(js|mdx)'], webpackFinal: async (config, { configType }) => { // Make whatever fine-grained changes you need // Return the altered config return config; }, };
解决方案
1. 统一类相关Babel插件的loose模式
错误根源是Storybook自动引入了@babel/plugin-proposal-private-methods和@babel/plugin-proposal-private-property-in-object,但项目配置中仅启用了@babel/plugin-proposal-class-properties,三者的loose模式未统一。
修改babel.config.js中的plugins数组,显式添加两个缺失的插件并统一设置loose: true:
const plugins = [ '@babel/plugin-syntax-dynamic-import', '@babel/plugin-syntax-import-meta', ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-proposal-private-methods', { loose: true }], ['@babel/plugin-proposal-private-property-in-object', { loose: true }], '@babel/plugin-proposal-json-strings', '@babel/plugin-proposal-optional-chaining', ];
同时移除@babel/preset-env中的loose: true,避免全局配置和插件单独配置冲突。
2. 升级Babel依赖到兼容版本
项目中@babel/core及相关插件版本为7.10.x,而@babel/plugin-proposal-optional-chaining已升级到7.16.7,版本不匹配可能导致配置冲突。执行以下命令升级所有Babel核心依赖:
npm install @babel/core@^7.16.0 @babel/preset-env@^7.16.0 @babel/preset-react@^7.16.0 @babel/preset-typescript@^7.16.0 @babel/plugin-proposal-class-properties@^7.16.0 --save-dev
升级后,Babel的类特性插件会自动协调loose模式,无需手动逐个配置。
3. 强制Storybook使用项目Babel配置
在.storybook/main.js中覆盖默认Babel配置,确保Storybook使用和项目一致的规则:
module.exports = { addons: [], babel: async (options) => ({ ...options, presets: [ ['@babel/preset-env', { modules: false, targets: { browsers: ['last 2 versions'] }, shippedProposals: true, }], '@babel/preset-react', '@babel/preset-typescript', ], plugins: [ '@babel/plugin-syntax-dynamic-import', '@babel/plugin-syntax-import-meta', ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-proposal-private-methods', { loose: true }], ['@babel/plugin-proposal-private-property-in-object', { loose: true }], '@babel/plugin-proposal-json-strings', '@babel/plugin-proposal-optional-chaining', ], }), framework: '@storybook/react', stories: ['../src/**/*.stories.@(js|mdx)'], webpackFinal: async (config, { configType }) => config, };
4. 清理依赖缓存
执行以下命令清理旧依赖和缓存,重新安装避免版本残留:
rm -rf node_modules package-lock.json npm install
内容的提问来源于stack exchange,提问作者Liran H
相关产品推荐
相关产品推荐

