Require.js中的路徑在IDEA中的最佳實踐

Cheney.Zhong.ZCY發表於2020-09-11

本文主要講述require.js在IDEA中路徑智慧感知的辦法和探索中遇到的問題。

 測試使用的目錄結構:一種典型的thinkphp 6的目錄結構,如下圖。

 現在我通過在 vue-a.js 中運用不同的方式引用 ../td/data.js 檔案。其中,data.js 的內容如下:

Require.js中的路徑在IDEA中的最佳實踐
define([],
    function () {
        let idx = 0;

        console.log('data.js')

        return 'data' + (++idx);
    });
data.js的內容

方法1:使用相對路徑

優點:

  1. 不用配置 require.config

缺點:

  1. 呼叫不同的模組的js時,路徑文字長
  2. 在不同模組間呼叫時極易發生相對位置錯誤

 方法2:使用require.config配置paths

require.config({
    paths: {
        'data': '../../../../public/static/admin/td/data',
    },
})

再在vue-a.js中使用paths中定義的短名進行引用。

Require.js中的路徑在IDEA中的最佳實踐
define(['data'],
    function (data1, data2) {
        let vueTemplate = {
            data: function () {
                let data = {
                    str: data1 + data2
                };
                return data;
            },
            template: `<div>{{str}}</div>`
        };
        return vueTemplate;
    });
vue-a.js

優點:

  1. 名字短

缺點:

  1. 需要配置require.config
  2. 在輸入時無法智慧感知,如上圖。
  3. 無法很友好的識別匯出的物件,參見:https://www.cnblogs.com/zhongchengyi/p/12982228.html

方法3:使用絕對路徑

使用絕對路徑時需要注意,必須使用require.config配置根目錄地址的別名(程式碼如下), 否則在執行時會找不到檔案(如下圖中的路徑,最終require可能會去找檔案:src/public/static/admin/src/public/static/admin/td/data.js)。

require.config({
    paths: {
        'src': '../../../..',
    },
})

 

優點:

  1. 不用糾結當前的路徑在哪裡。
  2. 配置相對少(只配置了根目錄)
  3. 輸入時完美智慧感知

缺點:

  1. 需要配置require.config
  2. 路徑文字長

 

特別注意:同一個檔案不能混用引用方式

混用絕對路徑和短名

此種混用絕對不能用,會導致嚴重後果。程式碼如下:

Require.js中的路徑在IDEA中的最佳實踐
define(['src/public/static/admin/td/data', 'data'],
    function (data1, data2) {
        let vueTemplate = {
            data: function () {
                let data = {
                    str: data1 + data2
                };
                return data;
            },
            template: `<div>{{str}}</div>`
        };
        return vueTemplate;
    });
vue-a.js

後果:

  1. 介面無法正常顯示
  2. require.js的程式碼報異常,無法進入 require後的程式碼。
  3. 無法載入短名代表的檔案,一直卡住,直到超時(超時時間是 require.config中配置的waitSeconds)

 

混用相對路徑和絕對路徑、混用相對路徑和短名

程式碼如下:

Require.js中的路徑在IDEA中的最佳實踐
define(['../td/data', 'data'],
    function (data1, data2) {
        let vueTemplate = {
            data: function () {
                let data = {
                    str: data1 + data2
                };
                return data;
            },
            template: `<div>{{str}}</div>`
        };
        return vueTemplate;
    });
相對路徑和短名
Require.js中的路徑在IDEA中的最佳實踐
define(['src/public/static/admin/td/data', '../td/data'],
    function (data1, data2) {
        let vueTemplate = {
            data: function () {
                let data = {
                    str: data1 + data2
                };
                return data;
            },
            template: `<div>{{str}}</div>`
        };
        return vueTemplate;
    });
絕對路徑和相對路徑

 

 這兩種混用方式都不會導致網頁卡住,但是,會導致被引用的檔案被呼叫兩次。如圖,控制檯輸出了兩次 'data.js'。

呼叫兩次有時會導致意想不到的問題。比如有些 js 會有事件註冊的邏輯,被呼叫兩次後,會導致事件被註冊兩次。後期會非常難定位。

 

我的最佳實踐

  1. 模組內部的相互引用,可以直接用相對路徑
  2. 模組間的引用,使用絕對路徑
  3. 外部模組(三方庫)使用短名
  4. 模組間儘量保持層級一致

 

PS:檢查require的檔案是否被呼叫兩次

在 require.config 中配置 onNodeCreated 回撥。

require.config({
    paths: {},
    shim: {},
    onNodeCreated: function (node, config, moduleName, url) {
        if (!this.nodes) {
            this.nodes = {};
        }
        if (!this.nodes[node.src]) {
            this.nodes[node.src] = {node, moduleName, url};
        } else {
            console.warn('重複的模組,如下:');
            console.log(this.nodes[node.src]);
            console.log({node, moduleName, url});
        }
    },
});

 

效果,在控制檯中輸出重複的模組的資訊。

 

相關文章