Javascript 带有小初始脚本和异步加载所有其他脚本的网页包
我在开发由多个页面和不同页面类型组成的常用网站时开始使用Webpack。我习惯了RequireJs脚本加载器,它在需要时根据需要加载所有依赖项。页面加载时只下载一小段javascript 我想要实现的是:Javascript 带有小初始脚本和异步加载所有其他脚本的网页包,javascript,jquery,asynchronous,webpack,Javascript,Jquery,Asynchronous,Webpack,我在开发由多个页面和不同页面类型组成的常用网站时开始使用Webpack。我习惯了RequireJs脚本加载器,它在需要时根据需要加载所有依赖项。页面加载时只下载一小段javascript 我想要实现的是: 加载异步依赖项的小型初始javascript文件 每种页面类型都可以有自己的javascript,也可能有依赖项 通用模块、供应商脚本应捆绑在通用脚本中 我尝试了许多配置来实现这一点,但没有成功 条目:{ main:'main.js',//用于所有页面,例如移动菜单 “标准页面”:“页面
- 加载异步依赖项的小型初始javascript文件
- 每种页面类型都可以有自己的javascript,也可能有依赖项
- 通用模块、供应商脚本应捆绑在通用脚本中
条目:{
main:'main.js',//用于所有页面,例如移动菜单
“标准页面”:“页面/标准页面.js”,
“起始页”:“pages/start page.js”,
'供应商':['jquery']
},
别名:{
jquery:'jquery/dist/jquery.js'
},
插件:[
新的webpack.optimize.commonChunkPlugin(“vendor”,“vendor.js”),
新建webpack.optimize.commonChunkPlugin('common.js'))
]
此问题的解决方案有两个方面:
commonchunkplugin
的东西来生成共享包require。确保
是在应用程序中创建“分割点”的一种方法。同样,您可能认为需要对配置执行此操作,但事实并非如此。在示例中,当我点击require时,请确保我的文件网页中的将自动创建第二个捆绑包并按需加载。在该分割点内执行的任何代码都将捆绑在一个单独的文件中
require.ensure(['jquery'], function() {
var $ = require('jquery');
/* ... */
});
要求([])
您还可以通过AMD版本的require()
实现同样的功能,该版本采用一系列依赖项。这也将创建相同的拆分点:
require(['jquery'], function($) {
/* ... */
});
共享束
在上面的示例中,您使用entry
创建一个包含jQuery的vendor
捆绑包。您不需要手动指定这些依赖项捆绑包。相反,使用网页上方的拆分点将自动生成此页面
仅将条目
用于页面中所需的单独的
标记
现在您已经完成了所有这些,您可以使用commonChunkPlugin
来进一步优化您的区块,但同样,大部分魔法都为您完成了,除了指定应该共享哪些依赖项之外,您不需要做任何其他事情webpack
将自动拉入共享块,而不需要额外的
标记或条目
配置
结论
您描述的场景(多个
标记)可能不是您真正想要的。使用webpack,所有依赖项和捆绑包都可以从一个
标记开始自动管理。在经历了从require.js到webpack的多次重新分解之后,我发现这通常是管理依赖关系的最简单和最好的方法
祝你一切顺利 这是我想出的解决办法
首先,将这两个函数导出到窗口。*
——您需要在浏览器中使用它们
export function requireAsync(module) {
return new Promise((resolve, reject) => require(`bundle!./pages/${module}`)(resolve));
}
export function runAsync(moduleName, data={}) {
return requireAsync(moduleName).then(module => {
if(module.__esModule) {
// if it's an es6 module, then the default function should be exported as module.default
if(_.isFunction(module.default)) {
return module.default(data);
}
} else if(_.isFunction(module)) {
// if it's not an es6 module, then the module itself should be the function
return module(data);
}
})
}
然后,当您希望在页面上包含一个脚本时,只需将其添加到HTML中:
<script>requireAsync('script_name.js')</script>
现在您可以访问它:
// script_that_needs_data.js
export default function({my,wow}) {
console.log(my,wow);
}
我最近也走过同样的路,我正在优化我的Webpack输出,因为我认为捆绑包太大了,HTTP2可以并行加载js文件,使用单独的文件缓存会更好,我在捆绑包中得到了一些重复的依赖项,等等。当我得到一个解决方案,使用Webpack 4 SplitChunksPlugin配置时,我目前主要使用Webpack的dynamic import()语法,因为正是这种语法将导致Webpack自动将动态导入的捆绑包捆绑到自己的文件中,我可以通过“神奇注释”命名这些文件:
不久前,我做了一个小小的“概念证明”,以检查importlazy在IE11中的工作情况。我必须承认它是有效的:)
单击按钮后,将加载负责更改页面背景颜色的代码-
Js:
Html:
更改背景
谢谢!使用您的方法时,我的问题是jquery包含在异步加载的所有依赖项包(a9114fd6e06bc77b48c9.js)中。我有require.sure(['jquery']在多个条目文件中。有没有办法只包含一个包含jquery的文件?这样我们就可以使用缓存不多次加载jquery了。当然可以。首先。我很困惑为什么要执行require.sure(['jquery'])
。你根本不需要这样做。普通块应该自动为你分解这些大东西,然后你可以使用
标记将它们加载到任何你想加载的地方。听起来像你想要这个示例所描述的:你的依赖应用程序js文件都将需要。确保(“[shared bundle]”)
按常用块吐出。这也可能有帮助:我..需要设置块文件名选项
// script_that_needs_data.js
export default function({my,wow}) {
console.log(my,wow);
}
import(/* webpackChunkName: "mymodule" */ "mymodule"); // I added an resolve.alias.mymodule entry in Webpack.config
// polyfils for IE11
import 'core-js/modules/es.array.iterator';
const button = document.getElementById('background');
button.addEventListener('click', async (event) => {
event.preventDefault();
try {
const background = await import(/* webpackChunkName: "background" */ `./${button.dataset.module}.js`);
background.default();
} catch (error) {
console.log(error);
}
})
<button id="background" class="button-primary" data-module="background">change the background</button>