背景
我的项目应用vue2
与element-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起了个别名e
,babel-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" } } ]}
成果如图