webpack动态加载与打包方式

 更新时间:2023年02月09日 10:29:37   作者:s-alone  
webpack有两种组织模块依赖的方式,同步和异步,这篇文章主要介绍了webpack动态加载与打包方式,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下

webpack代码拆分

webpack有两种组织模块依赖的方式,同步和异步。异步依赖作为分割点,形成一个新的块,在优化了依赖树后,每一个异步区块都作为一个文件被打包。

上下文模块(contextModule)

上下文模块有6种类型,分别为sync/lazy/lazy-once/eager/weak/sync-weak

  • sync:直接打包当前文件,同步加载并执行
  • lazy:为每个import()导入的模块生成一个可延迟加载(lazy-loadable)的chunk
  • lazy-once:生成一个可满足所有import()调用的可延迟加载(lazy-loadable)的chunk
  • 此chunk将在第一次import()调用时获取,随后import()则使用相同的网络响应。注意,这种模式仅在动态语句中有意义。例如:import(./locales/${language}.json),其中可能含有多个被请求的模块路径。
  • eager:不会分离出单独的chunk文件,但是会返回promise,只有调用promise才会执行代码,可以理解为先加载了代码,但是我们可以控制延迟执行这部分代码。
  • 此模块会阻止webpack生成额外的chunk。所有导入的模块被包含在当前chunk,所以不需要再发额外的网络请求。它仍然返回一个promise,但会被自动resolved。使用eager模式的动态导入与静态导入的区别在于整个模块只有当import()调用之后才会执行

例子:当前vue文件为Home.vue,同级菜单有一个文件夹pages,它里面有三个文件a.vue, b.vue, c.vue

// 把Home, a, b, c分别打包到不同的chunk中
import('./pages/' + pageId)

// 把Home打成一个chunk,a/b/c统一打包到一个chunk
import(/* webpackMode: "lazy-once" */ './pages/' + pageId)

// 把Home, a, b, c打包到一个chunk中,且a/b/c中的代码只有在import之后执行(不在chunk加载时执行)
import(/* webpackMode: "eager" */ './pages/' + pageId)

注意:即使没有引用pages里面的某个文件,也会对其进行打包!

​ 通过上下文组件请求的实际路径是相对于指定目录的相对路径;在这里相对于‘/pages’上下文的路径,即’./a.vue’, ‘./b.vue’, ‘./c.vue’

生成contextModule的方式

require(表达式)

​ require(./locale/${language}.js) 会把匹配到的文件打包进去

require.context()函数

require.context(
  (directory: String),
  (includeSubdirs: Boolean) /* 可选的,默认值是 true */,
  (filter: RegExp) /* 可选的,默认值是 /^.\/.*$/,所有文件 */,
  (mode: String)  /* 可选的, 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once',默认值是 'sync' */

​ 一个 context module 会导出一个(require)函数,此函数可以接收一个参数:request。

​ 此导出函数有三个属性:resolve, keys, id。

  • resolve 是一个函数,它返回 request 被解析后得到的模块 id。
  • keys 也是一个函数,它返回一个数组,由所有可能被此 context module 处理的请求组成
  • id 是 context module 的模块 id. 它可能在你使用 module.hot.accept 时会用到

例子:

​ 与当前文件index.js同级目录modules有 aaa/index.js和bbb/index.js两个文件

const modulesFiles = require.context('./modules', true, /index.js$/)
console.log('modulesFiles:', modulesFiles)
// ƒ webpackContext(req) {
//     var id = webpackContextResolve(req);
//     return __webpack_require__(id);
// }
console.log('modulesFiles.keys:', modulesFiles.keys()) // ['./aaa/index.js', './bbb/index.js']

console.log('modulesFiles.resove:', modulesFiles.resolve('./bbb/index.js')) // ./src/store/modules/bbb/index.js

console.log('modulesFiles.id:', modulesFiles.id) // ./src/store/modules sync recursive index.js$

export const modules = modulesFiles.keys().reduce((res, modulePath) => {
  const pathName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const moduleName = pathName.replace('/index', '')
  const module = modulesFiles(modulePath)
  const dModuleName = module.default.name || ''
  console.log('modulePath:', modulePath)
  console.log('moduleName:', moduleName)
  console.log('module:', module)
  res[dModuleName || moduleName] = module.default
  console.log('res:', res)
  return res
}, {})

import()函数

import(
/* webpackInclude: /\.json$/ */
/* webpackExclude: /\.noimport\.json$/ */
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */ /* 'eager' | 'weak' | 'lazy' | 'lazy-once',默认值是 'lazy' */
/* webpackPrefetch: true */
/* webpackPreload: true */
/* webpackIgnore: false */ /* 将 webpackIgnore 设置为 true 则不进行代码分割 */
`./locale/${language}`
)

require.ensure()函数

require.ensure()已被import()代替

含有环境变量的动态加载

代码运行时通过判断环境变量(例如process.env.NODE_ENV===‘production’),只会打包满足判断条件逻辑分支的请求!!!;

export function getBaseUrl () {
  if (process.env.NODE_ENV === 'production') {
    require('@/prod.host.js')
    return '/performance/'
  } else {
    const requireHostFiles = require.context('@/api', false, /devHost.js$/)
    return requireHostFiles.keys().includes('./devHost.js') ? requireHostFiles('./devHost.js').devHost : require('@/dev.host.js').devHost
  }
}

如果process.env.NODE_ENV === ‘production’,只会打包 ‘@/prod.host.js’

否则会打包 ‘@/api’下的直属下属文件中满足 /devHost.js$/ 正则的文件, 以及 ‘@/dev.host.js’

到此这篇关于webpack动态加载与打包方式的文章就介绍到这了,更多相关webpack动态加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • DEFER怎么用?

    DEFER怎么用?

    DEFER怎么用?...
    2006-07-07
  • 用JavaScript来美化HTML的select标签的下拉列表效果

    用JavaScript来美化HTML的select标签的下拉列表效果

    这篇文章主要介绍了用JavaScript来美化HTML的select标签的下拉列表效果的方法,而且在多浏览器下的兼容效果也得到提升,需要的朋友可以参考下
    2015-11-11
  • JavaScript获取XML数据附示例截图

    JavaScript获取XML数据附示例截图

    这篇文章主要介绍了JavaScript获取XML数据的方法,需要的朋友可以参考下
    2014-03-03
  • uniapp插件uview下表单无法动态校验的问题解决

    uniapp插件uview下表单无法动态校验的问题解决

    最近项目中用到了uview 在做表单时用到了校验,发现校验不友好的结果,下面这篇文章主要给大家介绍了关于uniapp插件uview下表单无法动态校验的问题解决,需要的朋友可以参考下
    2022-12-12
  • Bootstrap入门教程一Hello Bootstrap初识

    Bootstrap入门教程一Hello Bootstrap初识

    Bootstrap,来自 Twitter,是目前很受欢迎的前端框架。Bootstrap是基于 HTML5、CSS3和Javascriopt开发的。这篇文章主要介绍了基于Bootstrap3实现漂亮简洁的CSS3价格表(精美代码版),需要的朋友可以参考下
    2017-03-03
  • js实现三级联动效果(简单易懂)

    js实现三级联动效果(简单易懂)

    本文主要介绍了js实现三级联动效果的示例代码,简单易懂。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • JS中cookie的使用及缺点讲解

    JS中cookie的使用及缺点讲解

    Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。下面通过本文给大家介绍JS中cookie的使用及缺点,需要的朋友参考下吧
    2017-05-05
  • 微信小程序数据请求的方式和注意事项详解

    微信小程序数据请求的方式和注意事项详解

    这篇文章主要为大家介绍了微信小程序网络数据请求的方式和注意事项讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • JavaScript实现模块拖拽功能的代码示例

    JavaScript实现模块拖拽功能的代码示例

    这篇文章将给大家详细介绍一下JavaScript实现模块的拖拽功能的代码示例,文中有详细的实现步骤,需要的朋友可以参考下
    2023-07-07
  • javascript+xml技术实现分页浏览

    javascript+xml技术实现分页浏览

    基于web的技术中,分页是一个老的不能再老的,但大家津津乐道的问题,随着xml技术的日渐应用,把xml应用到分页当中,也是一种可能,当然网上的教程很多,当我都是看得稀里糊涂,索性自己写一个,与大家分享、指正。
    2008-07-07

最新评论