js规范-模块

61 阅读1分钟

模块规范

模块规范

ES6模块简写:ESM , CommonJS 简写 CJS

CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

  • 使用标准的import 、export
    采用ES6模块规范

      bad : ❌
      module.exports = {};
      require(moduleName)
    
      let name='ricky'
      export name;
    
      good ✅
      export default 
      export let name='ricky'
      export {name}
      export function sum(x,y){ return x+y;}
      import {xx} from 'xx'
    

    import 不用使用通配*,例如 import * as some form './xxx'

  • ESM 和 CJS 混合使用场景

    主要出现在Node.js场景,自 13.2.0 版本开始,Node.js 在保留了 CommonJS(CJS)语法的前提下,新增了对 ES Modules(ESM)语法的支持,但不太完美
    Node 默认只支持 CJS 语法,如果想在 Node 中使用 ESM 语法,有两种可行方式:

    1. 在 package.json 中新增 "type": "module" 配置项。
    2. 将希望使用 ESM 的文件改为 .mjs 后缀。
    ESM 引用 CJS 模块的问题
    /** @file cjs/a.js **/
    // named exports
    module.exports = {
        foo: () => {
            console.log("It's a foo function...")
        }
    }
    
    bad : ❌
    /** @file index_err.js **/
    import { foo } from './cjs/a.js';  
    // SyntaxError: Named export 'foo' not found. The requested module './cjs/a.js' is a CommonJS module, which may not support all module.exports as named exports.
    foo();
    
    good ✅
    /** @file index_err.js **/
    import pkg from './cjs/a.js';  // 以 default export 的形式引入
    pkg.foo();  // 正常执行
    
    CJS 引用 ESM 模块的问题
    
    bad : ❌
    let { foo } = require('./esm/b.js');
                  ^
    
    Error [ERR_REQUIRE_ESM]: require() of ES Module require.js not supported.
    Instead change the require of b.js in require.js to a dynamic import() which is available in all CommonJS modules.
        at Object.<anonymous> (\require.js:4:15) {
      code: 'ERR_REQUIRE_ESM'
    }
    
    good ✅
    import('./esm/b.js').then(({ foo }) => {
        foo();
    });
    
    // or
    
    (async () => { 
        const { foo } = await import('./esm/b.js'); 
    })();
    
    good ✅✅
    借助 rollup 之类的工具将项目编译为 CJS 模块
    @rollup/plugin-commonjs