1、在现代浏览器使用模块化开发
- 创建一个 script 标签,加上 type="module" 属性
- 创建一个 index.js 文件,使用 import 引入 另外一个文件 export 的内容
- 启动 一个本地的服务器,可以使 http-server 或者 browser-sync
sudo yarn add http-server --global
http-server // 这样就执行了一个简单地本地服务了
注意事项归纳
在es modules 中自动使用 严格模式,也就是说,全局的 this 是 undefined 而不是 window
每个esmodule 都是单独运行在 自己的私有作用域中
每个脚本都是通过 http 去请求的,不允许使用 file 的方式去获取脚本
同时 需要 cors 配合,有可能会发生跨域
使用 type=module 之后,就相当于 给 标签加上了一个 defer ,就是说这个脚本的加载不会阻塞页面的渲染
使用注意点
- export { name } 并不是 对象字面量,
- import {name} 也不是解构,这个只是 其 语法规定这样写的
导出的是一个 引用,即使是 字符串,也是把引用关系 给赋值给了对方,
无论定义的时候是var 还是 const 导出是 const 的,只读的
要证明第一点很简单,如果是对象字面量的话,那么 {name} ==> {name: name} 是成立的
const name = "jack"
export {name: name}
不止 vscode 本身会报错,浏览器也会报错
其实这个就类似于 export 123 或者 export "jack" 一样,是非法的语法
所以想要导出一个对象的话,就得 export default {name: 'jack'}
这样就能证明第二点了 import { name } from './index.js'
而以下代码反而能够成立:
import name from './index.js'
name.name === 'jack'
第三点的证明也可以通过修改字符串来实现
// index.js
let name = 'jack'
setTimeout(() => {
name = 'rose'
}, 1000)
export default {
name
}
// app.js
import { name } from './index.js'
setTimeout(() => {
console.log(name) // 这里输出的,就是 index.js 在一秒后 修改的值 rose
}, 2000)
至于第四点
// index.js
let name = 'jack'
export default {
name
}
// app.js
import { name } from './index.js'
name = 'rose'
2、兼容性polyfill
具体的可以看一下以下 github 连接 Browser ES Module Loader
https://unpkg.com/browse/browser-es-module-loader@0.4.1/dist/babel-browser-build.js // 将读取出来的文件使用 babel 解析
https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js // 把 文件读取出来
总的来说,就是把上面的两个文件当做外部资源包引进来,而 nomodule 属性是为了 只在不支持 module 语法的浏览器执行
<script nomodule src="https://unpkg.com/browse/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
3、在node中使用
将所有的文件名 从 .js 改为 .mjs ,然后执行以下命令
node --experimental-modules app.mjs
或者修改 package.json,这样就不需要 修改文件名称了,直接使用 .js
node --experimental-modules app.js
{
"type": "module"
}
使用babel 来进行兼容
yarn add @babel/node @babel/core @babel/preset-env --dev
// .babelrc
{
"presets": [
"@babel/preset-env"
]
}
// 或者
{
"plugins": [
"@babel/plugin-transform-modules-commonjs"
]
}
加上babel配置之后,就可以执行对应的命令了
yarn babel-node app.js