本文相关代码已经存放在 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 以后,明显地改善了用户体验;
此篇文章但愿能给有相似场景的同窗提供帮助;
下面的是个人公众号二维码图片,欢迎关注。