JavaScript 模块化完全教程

第一章:CommonJS 模块化

1.1 基本语法

CommonJS 模块化的基本语法和使用方法。

练习 1.1:模块导出和导入

展示 CommonJS 的模块导出和导入。

模块导出示例
// math.js
// 导出单个值
exports.add = function(a, b) {
  return a + b;
};

// 导出多个值
exports.subtract = function(a, b) {
  return a - b;
};

// 或者使用 module.exports
module.exports = {
  add: function(a, b) {
    return a + b;
  },
  subtract: function(a, b) {
    return a - b;
  }
};
模块导入示例
// main.js
// 导入整个模块
const math = require('./math');
console.log(math.add(1, 2)); // 3

// 解构导入
const { add, subtract } = require('./math');
console.log(add(1, 2)); // 3
console.log(subtract(3, 1)); // 2

1.2 循环依赖

CommonJS 中的循环依赖处理。

练习 1.2:循环依赖示例

展示如何处理循环依赖。

循环依赖示例
// a.js
const b = require('./b');
console.log('a.js: b =', b);
module.exports = {
  name: 'a'
};

// b.js
const a = require('./a');
console.log('b.js: a =', a);
module.exports = {
  name: 'b'
};

// main.js
require('./a');

第二章:ES Modules

2.1 基本语法

ES Modules 的基本语法和使用方法。

练习 2.1:模块导出和导入

展示 ES Modules 的模块导出和导入。

模块导出示例
// math.js
// 命名导出
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

// 默认导出
export default {
  add,
  subtract
};
模块导入示例
// main.js
// 导入命名导出
import { add, subtract } from './math.js';
console.log(add(1, 2)); // 3

// 导入默认导出
import math from './math.js';
console.log(math.add(1, 2)); // 3

// 导入所有导出
import * as math from './math.js';
console.log(math.add(1, 2)); // 3

2.2 动态导入

ES Modules 的动态导入功能。

练习 2.2:动态导入示例

展示动态导入的使用。

动态导入示例
// 动态导入
async function loadModule() {
  try {
    const module = await import('./math.js');
    console.log(module.add(1, 2)); // 3
  } catch (error) {
    console.error('模块加载失败:', error);
  }
}

// 条件导入
if (condition) {
  import('./moduleA.js');
} else {
  import('./moduleB.js');
}

第三章:AMD 模块化

3.1 基本语法

AMD 模块化的基本语法和使用方法。

练习 3.1:模块定义和依赖

展示 AMD 的模块定义和依赖管理。

模块定义示例
// math.js
define(['jquery'], function($) {
  return {
    add: function(a, b) {
      return a + b;
    },
    subtract: function(a, b) {
      return a - b;
    }
  };
});
模块使用示例
// main.js
require(['math', 'jquery'], function(math, $) {
  console.log(math.add(1, 2)); // 3
  // 使用 jQuery
  $('body').css('background-color', 'red');
});

3.2 配置选项

AMD 的配置选项。

练习 3.2:配置示例

展示 AMD 的配置选项。

配置示例
// 配置 RequireJS
requirejs.config({
  // 基础路径
  baseUrl: 'js',
  
  // 路径映射
  paths: {
    'jquery': 'lib/jquery.min',
    'underscore': 'lib/underscore.min'
  },
  
  // 依赖配置
  shim: {
    'underscore': {
      exports: '_'
    }
  },
  
  // 加载超时时间
  waitSeconds: 15
});

第四章:模块打包工具

4.1 Webpack

Webpack 的模块打包配置。

练习 4.1:Webpack 配置示例

展示 Webpack 的模块打包配置。

Webpack 配置示例
// webpack.config.js
const path = require('path');

module.exports = {
  // 入口文件
  entry: './src/index.js',
  
  // 输出配置
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  
  // 模块配置
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },
  
  // 解析配置
  resolve: {
    extensions: ['.js', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  }
};

4.2 Rollup

Rollup 的模块打包配置。

练习 4.2:Rollup 配置示例

展示 Rollup 的模块打包配置。

Rollup 配置示例
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';

export default {
  // 入口文件
  input: 'src/index.js',
  
  // 输出配置
  output: {
    file: 'dist/bundle.js',
    format: 'umd',
    name: 'MyLibrary'
  },
  
  // 插件配置
  plugins: [
    resolve(),
    commonjs(),
    babel({
      exclude: 'node_modules/**'
    })
  ]
};

学习建议

建议按照章节顺序学习,每完成一个练习后再进行下一个。可以通过实际项目来实践所学知识,特别是模块打包工具的使用。注意不同模块化方案的适用场景和优缺点。