关于babel:elementui部分引入失效问题追踪

7次阅读

共计 3485 个字符,预计需要花费 9 分钟才能阅读完成。

背景

我的项目应用 vue2element-ui;最近发现我的项目的局部引入生效了

// babel.config.js
module.exports = api => {
    return {"presets": ['@vue/cli-plugin-babel/preset'],
        "plugins": [
          [
            "component",
            {
              "libraryName": "element-ui",
              "styleLibraryName": "theme-chalk"
            }
          ]
        ]
      };
};

babel-plugin-component 负责将 element-ui 的引入代码转换为局部引入代码;

全量的 element-ui 是被谁引入的

这里咱们应用 Vue.component 这个函数作为切入点;

发现 Vue.component 对于同一个组件(如 ElTooltip)调用了 2 次;

看到全量引入的 element-ui 来自于 node_modules 中的包;
查看了下 logic-tree 这个包的代码

// 打包前源码
import {Button} from 'element-ui';

// 打包后
var _ks_kwai_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! element-ui */ \"../../node_modules/element-ui/lib/element-ui.common.js\");

能够看出包自身代码没有问题,是咱们在打包时 babel-plugin-component 没能在包文件上失效,导致 import 语句被 webpack 翻译为应用了 main 下的 index.js

为什么 babel-plugin-component 没能失效?

能够看出 babel-loader 没有去编译 node_modules 下的文件。
很好了解,如果所有 node_modules 代码都要编译,会大大增加打包与热更新工夫;
babel-plugin-component 源码中退出 log,发现的确没有调用

        ImportDeclaration: function ImportDeclaration(path, _ref2) {
          var opts = _ref2.opts;
          var node = path.node;
          var value = node.source.value;
          var result = {};

          if (Array.isArray(opts)) {result = opts.find(function (option) {return option.libraryName === value;}) || {};}

          console.log('hy', value);
          ...

通过文档浏览后,发现参数 transpileDependencies 能够管制 node_modules 哪些包须要通过 babel

默认状况下 babel-loader 会疏忽所有 node_modules 中的文件。你能够启用本选项,以防止构建后的代码中呈现未转译的第三方依赖

transpileDependencies 生效

咱们的我的项目采纳 pluginAPI 来配置 vue.config,因而在 plugin 中退出如下代码(现状)

module.exports = api => {
    api.service.projectOptions.transpileDependencies = ['logic-tree'];
    api.service.projectOptions.productionSourceMap = false;
    ...
}

然而加上后发现没有失效;通过调试与源码搜寻发现 transpileDependencies 的应用方为 @vue/cli-plugin-babel,也是一个 plugin,而且他的调用程序先于咱们的 plugin,此时transpileDependencies 还未初始化,成果如图

还是须要一个 vue.config.js,我这里建设一个空的 vue.config.js 来配置 transpileDependencies 参数

// vue.config.js
module.exports = {
    transpileDependencies: ['logic-tree'],
};

babel-plugin-component 报错

这次打包 babel-plugin-component 终于失效了,然而却引起如下报错。

查看了下 logic-tree/dist/index.es.js 源码

import{Button as t,Tooltip as e}from"element-ui";var r=Object.freeze(Object.defineProperty({__proto__:null,get default(){return No}},Symbol.toStringTag,{value:"Module"})),n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:...

发现这个包的 es 版本代码,将 Tootip 起了个别名 ebabel-plugin-component 没有兼容别名。

解决办法:将 babel-plugin-component 替换为 babel-plugin-import;

至此,问题解决,完。

附录 1 对于调试

留神:调试之前须要先革除 node_modules/.cache,否则 plugin 代码不会调用

追究问题过程中波及对 vue-cli-service 整个打包过程的调试,之前的调试计划个别借助 npx --node-options='--inspect-brk',联合chrome://inspect 页面进行调试,例如

PROJECT_PATH=/root-project/custom-widgets/customization-table npx --node-options='--inspect-brk' /root-project/tools/kwaibi-cli/node_modules/.bin/vue-cli-service build --target lib --name kwaibi-custom-widget-plugin/customization-table@0.9.82 --dest /root-project/custom-widgets/customization-table/dist /root-project/custom-widgets/customization-table/src/main.ts

然而 node 端常常会 fork child-process,这时候咱们只调试主过程是没有意义的,还须要找到子过程fork 的中央手动加上 inspect 参数能力对子过程进行调试

vscode参数 autoAttachChildProcesses 帮忙咱们节俭了这些工作。
进入 vscode 调试性能,配置 launch.json 如下

{
    "configurations": [
        {
            "type": "node-terminal",
            "name": "kwaibi-cli node",
            "request": "launch",
            "command": "PROJECT_PATH=/root-project/custom-widgets/customization-table /root-project/tools/kwaibi-cli/node_modules/.bin/vue-cli-service build --target lib --name kwaibi-custom-widget-plugin/customization-table@0.9.82 --dest /root-project/custom-widgets/customization-table/dist /root-project/custom-widgets/customization-table/src/main.ts",
            "autoAttachChildProcesses": true,
            "cwd": "${workspaceFolder}/tools/kwaibi-cli",
            "env": {"PROJECT_PATH": "${workspaceFolder}/custom-widgets/customization-table"
            }
        }
    ]
}

成果如图

正文完
 0