經過webpack的require.context,去路由中心化管理

什麼是webpack的require.context?前端

官網解釋:react

您可使用require.context()函數建立本身的上下文。webpack

它容許您傳入一個目錄進行搜索,一個標誌表示是否也應該搜索子目錄,以及一個正則表達式來匹配文件。git

在構建時,webpack解析代碼中的require.context()。github


直接在項目中使用,個人webpack4+react的一個開源項目,很早以前寫的移動端項目,你們有興趣能夠看看,給個Starweb

gitHub地址:https://github.com/JinJieTan/react-webpack

而且這個項目仍是帶docker+gitHub+Travis CI的,教程在我以前寫的這裏:正則表達式

前端工程師學Docker ? 看這篇就夠了   【零基礎入門;原創】 docker

項目結構:express

+ src
  + APP.jsx
  + pages 
    + buy
      + index.jsx
    + home 
      + index.jsx 
    + person 
      + index.jsx 
    //...
  + index.js 
  //....

我在src文件夾下的APP.jsx中使用webpack的require.context API數組

require.context('./pages', true, /\.jsx$/)

require.context接受三個參數,官網解釋:

It allows you to pass in a directory to search,
 a flag indicating whether subdirectories should be searched too,
  and a regular expression to match files against.

意思是:

它容許你經過一個目錄進行搜索,flag指定是否搜索子目錄,以及與文件匹配的正則表達式

也就是說 require.context 有三個參數:

  • directory:說明須要檢索的目錄
  • useSubdirectories:是否檢索子目錄
  • regExp: 匹配文件的正則表達式

當我使用 

require.context('./pages', true, /\.jsx$/)

獲得的打印返回值是:

ƒ webpackContext(req) {
  var id = webpackContextResolve(req);
  return __webpack_require__(id);
} ,"測試"

官網解釋:

上下文模塊導出一個(require)函數,該函數接受一個參數:請求。
導出的函數有3個屬性:解析、鍵值、id。
resolve是一個函數,返回解析後的請求的模塊id。
keys是一個函數,它返回上下文模塊能夠處理的全部可能請求的數組。

我按照官網示例演示,加入新的代碼:

const cache = {};

function importAll (r) {
  r.keys().forEach(key => cache[key] = r(key));
}

importAll(require.context('./pages', true, /\.jsx$/));

console.log(cache,'cache')

我獲得一些模塊信息:

你們可能會聯想到路由結合的使用,放一個示例代碼,以前咱們在react中寫聲明式路由,集中化管理須要這樣:

// rootRoute.js
const rootRoute = {
    childRoutes: [
        {
            path: '/',
            component: AppLayout,
            childRoutes: [
                require('./modules/shop/route'), //購買詳情頁
                require('./modules/order/route'), // 訂單頁
                require('./modules/login/route'), // 登陸註冊頁
                require('./modules/service/route'), // 服務中心
                // ...
                // 其餘大量新增路由
                // ...
            ]
        }
    ]
};

如今咱們只須要這樣,就能夠實現去中心化路由管理

const rootRoute = {
    childRoutes: [
        {
            path: '/',
            component: AppLayout,
              childRoutes: (r => {
                  return r.keys().map(key => r(key));
            })(require.context('./', true, /^\.\/modules\/((?!\/)[\s\S])+\/route\.js$/))
        }
    ]
};

這裏childRoutes是一個IIFE,馬上能夠執行函數,傳入require.context的結果,r就是初始值

修改以前的代碼成這樣:

const childRoutes = ((r) => {
  console.log(r.keys(), 'keys');
  return r.keys().map((key) => {
      console.log(key,'key',r(key))
    return r(key);
  });
})(require.context('./pages', true, /\.jsx$/));

console.log(childRoutes, 'childRoutes');

看打印結果

這樣每一個childRoutes的子節點,就是個require進來的模塊啦

優化後,新增一個業務模塊,只要業務模塊 route 文件遵循統一的目錄結構。業務模塊 route 就能被自動關聯到 rootRoute 裏。

若是感受寫得不錯,記得點個贊,關注下:前端巔峯專欄和個人公衆號

image.png

相關文章
相關標籤/搜索