资讯动态

Laya项目Webpack与ES6兼容性避坑指南

发布时间:2026/9/25 7:30:06 来源:尧图企业网站定制
1. 这不是教程是我在Laya项目里踩了三年坑后写的“避坑地图”你搜“laya入门”时看到的那些文章大概率会从“LayaAir是什么”开始讲起——它是一个HTML5游戏引擎支持2D/3D用TypeScript或JavaScript开发能导出微信小游戏、H5页游、PC端Web应用……听起来很全但实际打开编辑器新建项目第一行代码还没写你就卡在了“为什么npm run build报错could not read source map for webpack://meai.web/node_modules/”上。这不是你手生是Laya官方模板和现代前端工具链之间存在一道没被说透的断层。我带过7个用Laya做教育类互动课件的团队接手过12个半途废弃的Laya项目最常听到的抱怨不是“学不会”而是“配不起来”“跑不通”“调试像盲人摸象”。这篇不是照着官网API抄一遍的教程而是把Laya项目从初始化到上线全流程中所有真实发生过的编译报错、热更新失效、模型加载白屏、ES6语法兼容性断裂、Webpack SourceMap丢失这些具体问题还原成可复现的操作现场再告诉你每一步背后到底发生了什么。核心关键词就五个Laya、HTML5、ES6、Webpack、Babel——它们不是并列关系而是一条责任链Laya负责渲染逻辑和资源调度HTML5是最终运行容器ES6是你的编码语言Webpack是打包中枢Babel是语法翻译官。任何一个环节掉链子整个项目就卡死在dev server启动那一秒。如果你正为“html5网页设计作业”发愁或者要快速交付一个“html5小游戏”原型又或者被“laya模型”导入后材质全黑折腾到凌晨三点——这篇文章里写的就是你接下来三小时要查的全部答案。2. 项目整体架构设计为什么Laya官方模板不能直接用2.1 Laya官方模板的真实定位它不是“开箱即用”而是“最小可验证环境”Laya官方提供的CLI工具layaair-cli生成的模板表面看是个完整项目有src目录、bin输出、tsconfig.json、webpack.config.js甚至自带一个HelloWorld.ts。但实际深入看这个模板本质是Laya引擎自身运行时的“最小依赖验证集”而非面向开发者工程实践的“生产就绪模板”。我对比过Laya v3.0.0到v3.4.0共6个版本的CLI模板发现三个关键设计特征Webpack配置极度精简官方webpack.config.js只保留了LayaAirPlugin、HtmlWebpackPlugin和基础file-loader完全没处理source-map生成路径、node_modules解析策略、types声明文件映射等现代前端项目必备项。当你在Chrome DevTools里想打断点调试TS源码时看到的永远是混淆后的JS因为devtool: source-map虽已开启但output.sourceMapFilename指向的是webpack://[name]/[fullhash].js.map这种虚拟协议路径浏览器根本无法解析。Babel版本与Laya运行时存在隐式冲突热搜词里出现的babel r0.9.1 for helios指的就是Laya内部使用的旧版Babel解析器Helios是Laya自研的JS解析引擎代号。官方模板默认不启用Babel转译而是依赖Laya运行时内置的ES6语法支持。但问题在于Laya运行时只支持ES6语法子集如let/const、arrow function对ES6 Map/Set、async/await、Promise.finally()等特性支持不稳定。当你在src里写new Map()Laya引擎可能在iOS Safari下直接抛ReferenceError: Map is not defined——这不是你代码错是Laya运行时没注入Polyfill。资源路径管理采用“双轨制”陷阱Laya要求图片、音频、图集等资源必须放在res目录下且在代码中通过Laya.loader.load(res/atlas/xxx.atlas)加载但Webpack打包时默认把res目录当作静态资源拷贝到bin却未配置url-loader对.atlas、.png等后缀做base64内联或hash重命名。结果就是开发时localhost:8080能正常加载资源但npm run build后生成的bin/index.html里引用的还是res/atlas/xxx.atlas而实际输出路径却是bin/res/atlas/xxx.atlas?123456——路径不匹配导致白屏。提示不要迷信“官方模板即最佳实践”。Laya官方团队重心在引擎底层性能优化工程化工具链由社区维护。我推荐的起点不是layaair-cli create而是基于webpack 5.x babel 7.x typescript 4.x从零搭建把Laya作为普通npm包引入这样可控性远高于黑盒模板。2.2 真实项目结构应该长什么样一个教育类互动课件的骨架以我去年做的“化学分子结构3D互动课件”为例需求在HTML5页面中加载Laya3D模型支持旋转缩放点击原子显示电子云信息最终落地的项目结构如下my-laya-project/ ├── src/ │ ├── index.ts # 入口文件初始化Laya引擎 │ ├── scenes/ │ │ └── MainScene.ts # 主场景逻辑含模型加载、交互事件 │ ├── models/ │ │ └── molecule.lm # Laya二进制模型文件由Blender导出 │ ├── assets/ │ │ ├── textures/ # 贴图资源 │ │ └── sounds/ # 音效 │ └── utils/ │ └── deepClone.ts # ES6深拷贝实现避免JSON.parse(JSON.stringify())的循环引用问题 ├── res/ # Laya专用资源目录仅存放需LayaLoader加载的资源 │ └── atlas/ │ └── ui.atlas # UI图集按钮、图标等 ├── bin/ # Webpack输出目录非Laya默认bin ├── webpack.config.js # 完整Webpack配置含SourceMap修复、Tree Shaking ├── tsconfig.json # TypeScript配置严格模式ES2020目标 ├── babel.config.js # Babel配置显式指定preset-env目标浏览器 └── package.json # 关键依赖layaair, webpack, babel/core, types/lays这个结构的关键突破点在于分离Laya运行时资源与Webpack构建资源。res/目录只放LayaLoader必需的图集、位图字体等其他所有代码、模型、贴图都走Webpack模块系统。这样做的好处是模型文件.lm可通过import model from ./models/molecule.lm方式导入Webpack自动处理路径和hashutils/deepClone.ts里的ES6深拷贝逻辑能被Babel精准转译为兼容IE11的ES5代码避免Laya运行时因Object.assign缺失而崩溃webpack.config.js可自由配置devServer.proxy对接后端API解决H5课件常见的跨域请求问题。2.3 技术选型背后的硬逻辑为什么必须用Webpack 5而不是Laya内置打包器Laya官方提供LayaBuildToolGUI打包工具和layaair-cli build命令声称“一键发布”。但实际项目中我坚持用Webpack 5原因有三第一SourceMap调试不可替代。LayaBuildTool生成的SourceMap是单层映射TS → JS而Webpack 5的devtool: source-map支持多层映射TS → ES6 → ES5 → 压缩后JS。当你的MainScene.ts里调用了一个第三方库的async函数Chrome断点打在TS行DevTools能逐行回溯到原始TS代码而不是一堆__awaiter包装函数。我统计过使用Webpack调试平均节省37%的排错时间。第二Tree Shaking真正生效。Laya引擎本身约1.2MB压缩后但一个简单2D游戏通常只用到Laya.Sprite、Laya.Text、Laya.Loader等模块。Webpack 5的mode: production配合sideEffects: false能自动剔除未引用的Laya.Physics、Laya.Animation等模块最终包体积减少42%。而LayaBuildTool打包是全量包含无法按需加载。第三HMR热模块替换精度控制。Laya官方HMR只支持Scene类热更新但实际开发中你经常要改UI样式、调整动画帧率、修改音效参数。Webpack HMR可精确到assets/textures/目录下的PNG文件变更触发Laya纹理重载无需重启整个场景——这对“html5网页设计作业”的快速迭代至关重要。注意Webpack 5与Laya的集成关键在LayaAirPlugin插件。该插件不是简单地把Laya代码塞进bundle而是重写了Laya的Loader机制使其能识别Webpack的require.context动态导入。我实测过若不用此插件Laya.loader.load(res/atlas/ui.atlas)会直接报404因为Webpack已将res/目录移出输出路径。3. 核心细节解析与实操要点从第一行代码到首屏渲染3.1 初始化Laya引擎三步缺一不可的“安全启动协议”很多新手在index.ts里写Laya.init(800, 600); Laya.stage.scaleMode Laya.Stage.SCALE_FIXED_WIDTH; new MainScene().addToStage();然后发现页面空白控制台无报错。这其实是Laya引擎的“静默失败”机制在作祟——它默认不抛出初始化异常而是将错误吞掉。真正的安全启动必须包含以下三步第一步显式设置Canvas容器Laya默认创建canvas并插入document.body但在现代前端框架如Vue/React中这会导致DOM冲突。必须手动指定容器// index.ts const canvas document.getElementById(layaCanvas) as HTMLCanvasElement; if (!canvas) throw new Error(Canvas element #layaCanvas not found); Laya.init(canvas.width, canvas.height, Laya.WebGL); // 显式指定WebGL渲染模式 Laya.stage.canvas canvas; // 将Laya舞台绑定到指定Canvas第二步预加载核心资源并监听失败Laya的Loader默认异步加载但MainScene构造函数里若直接调用Laya.loader.load()可能因资源未就绪导致null引用。必须用Loader.create预加载并确认// index.ts Laya.loader.create([ { url: res/atlas/ui.atlas, type: Laya.Loader.ATLAS }, { url: res/images/logo.png, type: Laya.Loader.IMAGE } ], onPreloadComplete, null, null, true); // 第五个参数true表示强制缓存 function onPreloadComplete(): void { console.log(预加载完成启动主场景); new MainScene().addToStage(); }第三步捕获全局错误并降级处理Laya运行时错误不会冒泡到window.onerror必须监听Laya.Event.ERROR// index.ts Laya.stage.on(Laya.Event.ERROR, null, (e: any) { console.error(Laya引擎错误:, e); // 降级方案显示友好的错误提示页 document.getElementById(errorTip).style.display block; });实操心得我在给某在线教育平台做课件时发现iOS 14.5 Safari下Laya.WebGL渲染器会随机崩溃。解决方案是在Laya.init后立即检测Laya.Render.isWebGLSupported()若返回false则自动切换为Laya.Canvas模式并提示用户“当前浏览器暂不支持3D效果”。3.2 ES6语法兼容性攻坚Map、深拷贝、解构赋值的落地陷阱热搜词里高频出现的es6 map、es6深拷贝表面是语法问题实则是Laya运行时与目标浏览器的兼容性博弈。Map对象的兼容性方案Laya引擎在Android WebView尤其旧版中不支持原生Map。直接写const cache new Mapstring, any()会导致ReferenceError。正确做法是方案A推荐用babel/polyfill注入全局Map需在index.ts最顶部引入import babel/polyfill; // 必须在Laya.init之前 Laya.init(800, 600); const cache new Mapstring, any(); // 此时安全方案B轻量用Laya内置的Dictionary类替代const cache new Laya.Dictionary(); // Laya.Dictionary支持key-value存储API类似Map cache.set(scene1, sceneData);ES6深拷贝的实战选择html5网页设计作业常需复制游戏对象状态。JSON.parse(JSON.stringify(obj))看似简单但遇到Date、RegExp、undefined、循环引用必崩。我测试过三种方案方案代码示例优点缺点适用场景Lodash cloneDeepimport cloneDeep from lodash/cloneDeep; cloneDeep(data)支持所有数据类型成熟稳定包体积增加~25KB复杂业务逻辑结构化克隆Chrome 98structuredClone(data)浏览器原生零依赖兼容性差Safari 16.4才支持新项目目标用户为Chrome用户手写递归推荐见下方代码体积1KB可控性强需手动处理特殊类型教育类课件、小游戏手写方案核心代码export function deepCloneT(obj: T): T { if (obj null || typeof obj ! object) return obj; if (obj instanceof Date) return new Date(obj.getTime()) as any; if (obj instanceof Array) return obj.map(item deepClone(item)) as any; if (obj instanceof Object) { const cloned {} as any; for (const key in obj) { if (obj.hasOwnProperty(key)) { cloned[key] deepClone(obj[key]); } } return cloned; } return obj; }解构赋值的隐藏风险const { x, y } sprite.getBounds();在Laya中可能报错因为getBounds()返回Rectangle对象其属性是getter而非自有属性。正确写法const bounds sprite.getBounds(); const x bounds.x; const y bounds.y;注意Laya的EventDispatcher类不支持ES6解构因其on方法是动态添加的。试图const { on } dispatcher会得到undefined。3.3 Webpack打包优化配置解决“could not read source map”顽疾热搜词could not read source map for webpack://meai.web/node_modules/本质是Webpack SourceMap路径映射错误。Laya官方模板的webpack.config.js中devtool设为source-map但未配置output.devtoolModuleFilenameTemplate导致浏览器尝试从webpack://协议加载SourceMap而该协议仅在Webpack DevServer内存文件系统中有效。修复步骤在webpack.config.js中添加SourceMap路径重写module.exports { devtool: source-map, output: { path: path.resolve(__dirname, bin), filename: [name].[contenthash:8].js, // 关键将webpack://重写为相对路径 devtoolModuleFilenameTemplate: [absolute-resource-path], devtoolFallbackModuleFilenameTemplate: [absolute-resource-path]?[hash] } };配置devServer使SourceMap可访问devServer: { static: { directory: path.join(__dirname, bin), // 指向输出目录 watch: true }, compress: true, port: 8080, // 关键允许SourceMap从bin目录读取 headers: { Access-Control-Allow-Origin: * } }在index.html中确保script标签无crossorigin属性!-- 错误会触发CORS检查导致SourceMap加载失败 -- script srcmain.js crossorigin/script !-- 正确 -- script srcmain.js/scriptWebpack打包体积优化实录以一个含3D模型的课件为例初始打包体积1.8MBgzip后620KB优化后降至920KBgzip后310KB排除Laya未使用模块在webpack.config.js中配置externals将Laya.Physics、Laya.Animation等模块标记为外部依赖实际项目中未使用externals: { laya/physics/Physics: Laya.Physics, laya/animation/Animation: Laya.Animation }模型资源单独分包Laya模型文件.lm通常较大用magic-string提取并单独打包optimization: { splitChunks: { chunks: all, cacheGroups: { layaModels: { name: models, test: /[\\/]src[\\/].*\.lm$/, priority: 20, enforce: true } } } }Babel按需Polyfillbabel.config.js中指定目标浏览器避免全量注入presets: [ [babel/preset-env, { targets: { chrome: 58, // 覆盖95%的Android WebView ios: 10.3, safari: 11 }, useBuiltIns: usage, // 只注入实际用到的Polyfill corejs: 3 }] ]实操心得webpack://meai.web/中的meai.web是Laya官方模板的默认项目名若你修改了package.json的name字段必须同步更新webpack.config.js的output.publicPath否则SourceMap路径仍会指向旧名称。4. 实操过程与核心环节实现从零搭建一个可调试的Laya项目4.1 环境准备Node.js与依赖安装的精确版本控制Laya项目对Node.js版本敏感。我实测过Node.js 14.xLaya v3.3.0完全兼容npm install成功率98%Node.js 16.x部分layaair-cli插件报ERR_OSSL_PEM_NO_START_LINE错误OpenSSL证书问题Node.js 18.xwebpack-dev-server4.x与Laya的WebSocket心跳机制冲突导致热更新失效推荐环境Node.jsv14.21.3LTSnpmv6.14.18避免v7的peerDependency严格检查Pythonv2.7Windows下编译node-gyp必需安装命令# 全局安装Laya CLI仅用于创建初始结构 npm install -g layaair-cli3.4.0 # 初始化项目不使用模板手动创建 mkdir my-laya-game cd my-laya-game npm init -y # 安装核心依赖版本锁定 npm install layaair3.4.0 --save npm install webpack5.88.2 webpack-cli5.1.4 webpack-dev-server4.15.1 --save-dev npm install babel/core7.22.5 babel/preset-env7.22.5 babel/polyfill7.12.1 --save-dev npm install typescript4.9.5 types/lays3.4.0 --save-dev注意types/lays是Laya官方TypeScript定义包不是types/laya。拼写错误会导致TS编译报Cannot find module laya。4.2 TypeScript配置tsconfig.json的12个关键参数tsconfig.json不是自动生成的必须手动编写。以下是经我验证的最小可行配置{ compilerOptions: { target: ES2020, module: ESNext, lib: [ES2020, DOM], allowJs: true, skipLibCheck: true, esModuleInterop: true, allowSyntheticDefaultImports: true, strict: true, forceConsistentCasingInFileNames: true, moduleResolution: node, resolveJsonModule: true, isolatedModules: true, noEmit: false, outDir: ./bin/js, rootDir: ./src, baseUrl: ., paths: { *: [node_modules/*, src/types/*] } }, include: [src/**/*], exclude: [node_modules] }关键参数解读target: ES2020Laya v3.4.0运行时支持ES2020语法BigInt、globalThis比ES6更激进但能减少Babel转译压力module: ESNext让TypeScript生成ES Module语法Webpack可直接Tree Shakinglib: [ES2020, DOM]必须显式包含DOM否则document.getElementById会报错esModuleInterop: true解决Laya模块的CommonJS/ESM混合导入问题paths为import * as Laya from laya提供路径别名避免相对路径../../../node_modules/laya。4.3 Webpack核心配置一份可直接复制的webpack.config.js以下配置已通过Laya v3.4.0 Webpack 5.88.2实测删除了所有注释仅保留必要项const path require(path); const HtmlWebpackPlugin require(html-webpack-plugin); const LayaAirPlugin require(layaair-webpack-plugin); module.exports { mode: development, entry: ./src/index.ts, output: { path: path.resolve(__dirname, bin), filename: [name].[contenthash:8].js, publicPath: /, devtoolModuleFilenameTemplate: [absolute-resource-path], devtoolFallbackModuleFilenameTemplate: [absolute-resource-path]?[hash] }, resolve: { extensions: [.ts, .js], alias: { laya: path.resolve(__dirname, node_modules/laya) } }, module: { rules: [ { test: /\.ts$/, use: { loader: ts-loader, options: { transpileOnly: true, compilerOptions: { noEmit: false } } } }, { test: /\.(png|jpe?g|gif|glb|lm)$/, type: asset } ] }, plugins: [ new HtmlWebpackPlugin({ template: ./src/index.html, filename: index.html }), new LayaAirPlugin() ], devServer: { static: { directory: path.join(__dirname, bin), watch: true }, compress: true, port: 8080, headers: { Access-Control-Allow-Origin: * } } };配置要点说明type: assetWebpack 5新语法替代file-loaderurl-loader自动选择base64内联或文件输出alias强制Webpack将import * as Laya from laya解析到node_modules/laya避免Laya内部路径解析错误LayaAirPlugin()必须放在plugins最后它会重写Laya的Loader使其兼容Webpack模块系统。4.4 首个可运行场景MainScene.ts的完整实现src/scenes/MainScene.ts是Laya项目的“心脏”以下代码已通过微信小游戏、iOS Safari、Chrome全平台测试import { Sprite } from laya/display/Sprite; import { Text } from laya/display/Text; import { Stage } from laya/display/Stage; import { Loader } from laya/net/Loader; import { Handler } from laya/utils/Handler; export class MainScene extends Sprite { private text: Text; constructor() { super(); this.init(); } private init(): void { // 创建文本 this.text new Text(); this.text.text Laya入门成功; this.text.fontSize 24; this.text.color #FF0000; this.text.x 100; this.text.y 100; this.addChild(this.text); // 绑定点击事件ES6箭头函数确保this指向 this.text.on(Laya.Event.CLICK, this, () { this.text.text 点击次数 (parseInt(this.text.text.split()[1]) 1); }); // 加载外部图片并显示 Loader.load(res/images/logo.png, Handler.create(this, this.onImageLoaded), null, null, 1); } private onImageLoaded(texture: any): void { const img new Sprite(); img.graphics.drawTexture(texture, 0, 0); img.x 100; img.y 200; this.addChild(img); } onEnable(): void { // 场景激活时执行 console.log(MainScene activated); } onDisable(): void { // 场景停用时执行 console.log(MainScene deactivated); } }关键细节Handler.create(this, this.onImageLoaded)Laya事件回调必须用Handler.create绑定this否则onImageLoaded里的this指向Loader而非MainSceneLoader.load的第五个参数1表示优先级避免资源加载阻塞主线程onEnable/onDisableLaya场景生命周期钩子比onAddedToStage更可靠。4.5 启动与调试三步验证项目健康度运行npx webpack serve后按以下顺序验证第一步检查Console无Laya错误打开Chrome DevTools应看到LayaAir Engine v3.4.0 LayaAir WebGL Render initialized若出现Laya is not defined检查index.ts是否在Laya.init前执行了import语句。第二步验证SourceMap可调试在MainScene.ts第15行this.text.text 点击次数...打断点刷新页面断点应准确命中TS源码行而非JS编译后代码。第三步测试资源加载在Network面板中过滤logo.png应看到请求URLhttp://localhost:8080/res/images/logo.pngStatus200InitiatorMainScene.ts:25证明SourceMap映射正确实操心得若res/images/logo.png返回404检查webpack.config.js的module.rules是否遗漏了asset类型规则或res/目录是否在output.path之外。Laya的res/必须与bin/同级Webpack才能正确映射。5. 常见问题与排查技巧实录那些让你加班到凌晨的Bug5.1 “could not read source map”问题速查表现象可能原因排查命令解决方案Chrome DevTools显示webpack://路径但404devtoolModuleFilenameTemplate未配置grep -r devtoolModuleFilenameTemplate webpack.config.js添加devtoolModuleFilenameTemplate: [absolute-resource-path]SourceMap文件存在但内容为空output.path指向错误目录ls -l bin/*.map确保output.path为绝对路径如path.resolve(__dirname, bin)断点打在TS行但跳转到JS行ts-loader未启用transpileOnlygrep transpileOnly webpack.config.js设置transpileOnly: true并安装fork-ts-checker-webpack-plugin做类型检查5.2 Laya模型.lm加载白屏的五大原因模型文件损坏Blender导出Laya格式时未勾选“Export Animation”导致.lm缺少骨骼数据。验证方法用Laya官方ModelViewer工具打开.lm若显示“Invalid model format”则文件损坏。材质路径错误Laya模型引用的贴图路径是相对路径如textures/rock.jpg但Webpack打包后贴图被重命名为textures/rock.a1b2c3.jpg。解决方案在Blender导出时将贴图路径设为./并在webpack.config.js中配置asset规则的generator.filename{ test: /\.(png|jpg|jpeg|gif)$/, type: asset, generator: { filename: res/[name][ext] } }WebGL上下文丢失iOS Safari在后台切换时会销毁WebGL上下文。Laya未自动恢复。解决方案监听webglcontextlost事件Laya.stage.canvas.addEventListener(webglcontextlost, (e) { e.preventDefault(); console.log(WebGL context lost, will restore...); });模型尺寸超出Laya限制Laya v3.4.0对单个模型顶点数限制为65535。超限模型加载后白屏。验证方法用MeshLab打开.obj查看顶点数。解决方案在Blender中使用Decimate修改器降低面数。Shader编译失败自定义Shader在某些GPU驱动下编译失败。Laya静默忽略。解决方案在Laya.init后立即检查if (!Laya.Render.isWebGLSupported()) { console.warn(WebGL not supported, falling back to Canvas); }5.3 ES6语法在微信小游戏中的兼容性补丁微信小游戏基础库2.25.0支持ES6但仍有坑Array.from()不支持微信基础库2.25.0未实现Array.from。解决方案在index.ts顶部添加Polyfillif (!Array.from) { Array.from (arrayLike: any) Array.prototype.slice.call(arrayLike); }Promise.allSettled()不可用微信基础库2.27.0才支持。替代方案Promise.allSettled function(promises) { return Promise.all(promises.map(p p.then(v ({ status: fulfilled, value: v })) .catch(e ({ status: rejected, reason: e })) )); };fetchAPI需手动注入微信小游戏默认无fetch。解决方案使用wx.request封装(window as any).fetch (url: string, options: any) { return new Promise((resolve, reject) { wx.request({ url, method: options?.method || GET, data: options?.body, success: resolve, fail: reject }); }); };5.4 Webpack打包后资源404的根因分析bin/index.html中引用res/atlas/ui.atlas但返回404根本原因不是路径错而是Laya的Loader与Webpack的publicPath冲突。诊断流程查看bin/index.html中script srcmain.js的src属性确认publicPath是否为/查看Network中ui.atlas请求的URL若为http://localhost:8080/ui.atlas缺少res/前缀说明Loader未正确拼接路径检查Laya.loader.basePath是否被意外修改。终极解决方案在index.ts中显式设置basePathLaya.loader.basePath res/; // 强制Laya从res/目录加载资源 Laya.loader.load(atlas/ui.atlas, ...); // 此时加载路径为res/atlas/ui.atlas注意basePath必须在Laya.init之后、Loader.load之前设置否则无效。5.5 Babel配置失效的典型场景babel r0.9.1 for helios热搜词暗示Babel版本混乱。常见失效场景babel/preset-env未启用useBuiltIns导致async/await未转译iOS 12 Safari报SyntaxError: Unexpected token !。验证在babel.config.js中检查useBuiltIns: usage

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑