Javascript 正确加载多个Web包包包
tl;博士您应该如何加载多个webpack包,而不在代码中添加脚本标记Javascript 正确加载多个Web包包包,javascript,webpack,Javascript,Webpack,tl;博士您应该如何加载多个webpack包,而不在代码中添加脚本标记 我一直在研究使用WebPACK,但是在加载WebPACK捆绑包时,我似乎缺少了一块,到目前为止,我一直在使用Realjs,它允许您将代码拆分成模块(我认为WebPACK中相当于捆绑包)。但requirejs允许您在代码中按名称要求脚本,然后将脚本映射到配置中的url,但使用webpack,您只需在页面上添加一个脚本标记,这让人感觉它很容易失控,因为您的应用程序视图中到处都是脚本,这使得切换捆绑包变得更加困难,因为你需要更新一
我一直在研究使用WebPACK,但是在加载WebPACK捆绑包时,我似乎缺少了一块,到目前为止,我一直在使用Realjs,它允许您将代码拆分成模块(我认为WebPACK中相当于捆绑包)。但requirejs允许您在代码中按名称要求脚本,然后将脚本映射到配置中的url,但使用webpack,您只需在页面上添加一个脚本标记,这让人感觉它很容易失控,因为您的应用程序视图中到处都是脚本,这使得切换捆绑包变得更加困难,因为你需要更新一个url来查找和替换该url的每一个实例,而不是世界末日,但我似乎错过了一些使这变得更容易的功能,或者这是requirejs和webpack之间公认的区别
我应该提到的是,我正在考虑添加webpack的所有代码都不是单页应用程序,所以webpack可能不适合这种环境 为了给我想要包含的内容添加一点上下文,我们的服务器端代码使用了mvc模式,所以看起来像这样 页面骨架/布局
视图1
require(['something'],函数{/*news();*//*s();*//*etc*/});
视图2
require(['something','other_thing'],函数{/*news();*//*s();*//*etc*/});
最近,我在单页应用程序中使用了webpack的功能,根据路由动态加载捆绑包。这并不需要在整个应用程序中随意丢弃脚本标记。如果使用任何类型的路由机制,则可以在访问该路由时动态导入依赖项,如下所示:
// Index
router.on(() => {
import(/* webpackChunkName: "routeA" */ '../routes/routeA').then((module) => {
// do something with your loaded module
}).resolve();
});
这种“根”样式的模块,即webpack绑定的依赖关系树的根,意味着您只能在需要时获取它。这意味着当您执行此路由时,客户端将仅获取此bundle.js
使用动态导入需要在您的网页配置中添加chunkFilename
属性:
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
编辑:如果您使用的是express.js,您可以按照其路由机制执行相同的操作。您最好参考webpack提供的代码拆分文档(如上链接).我对路由器的方法并不完全满意,因为它实际上意味着必须在javascript中复制url重写配置,并复制页面共享代码的导入语句,我不确定,但这似乎意味着任何导入的脚本都将包含在最终包中,而不是在页面加载,这意味着包中有很多代码在大部分时间内未被使用 对我来说,似乎最好的方法是有效地创建一个更简单的requirejs版本来加载捆绑文件(下面的示例),这样我就可以保持与现有代码类似的结构。诚然,我可能仍然会寻找一个库,而不是滚动我自己的加载程序,但我还没有决定 装载机 加载程序配置 视图1
require(['something'],函数{/*news();*//*s();*//*etc*/});
window.loader.load('something');
因此,如果我理解正确,您将拥有包含在每个页面中的捆绑包以及所有路由,然后加载其他所需捆绑包?如果这是正确的,是webpack中内置的路由功能,还是其他库提供的路由功能?导入中的注释是否称为约定,或者它是否具有某种意义?我读过关于延迟加载的文章,但这似乎并没有解决这个问题。注释是一个特殊的注释,web包代码拆分使用它为绑定的块分配一个名称。如果为空,它将生成一个随机名称。您在应用程序中使用什么作为服务器?服务器端我们使用coldfusion(不幸的是:D)和coldbox(用于mvc功能),我在对主要问题的编辑中提供了一个大致的示例,说明它的外观。不幸的是,我对这两种框架都没有任何经验。但您必须有一些代码来定义为哪个url加载哪个视图?这本质上是一个路由,将URL映射到一个函数。在您的函数中,您可以动态导入该路由所需的模块,webpack将在浏览器中为您检索该模块。
<div>
<!-- ... -->
<!-- Currently it has this -->
<script>
require(['something', 'another_thing'], function(s){ /* new s(); */ /* s(); */ /* etc */ });
</script>
<!-- and i'd imagine it would be like this with webpack -->
<script src="my_bundle.js"></script>
<script src="my_bundle2.js"></script>
</div>
// Index
router.on(() => {
import(/* webpackChunkName: "routeA" */ '../routes/routeA').then((module) => {
// do something with your loaded module
}).resolve();
});
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
class Loader{
constructor(config){
this.config = config;
}
load(modName){
if(this.config.debug)console.log('loader - ', 'load called', arguments);
if(!document.getElementById(modName)){
if(this.config.debug)console.log('loader - ', 'loading new script', modName, this.config.map[modName]);
var script = document.createElement('script');
script.id = modName;
script.type = 'text/javascript';
script.src = this.config.map[modName];
script.async = true;
document.head.appendChild(script);
}
}
}
export default Loader;
window.loader = new Loader({
'debug': true,
'map': {
'something': '/scripts/bundle.js',
'another_thing': '/scripts/bundle2.js'
}
});
<div>
<!-- ... -->
<!-- Currently it has this -->
<script>
require(['something'], function(s){ /* new s(); */ /* s(); */ /* etc */ });
</script>
<!-- which would change to (any of the callback code would be inside the bundle) -->
<script>
window.loader.load('something');
</script>
</div>