背景

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

// babel.config.jsmodule.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.jsmodule.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"            }        }    ]}

成果如图