• home > tools > Bundler > webpack >

    升级到babel7踩坑回顾:主要解决lerna monorepo打包报错问题

    Author:zhoulujun Date:

    babel6升级到babel7,使用lerna作为monorepo管理工具。发现vue3项目jsx无法编译。需要把每个子包的package json改为xx json。通个这个问题在细看一遍babel

    Babel简介

    babel 最开始叫 6to5,顾名思义,功能是 es6 转 es5。我们知道,es 版本一年一个,有了 es7(es2016)、es8(es2017)等等。显然,6to5 的名字已经不合适了,所以 6to5 改名为了 babel。

    babel 来自巴别塔的典故:

    当时人类联合起来兴建希望能通往天堂的高塔,为了阻止人类的计划,上帝让人类说不同的语言,使人类相互之间不能沟通,计划因此失败,人类自此各散东西。此事件,为世上出现不同语言和种族提供解释。这座塔就是巴别塔。

    这个巴别塔的典故很符合 babel 的转译器的定位。

    babel 的编译流程

    babel 从最初到现在一直的目的都很明确,就是把源码中的新语法和 api 转成目标浏览器支持的。它采用了微内核的架构,整个流程比较精简,所有的转换功能都是通过插件来完成的。

    2.webp

    babel 的编译流程就是 parse、transform、generate 3步, parse 是把源码转成 AST,transform 是对 AST 的转换,generate 是把 AST 转成目标代码,并且生成 sourcemap。

    在 transform 阶段,会应用各种内置的插件来完成 AST 的转换。内置插件做的转换包括两部分,一是把不支持的语法转成目标环境支持的语法来实现相同功能,二是不支持的 api 自动引入对应的 polyfill。

    具体可以参看下 《插件化架构设计(2):插件化从设计到实践该考量的问题汇总

    babel 的编译流程和目的从没有变过,但是完成这个目的的方式却变化很大,babel 6,babel 7 变化还挺大的,未来babel 8 又会怎么做不得而知。

    具体推荐阅读


    babel7的重大改动

    • babel 7 改动挺大的,比如所有的包都迁移到了 @babel 的 scope 下,也就是 @babel/xxx

    • babel 7 废弃了 preset-20xx 和 preset-stage-x 的 preset 包,而换成了 preset-env,preset-env 默认会支持所有 es 标准的特性,如果没进入标准的,不再封装成 preset,需要手动指定 plugin-proposal-xxx。

    • babel 7 开始, .babelrc 的作用范围仅限于当前项目,默认不再作用与 node_modules 和工作区 (./packages/*),如果需要,可以指定作用范围

    • babel7新增了babel.config.js型的配置,对比.babelrc。.babelrc是从每一个文件向上查找配置的,babel.config.js则不会。

    其他的不提,.babelrc 的作用范围仅限于当前项目,如果项目中使用lerna,项目就跑不起来。比如:

    Support for the experimental syntax 'jsx' isn't currently enabled (45:5): #11700
    
    
    plugins/datasource/jsonapi/components/ConfigPanel.tsx: Support for the experimental syntax 'jsx' isn't currently enabled (48:17):
      46 |     }
      47 |     render() {
    > 48 |         return (<div class={'config-panel'}>
         |                 ^
      49 |         <Form formType="vertical" class="source-form" ref="sourceForm" model={this.formData}>
      50 |           <div class={'config-box'}>
      51 |             <p class={'step-title'}>基础信息</p>
    
    Add @babel/preset-react (https://github.com/babel/babel/tree/main/packages/babel-preset-react) to the 'presets' section of your Babel config to enable transformation.
    If you want to leave it as-is, add @babel/plugin-syntax-jsx (https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-jsx) to the 'plugins' section to enable parsing.
    
        at instantiate (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/parser/lib/index.js:653:32)
        at constructor (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/parser/lib/index.js:947:12)
        at Parser.raise (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/parser/lib/index.js:3261:19)
        at Parser.expectOnePlugin (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/parser/lib/index.js:3307:18)
        at Parser.parseExprAtom (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/parser/lib/index.js:11220:18)
        at Parser.parseExprSubscripts (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/parser/lib/index.js:10870:23)
        at Parser.parseUpdate (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/parser/lib/index.js:10853:21)

    这个不是jsx的问题,vite+vue3.0 jsx (tsx) 踩坑报错ReferenceError: React is not defined。因为已经加了vueJsx()

    // vite.config.ts
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import vueJsx from '@vitejs/plugin-vue-jsx' // 添加这一句
    
    // https://vitejs.dev/config/
    export default defineConfig({
     plugins: [
       vue(),
       vueJsx() // 添加这一句
     ]
    })

    webpack配置也加了babel,没有问题。只是把项目目录里面的package.json改为 **.json,就正常了

    升级Babel7所带来的问题

    Babel7使用 "scoped" packages 方式,加上了 @babel 标识便于区分官方 package 以及 非官方 package

    具体参看:https://babel.docschina.org/docs/en/7.0.0/config-files/

    我们先来看下babel配置文件的区别

    Babel配置文件

    .babelrc

    File-relative configuration

    • 与文件实际物理位置相关

    • 从编译文件向上查找文件系统获取.babelrc文件,找到package.json为止

    • 如果目录不在 babelrcRoots 配置中(默认配置为. 即根目录),.babelrc文件将被忽略

    进一步解析:

    • .babelrc文件不能跨多个package生效(即有package.json的目录),一般使用webpack配置js文件loader,我们会忽略node_modules目录,因为项目根目录的.babelrc文件通常不会对该目录下各个package生效,且如果node_modules目录下的package有自己的.babelrc文件,这个sub配置会生效,并可能因为插件依赖不完全而报错

    • 同理 .babelrc 文件也不能对 symlinked packages 生效

    .babelrc.js

    • js文件,配置同.babelrc

    • 可访问Node API

    babel.config.js

    Project-wide configuration
    Babel7.x新特性,项目全局配置
    默认使用当前工作目录下的babel.config.js文件,可配置configFile覆盖默认文件路径

    • 对当前工作目录下 node_modules 或 symlinked packages 均可生效

    • 当前工作目录下如果配置了.babelrc,其中配置将会覆盖或合并babel.config.js中的配置

    • 但是要注意,如果在工作目录下某个sub package中运行babel,将无法找到根目录的babel.config.js文件 (可以配置 "rootMode" 选项为 "upward",让Babel自动向上寻找)


    在项目 rootDir(项目根目录)创建 babel.config.js。

    但是还是会报错。


    Monorepo-structured repositories

    对于一个项目中存在多个package包的情况,Babel7提供了一种更方便进行babel配置管理、合并、特殊配置的方案

    • 根目录使用 babel.config.js 进行全局配置

    • Subpackage使用 .babelrc, 默认情况下 subpackage 目录下的 .babelrc文件不会生效

    package.json
    babel.config.js
    packages/
      mod/
        package.json
        .babelrc
        index.js

    当Babel编译packages/mod/index.js文件时,和它同一级目录的.babelrc文件不会被识别

    如果需要该.babelrc文件被识别加载,需要在根目录下的 babel.config.js 文件中使用配置项 "babelrcRoots"

    babelrcRoots: [
      ".",
      "packages/*",
    ],

    发现改完之后还是不行。


    @babel/plugin-transform-arrow-functions报错

    这个我目前找到了2个解决方案

    1、添加 @babel/plugin-transform-arrow-functions

    在@blueking/babel-preset-bk 插件里面修改

    1.jpg

    2、presets  targets配置修改。

    module.exports = {
      "presets": [
        [
          "@blueking/babel-preset-bk",
          {
            "targets": {
              "browsers": ["> 1%", "last 2 versions", "not ie <= 8"],
              "node": "current"
            }
          }
        ]
      ],
    }

    报错

    ERROR in ./node_modules/monaco-vue3-editor/node_modules/monaco-editor/esm/vs/editor/contrib/find/browser/findController.js
    Module build failed (from ./node_modules/thread-loader/dist/cjs.js):
    Thread Loader (Worker 1)
    /Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/monaco-vue3-editor/node_modules/monaco-editor/esm/vs/editor/contrib/find/browser/findController.js: When using '@babel/plugin-transform-arrow-functions', it's not possible to compile `super.prop` in an arrow function without compiling classes.
    Please add '@babel/plugin-transform-classes' to your Babel configuration.
      352 |     _start(opts, newState) {
      353 |         const _super = Object.create(null, {
    > 354 |             _start: { get: () => super._start }
          |                                  ^^^^^^^^^^^^
      355 |         });
      356 |         return __awaiter(this, void 0, void 0, function* () {
      357 |             if (!this._widget) {
    
        at File.buildCodeFrameError (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/core/lib/transformation/file/file.js:205:12)
        at NodePath.buildCodeFrameError (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/index.js:105:21)
        at hoistFunctionEnvironment (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/conversion.js:219:27)
        at NodePath.arrowFunctionToExpression (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/conversion.js:116:7)
        at PluginPass.ArrowFunctionExpression (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/plugin-transform-arrow-functions/lib/index.js:17:14)
        at newFn (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/visitors.js:149:21)
        at NodePath._call (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:45:20)
        at NodePath.call (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:35:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:80:31)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitSingle (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:65:19)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:109:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitMultiple (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:61:17)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:107:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitSingle (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:65:19)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:109:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitMultiple (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:61:17)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:107:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitMultiple (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:61:17)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:107:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitSingle (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:65:19)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:109:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitMultiple (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:61:17)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:107:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
        at TraversalContext.visitMultiple (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:61:17)
        at TraversalContext.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:107:19)
        at traverseNode (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/traverse-node.js:18:17)
        at NodePath.visit (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/path/context.js:86:52)
        at TraversalContext.visitQueue (/Users/andyzhou/www/bk-vision/vite-vue3-tsx/node_modules/@babel/traverse/lib/context.js:86:16)
     @ ./node_modules/monaco-vue3-editor/node_modules/monaco-editor/esm/vs/editor/editor.all.js 21:0-51
     @ ./node_modules/monaco-vue3-editor/node_modules/monaco-editor/esm/vs/editor/edcore.main.js 8:0-26
     @ ./node_modules/monaco-vue3-editor/node_modules/monaco-editor/esm/vs/editor/editor.main.js 13:14-38
     @ ./node_modules/monaco-vue3-editor/dist/index.js 26:82-106
     @ ./src/components/monaco/index.tsx 8:47-76
     @ ./src/pages/datasource/VariableEditor.tsx 27:37-67
     @ ./src/router/module/datasource.ts 100:15-99
     @ ./src/router/index.ts 18:41-71
     @ ./src/preview.ts 6:37-56


    参看文章:

    babel7配置备忘 https://www.jianshu.com/p/faad8917b8e9

    回顾 babel 6和7,来预测下 babel 8 https://juejin.cn/post/6956224866312060942



    转载本站文章《升级到babel7踩坑回顾:主要解决lerna monorepo打包报错问题》,
    请注明出处:https://www.zhoulujun.cn/html/tools/Bundler/webpack/2023_0302_8929.html