模块化开发
- 1.基于文件的划分模块的方式,缺点:污染全局作用域、命名冲突问题、无法管理模块依赖关系
- 2.每个模块只暴露一个全局对象,所有模块成员都挂载到这个对象中,缺点,仍然没有私有空间
- 3.使用立即执行函数表达式,为模块提供私有空间
- 一个文件就是一个模块
- 每个模块都有单独的作用域
- 通过module.exports导出成员
- 通过require函数载入模块。AMD规范,通过require加载模块的话,内部会创建一个script标签
- 如今前端模块化统一在node环境下使用commonJS,在浏览器环境下ESmodules
- 1.自动采用严格模式,忽略‘use stricr’
- 2.每个ESM模块都是单独的私有作用域
- 3.ESM时通过CORS去请求外部js模块的
- 4.ESM的script标签会延迟执行脚本
- export 模块内对外暴露接口
- import 模块内导入其他模块提供的接口
- 在html文件中引入js文件,script标签中要加上type=module,否则会报错
var name = 'foo module'
function hello(){
return 'hello'
}
class person{}
export{
name,
hello,
person
}
export{
name as fooName,
}
export{
name as default,
}
export default name
import { name,hello,person } from './module.js'
console.log(hello())
import { fooName } from './module.js'
console.log(fooName)
import { default as fooName } from './module.js'
console.log(fooName)
import { abc } from './module.js'
console.log(abc)
export{ name,age }
export default { name,age}
import { name,age }
import 用法与commonJS区别
commonJS中
import {lowercase} from './module'
import 导入模块必须使用完整的文件名
import {lowercase} from './module.js'
commonJS中
import {lowercase} from './utils'
import 导入模块完整路径
import {lowercase} from './utils/index.js'
使用相对路径./不能省略。如果没有./默认加载的是第三方模块
import可以使用绝对路径或者完整的url
import {lowercase} from '/utils/index.js'
import {lowercase} from 'http://localhost:3000'
import {} from './module.js'简写import './module.js'
import * as mod from './module.js'
动态导入模块
import ('./module.js').then(function(){console.log(module)})
同时导出命名成员和默认成员
export{name,age}
export default 'default export'
import {name,age,default as title}from './module.js'简写import abc,{name,age}from './module.js'
import {foo,bar} from './module.js'. 把import修改成export。export {foo,bar} from './module.js'
console.log(foo,bar)
- ESModules in Browser. Polyfill 兼容方案
ESModules在IE等浏览器中存在兼容性问题,引入下面两个js文件可以解决此问题
<script src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
<script src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
如果还是不支持promise特性,需要引入一个路径解决此问题
<script src="https://unpkg.com/promise-polyfill@8.1.3/dist/polyfill.min.js"></script>
<script type="module">
import { name } from './module.js'
console.log(name)
</script>
在支持ESModules的浏览器中,脚本会加载两次,使用nomodule标签解决
<script nomodule>
</script>
只在开发环境中使用,在生产环境效率低下
node --experimental-modules index.mjs
import {foo,bar} from './modules.mjs'
console.log(foo,bar)
import {writeFileSync} from 'fs'
writeFileSync('./bar.txt','es module wroking')
- ES Modules中可以导入CommonJS模块
- CommonJS中不能导入ES Modules模块
- CommonJS始终只会导出一个默认成员
- 注意import 不是解构导出对象
import mod from './common.js'
console.log(mod)
import{foo}from './common.js'
console.log(foo)
export const foo = 'es module export value'
module.exports = {
foo:'commonjs export value'
}
exports.foo = 'commonjs export value'
const mod = require('./es-modules.mjs')
console.log(mod)
- ES Modules in Node.js 与CommonJS 模块的差异
esm.js
console.log(require)
console.log(module)
console.log(exports)
console.log(__filename)
console.log(__dirname)
import {fileURLToPath} from 'url'
import {dirname} from 'path'
const __filename = fileURLToPath(import.meta.url)
console.log(__filename)
const __dirname = dirname(__filename)
console.log(__dirname)
common.js
console.log(require)
console.log(module)
console.log(exports)
console.log(__filename)
console.log(__dirname)
- ES Modules in nodeJS 新版本进一步支持ESM
import {foo,bar} from './module.mjs'
console.log(foo,bar)
export const foo = 'i an li'
export const bar = 'hello world'
{
"type":"module"
}
index.mjs可以写为index.js. module.mjs写为module.js
运行node --experimental-modules index.js 依旧按esm规则运行
- ESModules in nodeJS-babel兼容方案 早期的node版本兼容
- babel 是javascript编译器,可以把使用了新特性的代码编译为当前支持的代码
- 安装@babel/node @babel/core @babel/preset-emv --dev
- 安装成功后 运行 yarn babel-node 运行js文件 yarn babel-node index.js – presets=@babel/preset-env. 因为直接运行yarn babel-node index.js会报错,babel并不会转换代码,所以要借助转换插件来完成
{
"presets": ["@babel/preset-env"]
}
注意:preset是一个集合,转换的是插件并不是preset 安装@babel/plugin-transform-modules-commonjs --dev
{
"plugins": ["@babel/plugin-transform-modules-commonjs "]
}
|