import()
Javascript中的import()
语法,也被称作动态导入(dynamic import)。它允许异步地将Javascript模块加载到非模块代码中。
所谓Javascript模块,是指使用export
关键字导出的模块。比如以下代码:
export const site = 'runjs.work'
export default function axios() {
console.log('mock axios')
}
将其保存为
es-module.js
,方便后面使用。
浏览器运行
在浏览器中,使用<script type="module"></script>
语法,可以直接加载Javascript模块。
将上面的es-module.js
上传到RunJS静态文件仓库中,得到一个公网访问的地址:
https://s1.qingting.work/runjs/063f7158b7044f04/8adbd4be0620.js
创建一个RunJS项目,并在JS
版块粘入以下代码,选择编译类型为Module:
import('https://s1.qingting.work/runjs/063f7158b7044f04/8adbd4be0620.js').then(({default: axios, site}) => {
axios();
console.log(site);
})
如下图所示,我们可以看到,浏览器成功地加载了es-module.js
中导出的axios和site变量:
在RunJS中打开示例代码。
那么,兼容性如何呢?
MDN显示,主流新版浏览器,对Javascript模块的支持,都是不错的。至少,在开发阶段使用Javascript模块,能大大缩小编译工具的负担。这也是目前大部分前端框架在开发模式下采用的Js输出格式。
Node.js运行
在Node.js中,有两种方式运行Javascript模块。
第一种,是将所有相关文件以.mjs
后缀命名。
准备以下两个文件,放在同一目录:
es-module.mjs
,内容如下:
export const site = 'runjs.work'
export default function axios() {
console.log('mock axios')
}
index.mjs
,内容如下:
import('./es-module.mjs').then(({default: axios, site}) => {
console.log(site)
axios()
})
用node运行:
node ./index.mjs
可以看到正确的输出:
第二种,是借助babel
、webpack
之类的编译工具,将其转换为commonjs
格式。
准备以下两个文件,放在同一目录(src/
):
es-module.js
,内容如下:
export const site = 'runjs.work'
export default function axios() {
console.log('mock axios')
}
index.js
,内容如下:
import('./es-module.js').then(({default: axios, site}) => {
console.log(site)
axios()
})
用node运行:
node ./index.js
不允许直接运行:
用webpack
编译一下。
安装webpack
,并创建webpack.config.js
。
npm install --save-dev webpack webpack-cli
webpack.config.js
内容如下:
const path = require('path')
module.exports = {
mode: 'production',
entry: {
index: './src/index.js',
},
target: 'node',
optimization: {
minimizer: [false]
}
}
webpack中的target
默认是web
,所以这里我们需要显性声明打包目标平台是Node.js
.指定minimizer
为[false]
,可以让webpack打包的目标代码不压缩。
在package.json
中添加打包命令:
{
"scripts": {
"build": "webpack"
}
}
运行打包,会在dist/
目录生成index.js
:
npm run build
运行打包后的代码:
node dist/index.js
也可以看到正确的输出。
分析一下。打包后生成了入口文件dist/index.js
和chunk文件dist/274.js
。
dist/index.js
引入了dist/274.js
。引入的方法由import
变成了require
。
也就是说,webpack
默认识别javascript模块,并将其打包成独立的文件。不少前端框架基于路由做代码分割(Code Splitting)的原理,就是将页面的代码通过import()
方式导入。
总结
import()
在浏览器端的支持,使得web项目在开发阶段的打包效率大大提升。
import()
要在Node.js
上使用,则需要webpack
、babel
之类的工具支撑。webpack
对于import()
的处理,有利于灵活配置Code Splitting的分割点。
引用本文请注明来处。