Open FrankKai opened 4 years ago
项目中有用到vue-router和webpack实现异步加载组件,使用的就是import的函数语法import()语法 在学习webpack的代码拆分章节时,也有专门的一个章节用来讲这个,因此需要系统性学习一下import的函数语法import()。
import()
var promise = import("module-name");
标准版的import语法是static的,因此会在加载时就引入所有的代码。 但是很多情况下我们需要动态引入模块,也就是说满足特定条件才加载模块,我们可以使用动态引入去做这件事。
一共有5个原因。
在必要时使用动态引入。 静态引入用于加载初始化的依赖,可以从静态分析工具和tree shaking中做优化。
为了做到动态引入一个module,import需要被当做一个函数去调用。 import当函数调用时,返回结果是一个promise。
import('/modules/my-modules.js') .then((module)=>{ // 用module做点什么 })
还可以用await语法:
let module = await import('/modules/my-module.js');
// project webpack-demo |- package.json |- webpack.config.js |- /dist |- /src |- index.js |- /node_modules
// src/index.js + function getComponent() { + return import(/* webpackChunkName: "lodash" */ 'lodash').then(({ default: _ }) => { + const element = document.createElement('div'); + + element.innerHTML = _.join(['Hello', 'webpack'], ' '); + + return element; + + }).catch(error => 'An error occurred while loading the component'); } + getComponent().then(component => { + document.body.appendChild(component); + })
或者
// src/index.js + async function getComponent() { + const element = document.createElement('div'); + const { default: _ } = await import(/* webpackChunkName: "lodash" */ 'lodash'); + + element.innerHTML = _.join(['Hello', 'webpack'], ' '); + + return element; } getComponent().then(component => { document.body.appendChild(component); });
打包后的结果为:体积很小的主程序;体积很大的vendor程序。主程序动态引入verdor。
... Asset Size Chunks Chunk Names index.bundle.js 7.88 KiB index [emitted] index vendors~lodash.bundle.js 547 KiB vendors~lodash [emitted] vendors~lodash Entrypoint index = index.bundle.js ...
// router.js const Foo = () => import('./Foo.vue') const Bar = () => import(/* webpackChunkName: "group-bar" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-baz" */ './Baz.vue')
打包出来的结果为:
0.23f238869b2a7076bb5c.js group-bar.34f238869b2a776bbd2.js group-baz.43f23882b2a707623b2c.js
const chat = () => import(/* webpackChunkName: "chat" */ './chat.vue');
打包出来的结果为:chat.35f23886902a7076bb5c.js
当我们访问Foo 页面时,会只加载0.23f238869b2a7076bb5c.js。 此时访问Bar,动态引入group-bar.34f238869b2a776bbd2.js。 访问Baz,动态引入group-baz.43f23882b2a707623b2c.js。
资源加载过程为:
// srouces 访问Foo 0.23f238869b2a7076bb5c.js
// srouces 访问Foo后访问Bar 0.23f238869b2a7076bb5c.js group-bar.34f238869b2a776bbd2.js
// srouces 访问Foo后访问Bar,再访问Baz 0.23f238869b2a7076bb5c.js group-bar.34f238869b2a776bbd2.js group-baz.43f23882b2a707623b2c.js
webpack是通过webpackJsonp实现动态引入的。
webpackJsonp动态引入本质上是JSONP,动态增删script,从script引入需要的文件。
参考资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import https://webpack.js.org/guides/code-splitting/
这只是异步加载 不是按需导入
纠正过来了。按需加载应该是https://www.npmjs.com/package/babel-plugin-import 这样的
项目中有用到vue-router和webpack实现异步加载组件,使用的就是import的函数语法
import()
语法 在学习webpack的代码拆分章节时,也有专门的一个章节用来讲这个,因此需要系统性学习一下import的函数语法import()
。最简单的结构
初识import()
标准版的import语法是static的,因此会在加载时就引入所有的代码。 但是很多情况下我们需要动态引入模块,也就是说满足特定条件才加载模块,我们可以使用动态引入去做这件事。
为什么要动态引入
一共有5个原因。
动态引入使用示例
在必要时使用动态引入。 静态引入用于加载初始化的依赖,可以从静态分析工具和tree shaking中做优化。
为了做到动态引入一个module,import需要被当做一个函数去调用。 import当函数调用时,返回结果是一个promise。
还可以用await语法:
如何在webpack中使用import()实现动态引入
或者
打包后的结果为:体积很小的主程序;体积很大的vendor程序。主程序动态引入verdor。
vue-router中如何结合webpack如何动态引入
打包出来的结果为:
打包出来的结果为:chat.35f23886902a7076bb5c.js
当我们访问Foo 页面时,会只加载0.23f238869b2a7076bb5c.js。 此时访问Bar,动态引入group-bar.34f238869b2a776bbd2.js。 访问Baz,动态引入group-baz.43f23882b2a707623b2c.js。
资源加载过程为:
webpack是通过webpackJsonp实现动态引入的。
webpackJsonp动态引入本质上是JSONP,动态增删script,从script引入需要的文件。
参考资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import https://webpack.js.org/guides/code-splitting/