本文相關代碼已經存放在 dynamic-entry,可自行下載使用html
webpack 的優點不言而喻,所以在實際應用中咱們也經常使用它調試 多入口 應用,所謂 多入口 是指多個HTML頁面會使用多個入口文件,在官方教程 MULTIPLE ENTRY POINTS 介紹瞭如何配置:node
{ entry: { a: "./a", b: "./b", c: ["./c", "./d"] }, output: { path: path.join(__dirname, "dist"), filename: "[name].entry.js" } }
這裏指定了 3 個入口文件,打包以後分別會在 dist 文件夾中生成 3 個打包以後的 js 文件:a.entry.js、b.entry.js、c.entry.js,可被至少 3 個不一樣的 HTML 頁面直接引用;webpack
上述是最基本的使用,實際中還可使用 multiple-commons-chunks 等提升打包的速度、性能;git
像上面那樣直接應用 Webpack 的多入口功能,在普通的工程項目中並不存在什麼問題,還簡單高效;github
然而若是你使用 Webpack 構建較大型的頁面系統,遂着業務的擴大,入口的數量會逐漸增多,縱使每一個入口文件都很小,在調試的時候等全部的入口文件都 ready 所耗費的時間也是很是巨大的,讓用戶等待過久顯然很不友好;web
用戶等待時間隨着模塊數量而線性增長(見下圖):express
假設業務模塊有100個,而當前本身僅僅須要調試 A 模塊,若是使用默認的多模塊入口方式,用戶 必須等這100個模塊啓動以後才能調試 A 模塊,很明顯這會讓用戶抓狂;npm
比較合理的作法是,不管當前用戶模塊目錄下有多少個模塊,默認都只其構建一個模塊,當用戶想要調試另一個模塊的時候,再動態添加一個 entry 到 webpack 系統中,這就減小了用戶等待的時間,提升了調試時的用戶體驗;微信
目前業界並無現成的動態 entry 方案,須要本身分析 webpack 源碼找到解決方案;(若是不清楚 webpack 流程的,能夠參考 @七珏 同窗的 細說webpack之流程篇)app
2.一、先分析 webpack 源碼中處理單入口的 entry 狀況,在 WebpackOptionsApply.js
有:
context
和 entry
做爲參數傳入2.二、 繼續看 EntryOptionPlugin.js 文件,在 entry-option 事件節點中調用 SingleEntryPlugin
構造函數構建單入口模塊:
咱們能夠依樣畫葫蘆,利用官方的 SingleEntryPlugin
的對象來完成動態添加入口的功能。
webpack(config)
獲取 compiler 實例;compiler.apply(new SingleEntryPlugin(process.cwd(),...);
新增一個構建入口本節的代碼放在倉庫 dynamic-entry 中,能夠到下載獲取
這裏咱們以 express 框架爲例,講解如何實現動態 entry ;具體操做步驟以下:
git clone https://github.com/boycgit/dynamic-entry
cd dynamic-entry && npm install && node server.js
http://localhost:3000/add
,再去看命令行,你會發現如今會構建 src/index1.js 和 src/index2.js 這兩個文件,這就是所謂的動態 entry
簡要分析一下源碼,在 server.js 中:
... var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); var webpackDevMiddleware = require('webpack-dev-middleware'); ... var webpackDevMiddlewareInstance = webpackDevMiddleware(compiler, webpackDevMiddlewareParam); app.use(webpackDevMiddlewareInstance); // 應用針對 express 框架的 webpack 調試中間件 ... var once = true; // 新增入口 app.get('/add', function(req, res) { // 應用單入口插件 console.log('apply SingleEntryPlugin'); compiler.apply(new SingleEntryPlugin(process.cwd(), './src/index2.js','index2')); once && webpackDevMiddlewareInstance.invalidate(); // 強制從新構建一次,不用調用屢次,後續的觸發由webpack本身 hot reload once = false; // 置 once 就是 false res.send('already apply SingleEntryPlugin'); });
/add
路由,當用戶訪問此頁面的時候會調用 compiler.apply
新增一個構建入口 webpackDevMiddlewareInstance.invalidate()
強制 webpack 從新構建一次,這個方法只須要調用1次(所以這兒由 once
變量進行控制),後續的觸發由webpack本身 hot reload從上面的過程可見,動態 entry 實施的過程是借鑑 webpack 自身的 SingleEntryPlugin 插件進行的,在可靠性方面有很大的保障;其他的代碼則是借用現有的 express 中間件獲取所須要的 compiler
等對象協助此過程;
目前動態 entry 以後已經運用在若干個內部構建器中,在應用動態 entry 以後,明顯地改善了用戶體驗;
此篇文章但願能給有相似場景的同窗提供幫助;
下面的是個人公衆號二維碼圖片,歡迎關注。