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