动态

详情 返回 返回

element-ui部分引入失效問題追蹤 - 动态 详情

背景

項目使用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這個函數作為切入點;
image
發現Vue.component對於同一個組件(如ElTooltip)調用了2次;
image
看到全量引入的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還未初始化,效果如圖
image

還是需要一個vue.config.js,我這裏建立一個空的vue.config.js來配置transpileDependencies參數

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

babel-plugin-component 報錯

這次打包babel-plugin-component終於生效了,但是卻引起如下報錯。
image

查看了下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"
            }
        }
    ]
}

效果如圖
image

user avatar pudongping 头像
点赞 1 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.